创建一个像系统默认菜单一样的窗口?

时间:2013-04-09 03:02:53

标签: winapi user-interface

我在主窗口中创建了一个窗口。当新窗口显示时,主窗口失去焦点并停用。

因此主窗口的框架未激活,如下图所示: enter image description here

虽然激活的主窗口应如下所示: enter image description here

问题是我需要在创建和显示新窗口时保持主窗口激活,这类似于系统菜单窗口。

我怎么能这样做?

2 个答案:

答案 0 :(得分:0)

对于新窗口可能类似于SW_SHOWNA / SWP_NOACTIVATE?

答案 1 :(得分:0)

int HandledWidget::showPopup()
{
    int nRet(-1);

    show(SW_SHOWNOACTIVATE);

    BOOL bMenuDestroyed(FALSE);
    BOOL bMsgQuit(FALSE);
    HWND m_hWndOwner = GetWindow(m_hWnd, GW_OWNER);
    assert(GetForegroundWindow() == m_hWndOwner);

    while(TRUE)
    {
        if(GetProp(m_hWnd, MENU_EXIT_NOTIFY) != 0)
        {
            nRet = (int)GetProp(m_hWnd, MENU_EXIT_COMMAND_ID);
            break;
        }

        if(GetActiveWindow() != m_hWndOwner)
        {
            break;
        }

        m_bIsPopingUp = true;

        MSG msg = {0};
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if(msg.message == WM_KEYDOWN
                || msg.message == WM_SYSKEYDOWN
                || msg.message == WM_KEYUP
                || msg.message == WM_SYSKEYUP
                || msg.message == WM_CHAR
                || msg.message == WM_IME_CHAR
                || msg.message == WM_MOUSEWHEEL
                )
            {
                //transfer the message to menu window
                msg.hwnd = m_hWnd;
            }
            else if(msg.message == WM_LBUTTONDOWN
                || msg.message == WM_RBUTTONDOWN
                || msg.message == WM_NCLBUTTONDOWN
                || msg.message == WM_NCRBUTTONDOWN)
            {
                //click on other window
                if(msg.hwnd != m_hWnd)
                {
                    m_bIsPopingUp = false;
                    DestroyWindow(m_hWnd);
                    bMenuDestroyed = TRUE;
                }
            }
            else if(msg.message == WM_QUIT)
            {
                bMsgQuit = TRUE;
            }

            TranslateMessage (&msg);
            DispatchMessageW (&msg);
        }
        else
        {
            MsgWaitForMultipleObjects (0, 0, 0, 10, QS_ALLINPUT);
        }

        if(bMenuDestroyed) break;

        if(bMsgQuit)
        {
            PostQuitMessage(msg.wParam);
            break;
        }
    }

    m_bIsPopingUp = false;

    if(!bMenuDestroyed) DestroyWindow(m_hWnd);

    return nRet;
}

bool HandledWidget::exitPopup(int nCommandId)
{
    BOOL bRet = SetProp(m_hWnd, MENU_EXIT_NOTIFY, (HANDLE)1);
    SetProp(m_hWnd, MENU_EXIT_COMMAND_ID, (HANDLE)nCommandId);
    return bRet;
}

并处理wm_mouseactivate:

LRESULT ComboxList::onMouseActivate( WPARAM wParam, LPARAM lParam, bool &bHandled )
{
    bHandled = true;
    return MA_NOACTIVATE;
}

请记住不要使用SetFocus / SetWindowPos(SW_SHOWWINDOW)/ ShowWindow(SW_SHOW)/ SetActivate / SetForegroundWindow等激活新窗口。

然后你会得到一个非激活窗口,就像系统菜单一样。

参考:http://www.cppblog.com/weiym/archive/2013/04/07/199189.html