zoukankan      html  css  js  c++  java
  • MDI动态改变菜单、工具栏

    在MDI开发中,往往不同的视图需要不同的菜单和不同的工具栏,这样对于不同view可以有不同的操作。

    现在分步骤进行实现。

    第一步: 添加新的docTemplate

    我们知道在MFC中Document/view/ChildFrame是一体的,当新建一个工程后,IDE会自动为我们建立一份Document/view/ChildFrame,因此为了使用不同类型的文档我们需要额外定义另三个类。然后在WinApp中的InitInstance函数添加document模板:

     1     // 注册应用程序的文档模板。文档模板
    2 // 将用作文档、框架窗口和视图之间的连接
    3 m_pFirstDocTemplate = new CMultiDocTemplate(IDR_uuTYPE,
    4 RUNTIME_CLASS(CuuDoc),
    5 RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
    6 RUNTIME_CLASS(CuuView));
    7 AddDocTemplate(m_pFirstDocTemplate);
    8
    9 m_pSecondDocTemplate = new CMultiDocTemplate(IDR_xxTYPE,
    10 RUNTIME_CLASS(CuuDoc),
    11 RUNTIME_CLASS(CMyChildFrm),
    12 RUNTIME_CLASS(CEditView));
    13 AddDocTemplate(m_pSecondDocTemplate);

    说明:这里使用了同一份document,不同的childframe(因为菜单和工具栏不一样,这里必须区分开),不同view(应该是不一样的,不然就没意义了)

    第二步:制作自定义的菜单和工具栏

    制作这里的菜单和工具栏最好使用copy/paste方法,IDE中的资源编辑器不太好用。

    用记事本打开.rc的资源文件,里面都是文本格式,很容易看懂。

    1. 增加文档的图标

    1 IDR_uuTYPE         ICON         "res\\uuDoc.ico"
    2 IDR_xxTYPE ICON "res\\xxDoc.ico"

    第一行是原来已存在,复制一行就行。

    2. 工具栏

    要为工具栏载入位图

    1 IDR_xxTYPE         BITMAP      "res\\uu.bmp"

    然后,复制一个IDR_MAINFRAME的工具栏,作适当修改即可。

     1 IDR_xxTYPE TOOLBAR   16, 16
    2 BEGIN
    3 BUTTON ID_FILE_OPEN
    4 BUTTON ID_FILE_NEW
    5 BUTTON ID_FILE_SAVE
    6 SEPARATOR
    7 BUTTON ID_EDIT_CUT
    8 BUTTON ID_EDIT_COPY
    9 BUTTON ID_EDIT_PASTE
    10 SEPARATOR
    11 BUTTON ID_FILE_PRINT
    12 BUTTON ID_APP_ABOUT
    13 END

    3. 菜单

    菜单也可以复制一个IDR_MAINFRAME,然后再改。

     1 IDR_xxTYPE MENU
    2 BEGIN
    3 POPUP "haha(&F)"
    4 BEGIN
    5 MENUITEM "hehe(&N)\tCtrl+N", ID_FILE_NIMA
    6 MENUITEM "打开(&O)...\tCtrl+O", ID_FILE_OPEN
    7 MENUITEM "关闭(&C)", ID_FILE_CLOSE
    8 MENUITEM "保存(&S)\tCtrl+S", ID_FILE_SAVE
    9 MENUITEM "另存为(&A)...", ID_FILE_SAVE_AS
    10 MENUITEM SEPARATOR
    11 MENUITEM "退出(&X)", ID_APP_EXIT
    12 END
    13 POPUP "编辑(&E)"
    14 BEGIN
    15 MENUITEM "撤消(&U)\tCtrl+Z", ID_EDIT_UNDO
    16 MENUITEM SEPARATOR
    17 MENUITEM "剪切(&T)\tCtrl+X", ID_EDIT_CUT
    18 MENUITEM "复制(&C)\tCtrl+C", ID_EDIT_COPY
    19 MENUITEM "粘贴(&P)\tCtrl+V", ID_EDIT_PASTE
    20 END
    21 POPUP "视图(&V)"
    22 BEGIN
    23 POPUP "工具栏和停靠窗口(&T)"
    24 BEGIN
    25 MENUITEM "<占位符>", ID_VIEW_TOOLBAR
    26 END
    27 MENUITEM "状态栏(&S)", ID_VIEW_STATUS_BAR
    28 END
    29 POPUP "窗口(&W)"
    30 BEGIN
    31 MENUITEM "新建窗口(&N)", ID_WINDOW_NEW
    32 MENUITEM "层叠(&C)", ID_WINDOW_CASCADE
    33 MENUITEM "平铺(&T)", ID_WINDOW_TILE_HORZ
    34 MENUITEM "排列图标(&A)", ID_WINDOW_ARRANGE
    35 END
    36 POPUP "帮助(&H)"
    37 BEGIN
    38 MENUITEM "关于 uu(&A)...", ID_APP_ABOUT
    39 END
    40 END

    4. 字符串表,用来标识文件类型的。just copy it

    1     IDR_uuTYPE         "\nuu\nuu\n\n\nuu.Document\nuu.Document"
    2 IDR_xxTYPE "\nxx\nxx\n\n\nxx.Document\nxx.Document"

    5. 喔,差点忘了,还需要在Resource.h中定义

    1 #define IDR_xxTYPE                    133

    第三步:实现动态切换
    其实其实,做到这里,动态菜单已经好了,不信你试试?新建一个文档,看看菜单是不是变了?

    这里需要做的是将工具栏换掉。一般而言,工具栏和菜单上的项是对应的。

    说说切换原理吧,当某个文档被激活、被关闭、文档间切换都会导致ChildFrame的WM_MDIACTIVATE消息。我们捕获这个消息就可以动态改变工具栏了。

    在ChildFrame中添加WM_MDIACTIVATE消息处理函数,该函数原型为:

    1 afx_msg void OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd);

    第一个参数bActivate表明是激活还是不激活,第二个参数是激活的窗口,第三个参数是无效的窗口。

    在该函数添加以下语句:

     1     CMDIChildWndEx::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd); //调用基类,不然菜单就不切换了
    2 //My activate
    3 if(pActivateWnd != NULL && pActivateWnd->m_hWnd == this->m_hWnd)
    4 {
    5 CMainFrame* pMainFrame = DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
    6 if(pMainFrame != NULL)
    7 {
    8 pMainFrame->m_wndToolBar.LoadToolBar(IDR_xxTYPE);
    9 pMainFrame->m_wndToolBar.AdjustLayout(); //刷新工具栏
    10 }
    11 }
    12 //My Deactivate
    13 if(pDeactivateWnd != NULL && pDeactivateWnd->m_hWnd == this->m_hWnd)
    14 {
    15 if(pActivateWnd == NULL)
    16 {
    17 //还原为IDR_MAINFRAME
    18 CMainFrame* pMainFrame = DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
    19 if(pMainFrame != NULL)
    20 {
    21 pMainFrame->m_wndToolBar.LoadToolBar(IDR_MAINFRAME_256);
    22 pMainFrame->m_wndToolBar.AdjustLayout(); //刷新工具栏
    23
    24 }
    25 }
    26 }

    上述代码的意思是,如果我被激活,那么我就载入我自己的工具栏。如果我被无效,并且要激活的窗口为空,表示这时所有文档都被关闭,需要载入IDR_MAINFRAME的工具栏。

    大功告成,有了动态菜单和动态工具栏,多视图的文档使用起来灵活多了。








  • 相关阅读:
    小儿吃鸡蛋食积案
    女子经前胀痛脸上红斑案
    小儿外感咳嗽咽痛案
    顽固偏头痛案
    交通心肾治失眠
    小儿扁桃体高热兼咳嗽案
    过敏疾患与太少两感相合
    经前乳胀案
    女子黃带案
    小儿外感后频繁眨眼案
  • 原文地址:https://www.cnblogs.com/zhangyonghugo/p/MDI_Dynamic_ToolBar.html
Copyright © 2011-2022 走看看