MFC Ribbon UI 弹出菜单实现解析

    添加时间:2013-6-16 点击量:

    微软推出的Ribbon UI界面在应用法度开辟上完全倾覆了以往的菜单+对象条的应用模式,很是有新鲜性。Ribbon UI有一个弹出窗口功能让人感触感染很困惑,窗口截图如下:



    经由过程spy4win对象抓取窗口信息发明这几个窗口都具有WS_POPUP属性,也就是说它是一个弹出窗口。支撑鼠标、键盘按键,也有弹出窗口的特点“点窗口里面不会封闭,点外就会封闭”,让人困惑的是这个弹出窗口还不会抢窗口核心。理论上一个具有WS_POPUP属性的窗口必然要激活才干支撑按键及点窗口外封闭这两个功能的,于是花了点时候研究了一下MFC 自带的Ribbon界面,解析了一下这个弹出窗口的实现道理,困惑解决了。首要解决办法如下:


    第一步:创建一个具有WS_POPUP属性的窗口并以不激活的体式格式显示创建的窗口



    BOOL CMFCPopupMenu::Create(CWnd pWndParent, int x, int y, HMENU hMenu, BOOL bLocked, BOOL bOwnMessage)
    {
    ……
    UINT nClassStyle = CS_SAVEBITS;
    CString strClassName = ::AfxRegisterWndClass(nClassStyle, ::LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_BTNFACE + 1), NULL);
    ……
    DWORD dwStyle = WS_POPUP;
    if (m_pMenuCustomizationPage != NULL)
    {
    dwStyle |= (WS_CAPTION | WS_SYSMENU);
    }
    ……
    CRect rect(x, y, x, y);
    BOOL bCreated = CMiniFrameWnd::CreateEx(pWndParent->GetExStyle() & WS_EX_LAYOUTRTL, strClassName, m_strCaption,
    dwStyle, rect, pWndParent->GetOwner() == NULL ? pWndParent : pWndParent->GetOwner());
    ……
    SetWindowPos(&wndTop, -1, -1, -1, -1, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    ……
    return TRUE;
    }


    第二步:设置鼠标点击时不激活窗口,实现了即支撑鼠标事务又不强核心的结果



    int CMFCPopupMenu::OnMouseActivate(CWnd /pDesktopWnd/, UINT /nHitTest/, UINT /message/
    {
    return MA_NOACTIVATE;
    }


     

    第三步:经由过程应用法度激活事务来封闭弹出窗口



    void CMFCPopupMenu::OnActivateApp(BOOL bActive, DWORD /dwThreadID/
    {
    if (!bActive && !CMFCToolBar::IsCustomizeMode() && !InCommand())
    {
    if (m_bTrackMode)
    {
    m_bTobeDstroyed = TRUE;
    }

    PostMessage(WM_CLOSE);
    }
    }


    第四步:经由过程主窗口向弹出窗口发送键盘事务,实现了弹出窗口在不激活的时辰还能处理惩罚按钮,在哪之前要确保弹出窗口时它的主窗口是激活的



    BOOL CFrameImpl::ProcessKeyboard(int nKey, BOOL pbProcessAccel)
    {
    ……
    if (CMFCPopupMenu::m_pActivePopupMenu != NULL && ::IsWindow(CMFCPopupMenu::m_pActivePopupMenu->m_hWnd))
    {
    ……
    CMFCPopupMenu::m_pActivePopupMenu->SendMessage(WM_KEYDOWN, nKey);
    ……
    }
    ……
    }


    经由过程这四步就实现了可接管鼠标、键盘事务,又不抢核心的弹出窗口。这个对一向被弹出窗口抢核心这个题目困惑着的伴侣有效。

    容易发怒的意思就是: 别人做了蠢事, 然后我们代替他们, 表现出笨蛋的样子。—— 蔡康永
    分享到: