http://www.cnblogs.com/shijun-china/articles/1429183.html
在更改菜单之前,首先要把CMainFrame:: m_bAutoMenuEnable设为FALSE,不然就无法自己更改菜单的样式,而是被MFC自动的设为启动。
然后用AfxGetMainWnd()得到主窗口的句柄,再调用GetMenu,得到主菜单的指针,但是如果直接用 AfxGetMainWnd()->GetMenu()就会出错,因为用AfxGetMainWnd()得到的是CFrameWnd或其它,是 CMainFrame的父类,要把把强化转化为当前的框架类CMainFrame才可以再获得菜单等其他资源。
CMenu * pmenu = ((CMainFrame *)AfxGetMainWnd())->GetMenu();
现在pmenu获得的主菜单是整个菜单项,然后用它来调用GetSubMenu()来获取其中的子菜单。自菜单的序号是从0开始的。
CMenu * psub = pmenu->GetSubMenu(0);
之后就可以用psub来更改子菜单中的按钮的状态了,方法是:
psub->EnableMenuItem(
UINT uIDEnableItem, //菜单项标识
UINT uEnable //控制标志
);
个人觉得常用的控制标志只有3个:
MF_DISABLED —— 禁止
MF_ENABLED ——允许
MF_GRAYED —— 变灰
比如要让打开菜单项(标志为ID_FILE_OPEN)变灰并且禁用(其实纯变灰了就不能用了),那么语句就是psub->EnableMenuItem(ID_FILE_OPEN, MF_GRAYED | MF_DISABLED);
给出示例代码:放在int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)里面的最下面
2 {
3 if (CFrameWnd::OnCreate(lpCreateStruct) == - 1 )
4 return - 1 ;
5
6 if ( ! m_wndToolBar.CreateEx( this , TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
7 | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
8 ! m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
9 {
10 TRACE0( " 未能创建工具栏/n " );
11 return - 1 ; // 未能创建
12 }
13
14 if ( ! m_wndStatusBar.Create( this ) ||
15 ! m_wndStatusBar.SetIndicators(indicators,
16 sizeof (indicators) / sizeof (UINT)))
17 {
18 TRACE0( " 未能创建状态栏/n " );
19 return - 1 ; // 未能创建
20 }
21
22 // TODO: 如果不需要工具栏可停靠,则删除这三行
23 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
24 EnableDocking(CBRS_ALIGN_ANY);
25 DockControlBar( & m_wndToolBar);
26
27 CMainFrame::m_bAutoMenuEnable = false ; // 重要
28 CMenu * pmenu = this -> GetMenu();
29 CMenu * psub = pmenu -> GetSubMenu( 0 );
30 // psub->EnableMenuItem(UINT uIDEnableItem,UINT uEnable);
31 // uEnable have three states below:
32 // MF_DISABLED —— 禁止
33 // MF_ENABLED ——允许
34 // MF_GRAYED —— 变灰
35 psub -> EnableMenuItem(ID_FILE_OPEN, MF_GRAYED | MF_DISABLED);
36
37 return 0 ;
38 }
第28行 为什么是 CMenu * pmenu = this->GetMenu(); 而不是 CMenu * pmenu = ((CMainFrame *)AfxGetMainWnd())->GetMenu() 来得到主menu指针, 具体原因偶再去查查,
望高手指点。