2014-02-11 78 views
0

在我的Qt應用程序中,我使用DwmExtendFrameIntoClientArea來擴展窗口內的Aero Glass,並且我處理了WM_NCCALCSIZE WinEvent以在非客戶端區域繪製Qt小部件。TrackPopupMenu顯示的系統菜單與窗口狀態不匹配

另外,在我的應用程序中,我處理了WM_NCRBUTTONUP WinEvent,在窗口的客戶區域內顯示窗口系統(標題欄)菜單。例如:有時菜單起作用,我的意思是,我可以通過該菜單恢復,最大化,最小化和關閉窗口,但是,有時啓用的菜單項與窗口的狀態不匹配。不啓用恢復,但啓用已經最大化的窗口最大化,而我沒有問題,通過Windows任務欄顯示系統菜單

問題:我如何正確顯示與當前窗口狀態相匹配的菜單?基於我開發了下面的代碼,解決我的問題Firefox的源代碼

bool MainWindow::winEvent(MSG *msg, long *result) 
{ 
    HWND hWnd = msg->hwnd; 
    UINT message = msg->message; 
    WPARAM wParam = msg->wParam; 
    LPARAM lParam = msg->lParam; 

    bool retval = false; 
    LRESULT lRet = 0; 

    switch(message) 
    { 
    case WM_NCHITTEST: 
    { 
     lRet = HitTestNCA(hWnd, lParam); 
     DwmDefWindowProc(hWnd, message, wParam, lParam, &lRet); 
     retval = true; 
     break; 
    } 
    case WM_NCRBUTTONUP: 
    { 
     QPoint point = QCursor::pos(); 
     HMENU menu = GetSystemMenu(hWnd, FALSE); 
     BOOL Selected = TrackPopupMenu(menu, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, point.x(), point.y(), 0, hWnd, NULL); 
     if(Selected) PostMessage(hWnd, WM_SYSCOMMAND, Selected, 0); 
     break; 
    } 
    case WM_NCCALCSIZE: 
    { 
     retval = true; 
     break; 
    } 
    default: 
     break; 
    } 

    *result = lRet; 

    if(retval) return true; 

    return QMainWindow::winEvent(msg, result); 
} 

回答

0

碼聽的WinEvents

HMENU hMenu = GetSystemMenu(hWnd, FALSE); 

if (hMenu) 
{ 
    MENUITEMINFO mii; 
    mii.cbSize = sizeof(MENUITEMINFO); 
    mii.fMask = MIIM_STATE; 
    mii.fType = 0; 

    // update the options 
    mii.fState = MF_ENABLED; 
    SetMenuItemInfo(hMenu, SC_RESTORE, FALSE, &mii); 
    SetMenuItemInfo(hMenu, SC_SIZE, FALSE, &mii); 
    SetMenuItemInfo(hMenu, SC_MOVE, FALSE, &mii); 
    SetMenuItemInfo(hMenu, SC_MAXIMIZE, FALSE, &mii); 
    SetMenuItemInfo(hMenu, SC_MINIMIZE, FALSE, &mii); 

    mii.fState = MF_GRAYED; 

    WINDOWPLACEMENT wp; 
    GetWindowPlacement(hWnd, &wp); 

    switch (wp.showCmd) 
    { 
    case SW_SHOWMAXIMIZED: 
     SetMenuItemInfo(hMenu, SC_SIZE, FALSE, &mii); 
     SetMenuItemInfo(hMenu, SC_MOVE, FALSE, &mii); 
     SetMenuItemInfo(hMenu, SC_MAXIMIZE, FALSE, &mii); 
     SetMenuDefaultItem(hMenu, SC_CLOSE, FALSE); 
     break; 
    case SW_SHOWMINIMIZED: 
     SetMenuItemInfo(hMenu, SC_MINIMIZE, FALSE, &mii); 
     SetMenuDefaultItem(hMenu, SC_RESTORE, FALSE); 
     break; 
    case SW_SHOWNORMAL: 
     SetMenuItemInfo(hMenu, SC_RESTORE, FALSE, &mii); 
     SetMenuDefaultItem(hMenu, SC_CLOSE, FALSE); 
     break; 
    } 

    LPARAM cmd = TrackPopupMenu(hMenu, (TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD), 
           GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), NULL, hWnd, NULL); 

    if (cmd) PostMessage(hWnd, WM_SYSCOMMAND, cmd, 0); 
} 

顯然,你需要手動設置啓用和禁用物品。