[NTUSER][USER32] Re-implement WM_POPUPSYSTEMMENU message (#8144)

This PR resolves a bug of #8094. #8094
correctly validates the flags. TPM_SYSTEM_MENU is an internal flag
and not a valid flag for TrackPopupMenu.
Thus, calling TrackPopupMenu.TPM_SYSTEM_MENU
in User32DefWindowProc was wrong.
This caused failure of taskbar context
menu.

JIRA issue: CORE-20238

- Move WM_POPUPSYSTEMMENU
  message handling of user32 into
  win32k.sys!IntDefWindowProc.
- Use win32k.sys!IntTrackPopupMenuEx
  instead of user32!TrackPopupMenu
  in handling of WM_POPUPSYSTEMMENU.
This commit is contained in:
Katayama Hirofumi MZ 2025-06-19 22:59:27 +09:00 committed by GitHub
parent 9853869a79
commit 3a96c90c54
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 15 deletions

View file

@ -580,6 +580,57 @@ DefWndScreenshot(PWND pWnd)
UserCloseClipboard();
}
// WM_POPUPSYSTEMMENU
static BOOL
co_UserTrackSystemMenu(_In_ PWND pWnd, _In_ LONG nClickPos, _In_opt_ PUINT puCmdType)
{
USER_REFERENCE_ENTRY MenuRef, WndRef;
PMENU pMenu;
UINT uDefaultCmd;
FIXME("co_UserTrackSystemMenu() called\n"); // Useful trace, while working on CORE-3247
UserRefObjectCo(pWnd, &WndRef);
// Check style and make window foreground
if ((pWnd->style & WS_DISABLED) ||
(pWnd->state2 & WNDS2_INDESTROY) ||
(pWnd->head.pti->MessageQueue != gpqForeground && !co_IntSetForegroundWindow(pWnd)))
{
UserDerefObjectCo(pWnd);
return FALSE;
}
// Get the window's system menu
pMenu = IntGetSystemMenu(pWnd, FALSE);
if (!pMenu)
{
UserDerefObjectCo(pWnd);
return FALSE;
}
UserRefObjectCo(pMenu, &MenuRef);
// Set default menu item
if (puCmdType)
uDefaultCmd = *puCmdType;
else if (pWnd->style & (WS_MINIMIZE | WS_MAXIMIZE))
uDefaultCmd = SC_RESTORE;
else
uDefaultCmd = SC_MAXIMIZE;
UserSetMenuDefaultItem(pMenu, uDefaultCmd, FALSE);
if (nClickPos == -1) // Input from keyboard?
FIXME("Use WM_KLUDGEMINRECT and TPM_VERTICAL\n");
// Show the menu and wait for menu tracking ending
IntTrackPopupMenuEx(pMenu, TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_SYSTEM_MENU,
LOWORD(nClickPos), HIWORD(nClickPos), pWnd, NULL);
UserDerefObjectCo(pMenu);
UserDerefObjectCo(pWnd);
return TRUE;
}
/*
Win32k counterpart of User DefWindowProc
*/
@ -697,6 +748,12 @@ IntDefWindowProc(
UserDerefObjectCo(Wnd->spwndParent);
break;
case WM_POPUPSYSTEMMENU:
/* This is an undocumented message used by the windows taskbar to
display the system menu of windows that belong to other processes. */
co_UserTrackSystemMenu(Wnd, (LONG)lParam, NULL);
break;
case WM_KEYF1:
{
HELPINFO hi;

View file

@ -327,21 +327,6 @@ User32DefWindowProc(HWND hWnd,
case WM_DEVICECHANGE:
return TRUE;
case WM_POPUPSYSTEMMENU:
{
/* This is an undocumented message used by the windows taskbar to
display the system menu of windows that belong to other processes. */
HMENU menu = GetSystemMenu(hWnd, FALSE);
ERR("WM_POPUPSYSTEMMENU\n");
if (menu)
{
SetForegroundWindow(hWnd);
TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_SYSTEM_MENU,
LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
}
return 0;
}
case WM_RBUTTONUP:
{
POINT Pt;
@ -798,6 +783,7 @@ User32DefWindowProc(HWND hWnd,
case WM_WINDOWPOSCHANGED:
case WM_APPCOMMAND:
case WM_SETCURSOR:
case WM_POPUPSYSTEMMENU:
GoSS:
{
LRESULT lResult;