正文

第七课:菜单(二)2007-09-23 14:06:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lym51/29613.html

分享到:

第七课:菜单(二)

一、系统菜单:

1.  系统菜单是有鼠标点击应用程序图标弹出的菜单。点击系统菜单时,发出WM_SYSCOMMAND消息,可添加此消息的响应函数来进行控制。

2.  操作系统菜单:

CMainFrameOnCreate函数中加入代码:

CMenu *pMenu=GetSystemMenu(false);

     //得到系统菜单

pMenu->RemoveMenu(pMenu->GetMenuItemCount()-1,MF_BYPOSITION);

     //移除系统菜单的最后一项

     pMenu->EnableMenuItem(SC_CLOSE,MF_DISABLED | MF_BYCOMMAND|MF_GRAYED); 

                //将系统菜单的“关闭”菜单项设置为失效,变灰

     pMenu->AppendMenu(MF_STRING,1111,"HELLO");

        //在系统菜单中添加一个菜单

     GetSystemMenu(true);

        //重置系统菜单到默认状态

二、运行时产生菜单:

  在CMainFrameOnCreate函数中加入代码:

mnu.CreatePopupMenu();

      //产生一个弹出菜单,注意:在WIN2000mnu应定义为成员变量,否则会报红框,WINNT下可以定义为局部变量

    mnu.AppendMenu(MF_STRING,1111,"HELOO");

        //向刚产生的弹出菜单加入一个菜单项

    GetMenu()->AppendMenu(MF_POPUP,(INT)mnu.m_hMenu,"heha");

        //将弹出菜单添加到主窗口的菜单上

GetMenu()->GetSubMenu(4)->EnableMenuItem(32771,

MF_DISABLED| MF_BYCOMMAND|MF_GRAYED);

        //将新添加的菜单设置为失效,变灰

  说明:运行程序时,会发现上面代码的最后一句没有生效。应在CMainFrame的构造函数将成员变量m_bAutoMenuEnable设为FALSE。当这个成员变量设置为TRUE时,如果菜单项没有ON_UPDATE_COMMAND_UI 或者ON_COMMAND的处理函数,用户点击弹出菜单时系统自动将菜单项设为失效。如果菜单项有ON_COMMAND的处理函数,菜单项自动被设置为有效。

三、动态增长菜单程序的编写

 想实现的功能是,输入名字和电话,用空格格开,当用户按下回车键时把名字加入主菜单中,点击相应的菜单显示相应的名字和电话信息。

1.  CView中定义成员变量

      CString m_strLine;     //用于记录用户的键盘输入

    CMenu m_mnuPhone;           //用于产生弹出菜单

    int   m_nIndex;             //用于为菜单产生可变的ID

    CStringArray m_aInput;      //用于保存用户所有的用户输入

2.  ViewàResource Symbols New一个ID,用于为菜单的ID赋值,把它命名为IDM_PHONE

3.  CView中加入WM_CHAR消息的响应函数OnChar,加入以下代码:

if(0xd==nChar)     

   //如果输入的是回车键,就动态添加菜单

    {

        if(!m_mnuPhone.m_hMenu) 

 //如果弹出菜单没有产生

        {

            m_mnuPhone.CreatePopupMenu();    

//产生弹出菜单

    GetParent()->GetMenu()->AppendMenu(

MF_POPUP,

(UINT)m_mnuPhone.m_hMenu,

"Phone"); 

//将弹出菜单添加到主窗口的菜单上

            GetParent()->DrawMenuBar();    

//重绘菜单

        }        

m_mnuPhone.AppendMenu(MF_STRING,

IDM_PHONE+m_nIndex,

m_strLine.Left(m_strLine.Find(" ")));

//将用户输入的姓名(空格前面的字符)添加到弹出菜单上

        m_aInput.Add(m_strLine); 

     //将用户输入的字符串保存到动态数组中

        m_strLine.Empty();

         //清空字符串,以便用户下次输入

        m_nIndex++;//

        Invalidate();

//使窗口重绘

    }

    else

    {      //不是回车键

        CClientDC dc(this);       //生成DC

        m_strLine+=nChar ;      //将输入的字符保存

        dc.TextOut(0,0,m_strLine);   //输出到View

    }

说明:

a.     在窗口显示以后(如CView中的OnChar中)再添加菜单,需要调用DrawMenuBar()函数重绘一下菜单,否则新加入的菜单不会显示出来。而在在窗口显示之前(如CMainFrameOnCreate中)则不用。

b.     Invalidate()函数使窗口的全部客户区失效,它只是向窗口的消息队列中发送一个WM_PAINT消息,马上返回Invalidate()的下一句去执行,等Invalidate()所在的函数执行完毕之后,WM_PAINT消息才有机会被取到,去执行刷新操作。所以,如果在Invalidate()之后的代码中输出字符或图形,也将被稍后的刷新操作冲掉,不会看到输出效果。

4.  为动态产生的菜单添加响应函数

a.     手工添加:

i.                 CView中的消息映射表中添加消息映射:

      ON_COMMAND(IDM_PHONE, OnPhone)

ii.              CView添加成员函数OnPhone

       afx_msg void OnPhone1();

iii.          OnPhone中添加代码:

      void CMenu2View::OnPhone1()

{

    MessageBox("phone1");

}

b.     利用ClassWizard添加:

i.                 在资源面板里增加一个菜单,将其ID指定为IDM_PHONE

ii.              这时用ClassWizard可以为IDM_PHONE添加响应函数

iii.          从资源面板里删除刚刚增加的菜单项

c.     OnCommand中添加控制代码:

所有的WM_COMMAND消息都会交给拥有菜单的窗口的成员函数OnCommand去处理,可以在其中处理所有的动态添加的菜单。

CMainFrame中添加虚函数OnCommand,加入代码:

int nId=LOWORD(wParam);  //取出菜单的ID

int nIndex=((CMenu2View*)GetActiveView())->m_nIndex;

              //CMainFrame中访问CView中的变量

if( nId >=IDM_PHONE && nId < IDM_PHONE+nIndex)

{   //判断如果是动态添加的菜单消息

CClientDC dc(GetActiveView());

  //生成一个CViewDC

dc.TextOut(0,0,

((CMenu2View*)GetActiveView())->m_aInput.GetAt(nId-IDM_PHONE));

 //CMainFrame将保存在动态字符数组中的字符串打印到View

     return true;//返回,表示已经处理了WM_COMMAMD消息

}

else

           return CFrameWnd::OnCommand(wParam, lParam);

           //其它的WM_COMMAMD消息交由父类去处理


阅读(4041) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册