Системное меню, отображаемое TrackPopupMenu, не соответствует состоянию окна.

В моем приложении Qt я использовал DwmExtendFrameIntoClientArea чтобы расширить Aero Glass внутри моего окна, и я обработал WM_NCCALCSIZE WinEvent для рисования виджетов Qt в не клиентской области.

Кроме того, в моем приложении я обработал WM_NCRBUTTONUP WinEvent для отображения меню оконной системы (строки заголовка) внутри клиентской области моего окна.

Меню работает, я имею в виду, я могу восстановить, развернуть, свернуть и закрыть окно через это меню, однако, иногда включенные пункты меню не соответствуют состоянию окна, например: Иногда это меню не активируется восстановить, но позволяет развернуть окно, которое уже развернуто, пока у меня нет проблем с системным меню, отображаемым через панель задач Windows

Вопрос: как мне правильно показать, что меню соответствует текущему состоянию окна?

Код для прослушивания WinEvents:

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

Решение

На основе исходного кода Firefox я разработал следующий код, который решает мою проблему:

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);
}

Видимо, вам нужно вручную установить включенные и отключенные элементы.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector