当我在努力学习MFC的时候,我的两个好友,也是编程高手:Fall Hunter和鄢哥却告诉我:C++才是最根本的。并且推荐我看两本书,有趣的是,两人推荐的竟是完全一样的两本书:《inside the c++ object model》和《Design Patterns: Elements of Reusable Object-Oriented Software》。鉴于两位的水平以及和我的关系,他们的建议使我不得不重视,而这似乎又将成为一个新的开始。
或许他们并没有让我完全放弃VC的意思,毕竟他们本身就是优秀的VC程序员,而他们给出了同样的建议,告诉我C++才是最要紧的,在我看来,这就是他们在使用VC的过程中的深刻体会。所以,我没有放弃VC的打算,毕竟它只是一个开发工具而已。我要做的,是在我继续弄清楚MFC的同时,对C++和OOP再进行深入学习。而这一系列笔记,将从下一次更名为:C++学习历程,之所以这么说,是因为我对MFC还没有过达到入门的程度,还不能够独立写点程序。
一、菜单编程:(基于孙鑫20讲之第六讲&《深入浅出MFC》)
还记得在前面提到过菜单触发的消息属于命令消息(WM_COMMAND),对于命令消息的处理,前面也大致提过,这一小节详细记录如何添加消息处理函数,由于CView、CDocument、CMainFrame、CWndApp都可以捕获命令消息,只是响应优先次序不同,只能被最早出现的处理函数捕获,即当菜单项被点击时,命令消息最早由CMainFrame获得,紧接着交给其CView类子窗口,其余过程不复赘述。
1、菜单分类:
(1)系统菜单:即通常所说的菜单栏,通常含File、Help等,属于CMainFrame;
(2)子菜单:点击系统菜单时的弹出菜单,如File、Edit等,无标识号,只能通过索引号(0、1……,分隔栏占用索引)访问;
(3)菜单项:子菜单中的一项,如Open、New等,可通过索引或标识号(如IDM_FILE_OPEN)访问。
2、常用函数(仅列函数名和功能):
CMenu* CWnd::GetMenu() const; // 返回指向当前窗口菜单栏的指针
CMenu* Cwnd::GetSubMenu(int nPos) const; // 返回指向某子菜单(由索引值nPos决定)的指针
UINT CMenu::CheckMenuItem(UINT nIDCheckItem,UINT nCheck); // 设置复选标记菜单
BOOL CMenu::SetDefaultItem(UINT uItem,BOOL fByPos=FALSE); // 设置缺省菜单项(任一子菜单只能有一项缺省,最后一次设置有效)
BOOL CMenu::SetMenuItemBitmaps(UINT nPositon, UINT nFlags, const
CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked); // 设置图形标记菜单,位图不能过大(GetSystemMetrics)
UINT CMenu::CheckMenuItem(UINT nIDEnableItem,UINT nEnable); // Disable某菜单项,一般将MF_DISABLED和MF_GRAYED同时使用,此时必须将CMainFrame中的成员变量m_bAutoMenuEnable置为FALSE。
BOOL CWn d::SetMenu(CMenu* pMenu); // pMenu标识新菜单,为NULL时移去菜单
3、命令更新:
菜单项状态的维护依赖于CN_UPDATE_COMMAND_UI消息,当其被窗口捕获,MFC就为该窗口创建一个CCmdUI对象。我们可以通过手工或利用ClassWizard在消息映射中添加ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_UI消息并以函数处理(如void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)),命令更新机制只能用于菜单项,而不能用于顶级菜单。
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=926093