实现动态菜单的技巧

我的小软件想实现这样一个功能

登陆前,我希望只有

帐户  帮助 这两个菜单项,帐户菜单有注册和登陆两个弹出菜单 ,登陆以后,其他菜单才全部出来。

一般的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
    
{
  

    }
 
    
}

 

在登陆对话框处理函数中,登陆成功以后,再把相应的菜单加上去

这样子,菜单的处理函数还是完好的

这种方法比网上大多数介绍的动态菜单的方法要直观,也更加方便

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值