正文

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

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

分享到:

第七课:菜单(二) 一、系统菜单: 1.  系统菜单是有鼠标点击应用程序图标弹出的菜单。点击系统菜单时,发出WM_SYSCOMMAND消息,可添加此消息的响应函数来进行控制。 2.  操作系统菜单: 在CMainFrame的OnCreate函数中加入代码: 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);         //重置系统菜单到默认状态 二、运行时产生菜单:   在CMainFrame的OnCreate函数中加入代码: mnu.CreatePopupMenu();       //产生一个弹出菜单,注意:在WIN2000下mnu应定义为成员变量,否则会报红框,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()函数重绘一下菜单,否则新加入的菜单不会显示出来。而在在窗口显示之前(如CMainFrame的OnCreate中)则不用。 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());   //生成一个CView的DC 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消息交由父类去处理

阅读(4317) | 评论(0)


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

评论

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