diff --git a/reactos/dll/win32/user32/windows/class.c b/reactos/dll/win32/user32/windows/class.c index 479f8ba2e24..acaa383910b 100644 --- a/reactos/dll/win32/user32/windows/class.c +++ b/reactos/dll/win32/user32/windows/class.c @@ -527,6 +527,7 @@ GetWindowLongA ( HWND hWnd, int nIndex ) return Wnd->UserData; case GWL_HWNDPARENT: + DbgPrint("GWL_HWNDPARENT\n"); /* FIXME: Implement in user32 */ case GWL_WNDPROC: /* Call win32k for this as a callproc handle may need @@ -580,6 +581,7 @@ GetWindowLongW(HWND hWnd, int nIndex) return Wnd->UserData; case GWL_HWNDPARENT: + DbgPrint("GWL_HWNDPARENT\n"); /* FIXME: Implement in user32 */ case GWL_WNDPROC: /* Call win32k for this as a callproc handle may need diff --git a/reactos/dll/win32/user32/windows/window.c b/reactos/dll/win32/user32/windows/window.c index 321b2757407..dbca2e5b209 100644 --- a/reactos/dll/win32/user32/windows/window.c +++ b/reactos/dll/win32/user32/windows/window.c @@ -893,7 +893,37 @@ GetLastActivePopup(HWND hWnd) HWND STDCALL GetParent(HWND hWnd) { - return NtUserGetParent(hWnd); + PWINDOW Wnd, WndParent; + HWND Ret = NULL; + + Wnd = ValidateHwnd(hWnd); + if (Wnd != NULL) + { + _SEH_TRY + { + WndParent = NULL; + if (Wnd->Style & WS_CHILD) + { + if (Wnd->Parent != NULL) + WndParent = DesktopPtrToUser(Wnd->Parent); + } + else if (Wnd->Style & WS_POPUP) + { + if (Wnd->Owner != NULL) + WndParent = DesktopPtrToUser(Wnd->Owner); + } + + if (WndParent != NULL) + Ret = UserHMGetHandle(WndParent); + } + _SEH_HANDLE + { + /* Do nothing */ + } + _SEH_END; + } + + return Ret; } diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index 99d7ed281a3..78f5e8d94dd 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -5,6 +5,9 @@ struct _W32PROCESSINFO; struct _W32THREADINFO; struct _WINDOW; +/* FIXME: UserHMGetHandle needs to be updated once the new handle manager is implemented */ +#define UserHMGetHandle(obj) ((obj)->hdr.Handle) + typedef struct _REGISTER_SYSCLASS { /* This is a reactos specific class used to initialize the @@ -19,6 +22,12 @@ typedef struct _REGISTER_SYSCLASS UINT ClassId; } REGISTER_SYSCLASS, *PREGISTER_SYSCLASS; +typedef struct _USER_OBJHDR +{ + /* This is the common header for all user handle objects */ + HANDLE Handle; +} USER_OBJHDR, PUSER_OBJHDR; + typedef struct _DESKTOP { HANDLE hKernelHeap; @@ -32,6 +41,7 @@ typedef struct _DESKTOP typedef struct _CALLPROC { + USER_OBJHDR hdr; /* FIXME: Move out of the structure once new handle manager is implemented */ struct _W32PROCESSINFO *pi; WNDPROC WndProc; struct _CALLPROC *Next; @@ -92,6 +102,8 @@ typedef struct _WINDOWCLASS typedef struct _WINDOW { + USER_OBJHDR hdr; /* FIXME: Move out of the structure once new handle manager is implemented */ + /* NOTE: This structure is located in the desktop heap and will eventually replace WINDOW_OBJECT. Right now WINDOW_OBJECT keeps a reference to this structure until all the information @@ -110,6 +122,9 @@ typedef struct _WINDOW WNDPROC WndProcExtra; }; + struct _WINDOW *Parent; + struct _WINDOW *Owner; + /* Size of the extra data associated with the window. */ ULONG ExtraDataSize; /* Style. */ diff --git a/reactos/subsystems/win32/win32k/ntuser/callproc.c b/reactos/subsystems/win32/win32k/ntuser/callproc.c index 805d12acb83..0d66e05a530 100644 --- a/reactos/subsystems/win32/win32k/ntuser/callproc.c +++ b/reactos/subsystems/win32/win32k/ntuser/callproc.c @@ -67,6 +67,7 @@ CloneCallProc(IN PDESKTOP Desktop, sizeof(CALLPROC)); if (NewCallProc != NULL) { + NewCallProc->hdr.Handle = Handle; /* FIXME: Remove hack */ NewCallProc->pi = CallProc->pi; NewCallProc->WndProc = CallProc->WndProc; NewCallProc->Unicode = CallProc->Unicode; @@ -92,6 +93,7 @@ CreateCallProc(IN PDESKTOP Desktop, sizeof(CALLPROC)); if (NewCallProc != NULL) { + NewCallProc->hdr.Handle = Handle; /* FIXME: Remove hack */ NewCallProc->pi = pi; NewCallProc->WndProc = WndProc; NewCallProc->Unicode = Unicode; diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index f4de037b10b..a92734eba2a 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -908,6 +908,7 @@ IntLinkWindow( PWINDOW_OBJECT Parent; Wnd->Parent = WndParent; + Wnd->Wnd->Parent = WndParent ? WndParent->Wnd : NULL; if ((Wnd->PrevSibling = WndPrevSibling)) { /* link after WndPrevSibling */ @@ -964,9 +965,13 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner) if((WndNewOwner = UserGetWindowObject(hWndNewOwner))) { Wnd->hOwner = hWndNewOwner; + Wnd->Wnd->Owner = WndNewOwner->Wnd; } else + { Wnd->hOwner = NULL; + Wnd->Wnd->Owner = NULL; + } UserDerefObject(Wnd); return ret; @@ -1109,6 +1114,7 @@ IntUnlinkWindow(PWINDOW_OBJECT Wnd) WndParent->FirstChild = Wnd->NextSibling; Wnd->PrevSibling = Wnd->NextSibling = Wnd->Parent = NULL; + Wnd->Wnd->Parent = NULL; } BOOL FASTCALL @@ -1575,10 +1581,11 @@ co_IntCreateWindowEx(DWORD dwExStyle, sizeof(WINDOW) + Class->WndExtra); if (!Window->Wnd) goto AllocErr; - Wnd = Window->Wnd; - RtlZeroMemory(Window->Wnd, sizeof(WINDOW) + Class->WndExtra); + Window->Wnd->hdr.Handle = hWnd; /* FIXME: Remove hack */ + Wnd = Window->Wnd; + Wnd->ti = ti; Wnd->pi = ti->kpi; } @@ -1631,15 +1638,18 @@ AllocErr: Window->MessageQueue = PsGetCurrentThreadWin32Thread()->MessageQueue; IntReferenceMessageQueue(Window->MessageQueue); Window->Parent = ParentWindow; + Wnd->Parent = ParentWindow ? ParentWindow->Wnd : NULL; if((OwnerWindow = UserGetWindowObject(OwnerWindowHandle))) { Window->hOwner = OwnerWindowHandle; + Wnd->Owner = OwnerWindow->Wnd; HasOwner = TRUE; } else { Window->hOwner = NULL; + Wnd->Owner = NULL; HasOwner = FALSE; } @@ -2336,6 +2346,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window) if (Child->hOwner != NULL) { Child->hOwner = NULL; + Child->Wnd->Owner = NULL; } }