diff --git a/dlls/user32/win.c b/dlls/user32/win.c index fb7d05b71dc..c860464125e 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -2908,39 +2908,7 @@ DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process ) */ HWND WINAPI GetParent( HWND hwnd ) { - WND *wndPtr; - HWND retvalue = 0; - - if (!(wndPtr = WIN_GetPtr( hwnd ))) - { - SetLastError( ERROR_INVALID_WINDOW_HANDLE ); - return 0; - } - if (wndPtr == WND_DESKTOP) return 0; - if (wndPtr == WND_OTHER_PROCESS) - { - LONG style = GetWindowLongW( hwnd, GWL_STYLE ); - if (style & (WS_POPUP | WS_CHILD)) - { - SERVER_START_REQ( get_window_tree ) - { - req->handle = wine_server_user_handle( hwnd ); - if (!wine_server_call_err( req )) - { - if (style & WS_POPUP) retvalue = wine_server_ptr_handle( reply->owner ); - else if (style & WS_CHILD) retvalue = wine_server_ptr_handle( reply->parent ); - } - } - SERVER_END_REQ; - } - } - else - { - if (wndPtr->dwStyle & WS_POPUP) retvalue = wndPtr->owner; - else if (wndPtr->dwStyle & WS_CHILD) retvalue = wndPtr->parent; - WIN_ReleasePtr( wndPtr ); - } - return retvalue; + return UlongToHandle( NtUserCallHwnd( hwnd, NtUserGetParent )); } diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index e3cf939db09..a46accddd71 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -296,6 +296,7 @@ extern void user_check_not_lock(void) DECLSPEC_HIDDEN; struct tagWND; extern HWND is_current_thread_window( HWND hwnd ) DECLSPEC_HIDDEN; extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN; +extern DWORD get_window_long( HWND hwnd, INT offset ) DECLSPEC_HIDDEN; extern void register_window_surface( struct window_surface *old, struct window_surface *new ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index f24fc531f16..eb49d9bf237 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -361,6 +361,44 @@ static DWORD get_window_thread( HWND hwnd, DWORD *process ) return tid; } +/* see GetParent */ +static HWND get_parent( HWND hwnd ) +{ + HWND retval = 0; + WND *win; + + if (!(win = get_win_ptr( hwnd ))) + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return 0; + } + if (win == WND_DESKTOP) return 0; + if (win == WND_OTHER_PROCESS) + { + LONG style = get_window_long( hwnd, GWL_STYLE ); + if (style & (WS_POPUP | WS_CHILD)) + { + SERVER_START_REQ( get_window_tree ) + { + req->handle = wine_server_user_handle( hwnd ); + if (!wine_server_call_err( req )) + { + if (style & WS_POPUP) retval = wine_server_ptr_handle( reply->owner ); + else if (style & WS_CHILD) retval = wine_server_ptr_handle( reply->parent ); + } + } + SERVER_END_REQ; + } + } + else + { + if (win->dwStyle & WS_POPUP) retval = win->owner; + else if (win->dwStyle & WS_CHILD) retval = win->parent; + release_win_ptr( win ); + } + return retval; +} + /* see GetWindow */ static HWND get_window_relative( HWND hwnd, UINT rel ) { @@ -557,7 +595,7 @@ static LONG_PTR get_window_long_size( HWND hwnd, INT offset, UINT size, BOOL ans } /* see GetWindowLongW */ -static DWORD get_window_long( HWND hwnd, INT offset ) +DWORD get_window_long( HWND hwnd, INT offset ) { return get_window_long_size( hwnd, offset, sizeof(LONG), FALSE ); } @@ -757,6 +795,8 @@ DWORD WINAPI NtUserCallHwnd( HWND hwnd, DWORD code ) { switch (code) { + case NtUserGetParent: + return HandleToUlong( get_parent( hwnd )); case NtUserGetWindowTextLength: return get_server_window_text( hwnd, NULL, 0 ); case NtUserIsWindow: diff --git a/include/ntuser.h b/include/ntuser.h index 3021a8a9af4..8ae916e57bd 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -139,6 +139,7 @@ enum /* NtUserCallHwnd codes, not compatible with Windows */ enum { + NtUserGetParent, NtUserGetWindowTextLength, NtUserIsWindow, };