TrackPopupMenu显示的系统菜单与窗口状态不匹配
问题描述:
在我的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);
}
答
:
码听的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);
}
显然,你需要手动设置启用和禁用物品。