Skip to content

Commit 22577ae

Browse files
authored
[NTUSER][USER32] Support GetWindow.GW_ENABLEDPOPUP (reactos#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.
1 parent 2d8a294 commit 22577ae

File tree

7 files changed

+82
-8
lines changed

7 files changed

+82
-8
lines changed

win32ss/include/ntuser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1670,7 +1670,7 @@ enum SimpleCallRoutines
16701670
TWOPARAM_ROUTINE_WOWCLEANUP
16711671
};
16721672

1673-
DWORD
1673+
DWORD_PTR
16741674
NTAPI
16751675
NtUserCallHwnd(
16761676
HWND hWnd,

win32ss/user/ntuser/defwnd.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,58 @@ DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
495495
return (LRESULT)hIconRet;
496496
}
497497

498+
PWND FASTCALL
499+
DWP_GetEnabledPopup(PWND pWnd)
500+
{
501+
PWND pwndNode1;
502+
PTHREADINFO pti = pWnd->head.pti, ptiNode;
503+
BOOL bFoundNullNode = FALSE;
504+
505+
for (pwndNode1 = pWnd->spwndNext; pwndNode1 != pWnd; )
506+
{
507+
if (!pwndNode1) /* NULL detected? */
508+
{
509+
if (bFoundNullNode)
510+
return NULL;
511+
bFoundNullNode = TRUE;
512+
/* Retry with parent's first child (once only) */
513+
pwndNode1 = pWnd->spwndParent->spwndChild;
514+
continue;
515+
}
516+
517+
/*
518+
* 1. We want to detect the window that owns the same input target of pWnd.
519+
* 2. For non-16-bit apps, we need to check the two threads' input queues to
520+
* see whether they are the same, while for 16-bit apps it's sufficient to
521+
* only check the thread info pointers themselves (ptiNode and pti).
522+
* See also:
523+
* https://devblogs.microsoft.com/oldnewthing/20060221-09/?p=32203
524+
* https://github.com/reactos/reactos/pull/7700#discussion_r1939435931
525+
*/
526+
ptiNode = pwndNode1->head.pti;
527+
if ((!(pti->TIF_flags & TIF_16BIT) && ptiNode->MessageQueue == pti->MessageQueue) ||
528+
((pti->TIF_flags & TIF_16BIT) && ptiNode == pti))
529+
{
530+
DWORD style = pwndNode1->style;
531+
if ((style & WS_VISIBLE) && !(style & WS_DISABLED)) /* Visible and enabled? */
532+
{
533+
/* Does pwndNode1 have a pWnd as an ancestor? */
534+
PWND pwndNode2;
535+
for (pwndNode2 = pwndNode1->spwndOwner; pwndNode2;
536+
pwndNode2 = pwndNode2->spwndOwner)
537+
{
538+
if (pwndNode2 == pWnd)
539+
return pwndNode1;
540+
}
541+
}
542+
}
543+
544+
pwndNode1 = pwndNode1->spwndNext;
545+
}
546+
547+
return NULL;
548+
}
549+
498550
VOID FASTCALL
499551
DefWndScreenshot(PWND pWnd)
500552
{

win32ss/user/ntuser/simplecall.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ NtUserCallHwndOpt(
706706
return hWnd;
707707
}
708708

709-
DWORD
709+
DWORD_PTR
710710
APIENTRY
711711
NtUserCallHwnd(
712712
HWND hWnd,
@@ -755,6 +755,17 @@ NtUserCallHwnd(
755755
UserLeave();
756756
return FALSE;
757757
}
758+
759+
case HWND_ROUTINE_DWP_GETENABLEDPOPUP:
760+
{
761+
PWND pWnd;
762+
UserEnterShared();
763+
pWnd = UserGetWindowObject(hWnd);
764+
if (pWnd)
765+
pWnd = DWP_GetEnabledPopup(pWnd);
766+
UserLeave();
767+
return (DWORD_PTR)pWnd;
768+
}
758769
}
759770

760771
STUB;

win32ss/user/ntuser/userfuncs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ LRESULT NC_HandleNCRButtonDown( PWND wnd, WPARAM wParam, LPARAM lParam );
161161
HBRUSH FASTCALL DefWndControlColor(HDC hDC,UINT ctlType);
162162
BOOL UserDrawSysMenuButton(PWND pWnd, HDC hDC, LPRECT Rect, BOOL Down);
163163
BOOL UserPaintCaption(PWND pWnd, INT Flags);
164+
PWND FASTCALL DWP_GetEnabledPopup(PWND pWnd);
164165

165166
/************** LAYERED **************/
166167

win32ss/user/ntuser/window.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ IntGetWindow(HWND hWnd,
428428
break;
429429

430430
default:
431-
Wnd = NULL;
431+
EngSetLastError(ERROR_INVALID_GW_COMMAND);
432432
break;
433433
}
434434

win32ss/user/user32/include/ntwrapper.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -725,22 +725,22 @@ EXTINLINE VOID NtUserxNotifyWinEvent(HWND hWnd, PVOID ne)
725725

726726
EXTINLINE DWORD NtUserxGetWindowContextHelpId(HWND hwnd)
727727
{
728-
return NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID);
728+
return (DWORD)NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID);
729729
}
730730

731731
EXTINLINE BOOL NtUserxDeregisterShellHookWindow(HWND hWnd)
732732
{
733-
return NtUserCallHwnd(hWnd, HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW);
733+
return (BOOL)NtUserCallHwnd(hWnd, HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW);
734734
}
735735

736736
EXTINLINE BOOL NtUserxRegisterShellHookWindow(HWND hWnd)
737737
{
738-
return NtUserCallHwnd(hWnd, HWND_ROUTINE_REGISTERSHELLHOOKWINDOW);
738+
return (BOOL)NtUserCallHwnd(hWnd, HWND_ROUTINE_REGISTERSHELLHOOKWINDOW);
739739
}
740740

741741
EXTINLINE BOOL NtUserxSetMessageBox(HWND hWnd)
742742
{
743-
return NtUserCallHwnd(hWnd, HWND_ROUTINE_SETMSGBOX);
743+
return (BOOL)NtUserCallHwnd(hWnd, HWND_ROUTINE_SETMSGBOX);
744744
}
745745

746746
EXTINLINE VOID NtUserxClearWindowState(PWND pWnd, UINT Flag)

win32ss/user/user32/windows/window.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,9 +1141,19 @@ GetWindow(HWND hWnd,
11411141
FoundWnd = DesktopPtrToUser(FoundWnd->spwndNext);
11421142
break;
11431143

1144+
case GW_ENABLEDPOPUP:
1145+
{
1146+
PWND pwndPopup = (PWND)NtUserCallHwnd(hWnd, HWND_ROUTINE_DWP_GETENABLEDPOPUP);
1147+
if (pwndPopup)
1148+
FoundWnd = DesktopPtrToUser(pwndPopup);
1149+
break;
1150+
}
1151+
11441152
default:
1145-
Wnd = NULL;
1153+
{
1154+
UserSetLastError(ERROR_INVALID_GW_COMMAND);
11461155
break;
1156+
}
11471157
}
11481158

11491159
if (FoundWnd != NULL)

0 commit comments

Comments
 (0)