mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[NTUSER][USER32] Support GetWindow.GW_ENABLEDPOPUP (#7700)
JIRA issue: CORE-6920 - Make the return value of NtUserCallHwnd a DWORD_PTR. - Add DWP_GetEnabledPopup helper function in win32ss/user/ntuser/defwnd.c. - Add code to NtUserCallHwnd for HWND_ROUTINE_DWP_GETENABLEDPOPUP. - Add code to GetWindow for GW_ENABLEDPOPUP. - Set last error in GetWindow and IntGetWindow.
This commit is contained in:
parent
2d8a2944ba
commit
22577aed85
7 changed files with 83 additions and 9 deletions
|
@ -1670,7 +1670,7 @@ enum SimpleCallRoutines
|
|||
TWOPARAM_ROUTINE_WOWCLEANUP
|
||||
};
|
||||
|
||||
DWORD
|
||||
DWORD_PTR
|
||||
NTAPI
|
||||
NtUserCallHwnd(
|
||||
HWND hWnd,
|
||||
|
|
|
@ -495,6 +495,58 @@ DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
|
|||
return (LRESULT)hIconRet;
|
||||
}
|
||||
|
||||
PWND FASTCALL
|
||||
DWP_GetEnabledPopup(PWND pWnd)
|
||||
{
|
||||
PWND pwndNode1;
|
||||
PTHREADINFO pti = pWnd->head.pti, ptiNode;
|
||||
BOOL bFoundNullNode = FALSE;
|
||||
|
||||
for (pwndNode1 = pWnd->spwndNext; pwndNode1 != pWnd; )
|
||||
{
|
||||
if (!pwndNode1) /* NULL detected? */
|
||||
{
|
||||
if (bFoundNullNode)
|
||||
return NULL;
|
||||
bFoundNullNode = TRUE;
|
||||
/* Retry with parent's first child (once only) */
|
||||
pwndNode1 = pWnd->spwndParent->spwndChild;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. We want to detect the window that owns the same input target of pWnd.
|
||||
* 2. For non-16-bit apps, we need to check the two threads' input queues to
|
||||
* see whether they are the same, while for 16-bit apps it's sufficient to
|
||||
* only check the thread info pointers themselves (ptiNode and pti).
|
||||
* See also:
|
||||
* https://devblogs.microsoft.com/oldnewthing/20060221-09/?p=32203
|
||||
* https://github.com/reactos/reactos/pull/7700#discussion_r1939435931
|
||||
*/
|
||||
ptiNode = pwndNode1->head.pti;
|
||||
if ((!(pti->TIF_flags & TIF_16BIT) && ptiNode->MessageQueue == pti->MessageQueue) ||
|
||||
((pti->TIF_flags & TIF_16BIT) && ptiNode == pti))
|
||||
{
|
||||
DWORD style = pwndNode1->style;
|
||||
if ((style & WS_VISIBLE) && !(style & WS_DISABLED)) /* Visible and enabled? */
|
||||
{
|
||||
/* Does pwndNode1 have a pWnd as an ancestor? */
|
||||
PWND pwndNode2;
|
||||
for (pwndNode2 = pwndNode1->spwndOwner; pwndNode2;
|
||||
pwndNode2 = pwndNode2->spwndOwner)
|
||||
{
|
||||
if (pwndNode2 == pWnd)
|
||||
return pwndNode1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pwndNode1 = pwndNode1->spwndNext;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
DefWndScreenshot(PWND pWnd)
|
||||
{
|
||||
|
|
|
@ -706,7 +706,7 @@ NtUserCallHwndOpt(
|
|||
return hWnd;
|
||||
}
|
||||
|
||||
DWORD
|
||||
DWORD_PTR
|
||||
APIENTRY
|
||||
NtUserCallHwnd(
|
||||
HWND hWnd,
|
||||
|
@ -755,6 +755,17 @@ NtUserCallHwnd(
|
|||
UserLeave();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case HWND_ROUTINE_DWP_GETENABLEDPOPUP:
|
||||
{
|
||||
PWND pWnd;
|
||||
UserEnterShared();
|
||||
pWnd = UserGetWindowObject(hWnd);
|
||||
if (pWnd)
|
||||
pWnd = DWP_GetEnabledPopup(pWnd);
|
||||
UserLeave();
|
||||
return (DWORD_PTR)pWnd;
|
||||
}
|
||||
}
|
||||
|
||||
STUB;
|
||||
|
|
|
@ -161,6 +161,7 @@ LRESULT NC_HandleNCRButtonDown( PWND wnd, WPARAM wParam, LPARAM lParam );
|
|||
HBRUSH FASTCALL DefWndControlColor(HDC hDC,UINT ctlType);
|
||||
BOOL UserDrawSysMenuButton(PWND pWnd, HDC hDC, LPRECT Rect, BOOL Down);
|
||||
BOOL UserPaintCaption(PWND pWnd, INT Flags);
|
||||
PWND FASTCALL DWP_GetEnabledPopup(PWND pWnd);
|
||||
|
||||
/************** LAYERED **************/
|
||||
|
||||
|
|
|
@ -428,7 +428,7 @@ IntGetWindow(HWND hWnd,
|
|||
break;
|
||||
|
||||
default:
|
||||
Wnd = NULL;
|
||||
EngSetLastError(ERROR_INVALID_GW_COMMAND);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -725,22 +725,22 @@ EXTINLINE VOID NtUserxNotifyWinEvent(HWND hWnd, PVOID ne)
|
|||
|
||||
EXTINLINE DWORD NtUserxGetWindowContextHelpId(HWND hwnd)
|
||||
{
|
||||
return NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID);
|
||||
return (DWORD)NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID);
|
||||
}
|
||||
|
||||
EXTINLINE BOOL NtUserxDeregisterShellHookWindow(HWND hWnd)
|
||||
{
|
||||
return NtUserCallHwnd(hWnd, HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW);
|
||||
return (BOOL)NtUserCallHwnd(hWnd, HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW);
|
||||
}
|
||||
|
||||
EXTINLINE BOOL NtUserxRegisterShellHookWindow(HWND hWnd)
|
||||
{
|
||||
return NtUserCallHwnd(hWnd, HWND_ROUTINE_REGISTERSHELLHOOKWINDOW);
|
||||
return (BOOL)NtUserCallHwnd(hWnd, HWND_ROUTINE_REGISTERSHELLHOOKWINDOW);
|
||||
}
|
||||
|
||||
EXTINLINE BOOL NtUserxSetMessageBox(HWND hWnd)
|
||||
{
|
||||
return NtUserCallHwnd(hWnd, HWND_ROUTINE_SETMSGBOX);
|
||||
return (BOOL)NtUserCallHwnd(hWnd, HWND_ROUTINE_SETMSGBOX);
|
||||
}
|
||||
|
||||
EXTINLINE VOID NtUserxClearWindowState(PWND pWnd, UINT Flag)
|
||||
|
|
|
@ -1141,9 +1141,19 @@ GetWindow(HWND hWnd,
|
|||
FoundWnd = DesktopPtrToUser(FoundWnd->spwndNext);
|
||||
break;
|
||||
|
||||
default:
|
||||
Wnd = NULL;
|
||||
case GW_ENABLEDPOPUP:
|
||||
{
|
||||
PWND pwndPopup = (PWND)NtUserCallHwnd(hWnd, HWND_ROUTINE_DWP_GETENABLEDPOPUP);
|
||||
if (pwndPopup)
|
||||
FoundWnd = DesktopPtrToUser(pwndPopup);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
UserSetLastError(ERROR_INVALID_GW_COMMAND);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FoundWnd != NULL)
|
||||
|
|
Loading…
Reference in a new issue