mirror of
https://github.com/reactos/reactos.git
synced 2025-05-25 12:14:32 +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
|
TWOPARAM_ROUTINE_WOWCLEANUP
|
||||||
};
|
};
|
||||||
|
|
||||||
DWORD
|
DWORD_PTR
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserCallHwnd(
|
NtUserCallHwnd(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
|
|
|
@ -495,6 +495,58 @@ DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
|
||||||
return (LRESULT)hIconRet;
|
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
|
VOID FASTCALL
|
||||||
DefWndScreenshot(PWND pWnd)
|
DefWndScreenshot(PWND pWnd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -706,7 +706,7 @@ NtUserCallHwndOpt(
|
||||||
return hWnd;
|
return hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
DWORD_PTR
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserCallHwnd(
|
NtUserCallHwnd(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
|
@ -755,6 +755,17 @@ NtUserCallHwnd(
|
||||||
UserLeave();
|
UserLeave();
|
||||||
return FALSE;
|
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;
|
STUB;
|
||||||
|
|
|
@ -161,6 +161,7 @@ LRESULT NC_HandleNCRButtonDown( PWND wnd, WPARAM wParam, LPARAM lParam );
|
||||||
HBRUSH FASTCALL DefWndControlColor(HDC hDC,UINT ctlType);
|
HBRUSH FASTCALL DefWndControlColor(HDC hDC,UINT ctlType);
|
||||||
BOOL UserDrawSysMenuButton(PWND pWnd, HDC hDC, LPRECT Rect, BOOL Down);
|
BOOL UserDrawSysMenuButton(PWND pWnd, HDC hDC, LPRECT Rect, BOOL Down);
|
||||||
BOOL UserPaintCaption(PWND pWnd, INT Flags);
|
BOOL UserPaintCaption(PWND pWnd, INT Flags);
|
||||||
|
PWND FASTCALL DWP_GetEnabledPopup(PWND pWnd);
|
||||||
|
|
||||||
/************** LAYERED **************/
|
/************** LAYERED **************/
|
||||||
|
|
||||||
|
|
|
@ -428,7 +428,7 @@ IntGetWindow(HWND hWnd,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Wnd = NULL;
|
EngSetLastError(ERROR_INVALID_GW_COMMAND);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -725,22 +725,22 @@ EXTINLINE VOID NtUserxNotifyWinEvent(HWND hWnd, PVOID ne)
|
||||||
|
|
||||||
EXTINLINE DWORD NtUserxGetWindowContextHelpId(HWND hwnd)
|
EXTINLINE DWORD NtUserxGetWindowContextHelpId(HWND hwnd)
|
||||||
{
|
{
|
||||||
return NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID);
|
return (DWORD)NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTINLINE BOOL NtUserxDeregisterShellHookWindow(HWND hWnd)
|
EXTINLINE BOOL NtUserxDeregisterShellHookWindow(HWND hWnd)
|
||||||
{
|
{
|
||||||
return NtUserCallHwnd(hWnd, HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW);
|
return (BOOL)NtUserCallHwnd(hWnd, HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTINLINE BOOL NtUserxRegisterShellHookWindow(HWND hWnd)
|
EXTINLINE BOOL NtUserxRegisterShellHookWindow(HWND hWnd)
|
||||||
{
|
{
|
||||||
return NtUserCallHwnd(hWnd, HWND_ROUTINE_REGISTERSHELLHOOKWINDOW);
|
return (BOOL)NtUserCallHwnd(hWnd, HWND_ROUTINE_REGISTERSHELLHOOKWINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTINLINE BOOL NtUserxSetMessageBox(HWND hWnd)
|
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)
|
EXTINLINE VOID NtUserxClearWindowState(PWND pWnd, UINT Flag)
|
||||||
|
|
|
@ -1141,9 +1141,19 @@ GetWindow(HWND hWnd,
|
||||||
FoundWnd = DesktopPtrToUser(FoundWnd->spwndNext);
|
FoundWnd = DesktopPtrToUser(FoundWnd->spwndNext);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case GW_ENABLEDPOPUP:
|
||||||
Wnd = NULL;
|
{
|
||||||
|
PWND pwndPopup = (PWND)NtUserCallHwnd(hWnd, HWND_ROUTINE_DWP_GETENABLEDPOPUP);
|
||||||
|
if (pwndPopup)
|
||||||
|
FoundWnd = DesktopPtrToUser(pwndPopup);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
UserSetLastError(ERROR_INVALID_GW_COMMAND);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FoundWnd != NULL)
|
if (FoundWnd != NULL)
|
||||||
|
|
Loading…
Reference in a new issue