• 给对话框添加菜单和状态栏


    From: http://hi.baidu.com/machh03/blog/item/f320a533fd1672fe1a4cfffe.html/cmtid/f3235f24ff89713a8644f950

     

    最近做了个播放器,用到这方面的知识挺多, 总结一下:

    1,添加菜单

    有多种方法

    (1:在resource View中选中对话框属性的 menu 属性

    (2:CMenu    m_Menu;

           m_Menu.LoadMenu(IDR_MAIN_MENU);
            SetMenu(&m_Menu);

           取消菜单 SetMenu(NULL);

    2,添加状态栏

    在头文件添加 /** 状态栏*/
    CStatusBar m_wndStatusBar;

      

    。CPP文件中添加

    /** 状态栏*/
    if (!m_wndStatusBar.Create(this) ||
            !m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT))
            )
    {
       TRACE0("Failed to create status bar\n");
       return -1;      // fail to create
    }

    3.WM_MENUSELECT消息

         这样手动添加的状态栏,无法接收WM_MENUSELECT消息,所以我们要自己添加

    ON_WM_MENUSELECT()

    响应的消息函数

    /**
    * 菜单栏选择
    */
    void CFilePlayerDlg::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSystemMenu)
    {
    CString sFileName;
    if(nItemID == AFX_IDS_IDLEMESSAGE)
    {
       sFileName = L"就绪";
       SendMessage(WM_SETMESSAGESTRING, (WPARAM)0, (LPARAM)(LPCTSTR)sFileName);
       return ;
    }
    if(nFlags & MF_SEPARATOR)
       return ;
    if(nFlags & (MF_SYSMENU | MF_POPUP))
       return ;

    CString   strStatusText;  
    strStatusText.LoadString( nItemID);   

    m_wndStatusBar.SetPaneText(0, strStatusText);//

    // SendMessage(WM_SETMESSAGESTRING, (WPARAM)0, (LPARAM)(LPCTSTR)strStatusText);

    return ;
    }

    这样就获得了菜单的提示内容,m_wndStatusBar.SetPaneText(0, strStatusText); //将菜单提示显示在状态栏第一个窗格。当然自己可以指定其它窗格,

    如果用 SendMessage(WM_SETMESSAGESTRING, (WPARAM)0, (LPARAM)(LPCTSTR)strStatusText);

    发送 WM_SETMESSAGESTRING消息也可实现,

    需要自己添加该消息的响应函数

    如下:

    ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString) // 消息宏

    消息处理函数

    LRESULT CFilePlayerDlg::OnSetMessageString(WPARAM wParam, LPARAM lParam)
    {
    LPCTSTR lpsz = NULL;
    CString strMessage;

    if (lParam != 0)
    {
       ASSERT(wParam == 0);    // can't have both an ID and a string
       lpsz = (LPCTSTR)lParam; // set an explicit string
    }
    else if (wParam != 0)
    {
       {
        LPTSTR lpsz = strMessage.GetBuffer(255);
        if (AfxLoadString(wParam, lpsz) != 0)
        {
         lpsz = _tcschr(lpsz, _T('\n'));
         if (lpsz != NULL)
          *lpsz = '\0';
        }
        else
        {
          TRACE1("Warning: no message line prompt for ID 0x%04X.\n", wParam);
        }
        strMessage.ReleaseBuffer();  
       }
       lpsz = strMessage;
    }
    m_wndStatusBar.SetWindowText(lpsz);   //显示菜单提示
    return 0L;
    }

    4. 这样手动给对话框添加菜单,不能响应菜单更新命令,没有OnInitMenuPopup()函数,所以需要自己实现

       手动添加            ON_WM_INITMENUPOPUP() // 响应菜单命令更新消息

    并添加相应的消息处理函数。

    // 给对话框添加处理菜单命令消息的函数 命令更新
    void CFilePlayerDlg::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex,BOOL bSysMenu)
    {
    ASSERT(pPopupMenu != NULL);
    // Check the enabled state of various menu items.

    CCmdUI state;
    state.m_pMenu = pPopupMenu;
    ASSERT(state.m_pOther == NULL);
    ASSERT(state.m_pParentMenu == NULL);

    // Determine if menu is popup in top-level menu and set m_pOther to
    // it if so (m_pParentMenu == NULL indicates that it is secondary popup).
    HMENU hParentMenu;
    if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)
       state.m_pParentMenu = pPopupMenu;    // Parent == child for tracking popup.
    else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
    {
       CWnd* pParent = this;
       // Child windows don't have menus--need to go to the top!
       if (pParent != NULL &&
        (hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
       {
        int nIndexMax = ::GetMenuItemCount(hParentMenu);
        for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
        {
         if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu)
         {
          // When popup is found, m_pParentMenu is containing menu.
          state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
          break;
         }
        }
       }
    }

    state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
    for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
       state.m_nIndex++)
    {
       state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
       if (state.m_nID == 0)
        continue; // Menu separator or invalid cmd - ignore it.

       ASSERT(state.m_pOther == NULL);
       ASSERT(state.m_pMenu != NULL);
       if (state.m_nID == (UINT)-1)
       {
        // Possibly a popup menu, route to first item of that popup.
        state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
        if (state.m_pSubMenu == NULL ||
         (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
         state.m_nID == (UINT)-1)
        {
         continue;       // First item of popup can't be routed to.
        }
        state.DoUpdate(this, TRUE);   // Popups are never auto disabled.
       }
       else
       {
        // Normal menu item.
        // Auto enable/disable if frame window has m_bAutoMenuEnable
        // set and command is _not_ a system command.
        state.m_pSubMenu = NULL;
        state.DoUpdate(this, FALSE);
       }

       // Adjust for menu deletions and additions.
       UINT nCount = pPopupMenu->GetMenuItemCount();
       if (nCount < state.m_nIndexMax)
       {
        state.m_nIndex -= (state.m_nIndexMax - nCount);
        while (state.m_nIndex < nCount &&
         pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
        {
         state.m_nIndex++;
        }
       }
       state.m_nIndexMax = nCount;
    }
    }

  • 相关阅读:
    Java 在方法和作用域内的内部类
    java 内部类和向上转型
    java 内部类使用 .this 和 .new
    java innerclasses(内部类)
    Java过滤器与SpringMVC拦截器之间的关系与区别
    Maven异常:Could not find artifact
    soapUI测试webservice(参数为xml格式的处理方式)
    maven仓库加载本地包依赖
    spring data jpa的学习总结
    Java 中常用缓存Cache机制的实现
  • 原文地址:https://www.cnblogs.com/joeblackzqq/p/1874494.html
Copyright © 2020-2023  润新知