我的小软件想实现这样一个功能
登陆前,我希望只有
帐户 帮助 这两个菜单项,帐户菜单有注册和登陆两个弹出菜单 ,登陆以后,其他菜单才全部出来。
一般的MFC书上都介绍了用AppendMenu动态生成菜单的方法
但是这样生成的菜单并没有命令处理机制,解决的办法是重载OnCmdMsg函数
然后根据菜单ID用switch方式选择执行函数。
总是感觉这种方法很别拗。
当然可以一开始就在资源编辑框内把菜单做好,登陆以前把它们的属性赋成灰色的
这样实现起来很简单,但是我更倾向于登陆以后菜单才出现这样的方法。
解决的办法是在资源编辑器中做好所有的菜单,然后用wizzard把菜单项和命令函数联系起来,就和一般的菜单没有区别。
重载OnCreate()函数,把不需要的菜单删去
我的代码:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
...{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | CBRS_TOP | WS_VISIBLE
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
...{
TRACE0("Failed to create toolbar ");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
...{
TRACE0("Failed to create status bar ");
return -1; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
CMenu *pMenu = GetMenu();
pMenu->DeleteMenu(1, MF_BYPOSITION);
pMenu->DeleteMenu(1, MF_BYPOSITION);
return 0;
}
这样程序运行的时候
就只有帐户 帮助 2个菜单项
void CHopeApp::OnLog() 
...{
CLogDlg dlg;
if(dlg.DoModal() == IDOK)
...{
CString realUserName = dlg.GetUserName();
CString cryptPassWord;
CString cryptUserName = MyEncrypt(realUserName);
if((dlg.m_ini)->Load(&cryptUserName, &cryptPassWord))
...{
if(MyDecrypt(cryptPassWord) == dlg.GetPassWord())
...{
m_LoginName = realUserName;
CWnd *pFrame = AfxGetMainWnd();
CMenu *pMenu = pFrame->GetMenu();
pMenu->DeleteMenu(1, MF_BYPOSITION); // 为了调整顺序,先把"帮助"菜单删去
CMenu pop;
pop.CreatePopupMenu();
pop.AppendMenu(MF_STRING|MF_ENABLED,ID_ADD, "&添加");
pop.AppendMenu(MF_STRING|MF_ENABLED,ID_MODIFY, "&修改");
pop.AppendMenu(MF_STRING|MF_ENABLED,ID_IMPORT, "&导入");
pop.AppendMenu(MF_STRING|MF_ENABLED,ID_EXPORT, "&导出");
pMenu->AppendMenu(MF_POPUP, (UINT)pop.Detach(), "数据");
pop.CreatePopupMenu();
pop.AppendMenu(MF_STRING|MF_ENABLED,ID_YS, "&预算");
pop.AppendMenu(MF_STRING|MF_ENABLED,ID_COMPARE, "&比较");
pop.AppendMenu(MF_STRING|MF_ENABLED,ID_SET, "&设置");
pMenu->AppendMenu(MF_POPUP, (UINT)pop.Detach(), "&工具");
pop.CreatePopupMenu();
pop.AppendMenu(MF_STRING|MF_ENABLED,ID_APP_ABOUT, "&关于 Hope(&A)...");
pMenu->AppendMenu(MF_POPUP, (UINT)pop.Detach(), "帮助");
pFrame->SetMenu(pMenu);
pFrame->Invalidate(); m_pMainWnd->UpdateWindow();
}
else
...{
::AfxMessageBox("密码错误!请核对!");
}
}
else
...{
::AfxMessageBox("对不起,您输入的用户不存在!");
}
}
else
...{
}
}
在登陆对话框处理函数中,登陆成功以后,再把相应的菜单加上去
这样子,菜单的处理函数还是完好的
这种方法比网上大多数介绍的动态菜单的方法要直观,也更加方便

被折叠的 条评论
为什么被折叠?



