diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index 14511c22d9d..63c08e5d795 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -239,120 +239,6 @@ HWND WINAPI ChildWindowFromPointEx( HWND parent, POINT pt, UINT flags ) } -/******************************************************************* - * WINPOS_GetWinOffset - * - * Calculate the offset between the origin of the two windows. Used - * to implement MapWindowPoints. - */ -static BOOL WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, BOOL *mirrored, POINT *ret_offset ) -{ - WND * wndPtr; - POINT offset; - BOOL mirror_from, mirror_to, ret; - HWND hwnd; - - offset.x = offset.y = 0; - *mirrored = mirror_from = mirror_to = FALSE; - - /* Translate source window origin to screen coords */ - if (hwndFrom) - { - if (!(wndPtr = WIN_GetPtr( hwndFrom ))) - { - SetLastError( ERROR_INVALID_WINDOW_HANDLE ); - return FALSE; - } - if (wndPtr == WND_OTHER_PROCESS) goto other_process; - if (wndPtr != WND_DESKTOP) - { - if (wndPtr->dwExStyle & WS_EX_LAYOUTRTL) - { - mirror_from = TRUE; - offset.x += wndPtr->client_rect.right - wndPtr->client_rect.left; - } - while (wndPtr->parent) - { - offset.x += wndPtr->client_rect.left; - offset.y += wndPtr->client_rect.top; - hwnd = wndPtr->parent; - WIN_ReleasePtr( wndPtr ); - if (!(wndPtr = WIN_GetPtr( hwnd ))) break; - if (wndPtr == WND_OTHER_PROCESS) goto other_process; - if (wndPtr == WND_DESKTOP) break; - if (wndPtr->flags & WIN_CHILDREN_MOVED) - { - WIN_ReleasePtr( wndPtr ); - goto other_process; - } - } - if (wndPtr && wndPtr != WND_DESKTOP) WIN_ReleasePtr( wndPtr ); - offset = point_win_to_thread_dpi( hwndFrom, offset ); - } - } - - /* Translate origin to destination window coords */ - if (hwndTo) - { - if (!(wndPtr = WIN_GetPtr( hwndTo ))) - { - SetLastError( ERROR_INVALID_WINDOW_HANDLE ); - return FALSE; - } - if (wndPtr == WND_OTHER_PROCESS) goto other_process; - if (wndPtr != WND_DESKTOP) - { - POINT pt = { 0, 0 }; - if (wndPtr->dwExStyle & WS_EX_LAYOUTRTL) - { - mirror_to = TRUE; - pt.x += wndPtr->client_rect.right - wndPtr->client_rect.left; - } - while (wndPtr->parent) - { - pt.x += wndPtr->client_rect.left; - pt.y += wndPtr->client_rect.top; - hwnd = wndPtr->parent; - WIN_ReleasePtr( wndPtr ); - if (!(wndPtr = WIN_GetPtr( hwnd ))) break; - if (wndPtr == WND_OTHER_PROCESS) goto other_process; - if (wndPtr == WND_DESKTOP) break; - if (wndPtr->flags & WIN_CHILDREN_MOVED) - { - WIN_ReleasePtr( wndPtr ); - goto other_process; - } - } - if (wndPtr && wndPtr != WND_DESKTOP) WIN_ReleasePtr( wndPtr ); - pt = point_win_to_thread_dpi( hwndTo, pt ); - offset.x -= pt.x; - offset.y -= pt.y; - } - } - - *mirrored = mirror_from ^ mirror_to; - if (mirror_from) offset.x = -offset.x; - *ret_offset = offset; - return TRUE; - - other_process: /* one of the parents may belong to another process, do it the hard way */ - SERVER_START_REQ( get_windows_offset ) - { - req->from = wine_server_user_handle( hwndFrom ); - req->to = wine_server_user_handle( hwndTo ); - req->dpi = get_thread_dpi(); - if ((ret = !wine_server_call_err( req ))) - { - ret_offset->x = reply->x; - ret_offset->y = reply->y; - *mirrored = reply->mirror; - } - } - SERVER_END_REQ; - return ret; -} - - /******************************************************************* * MapWindowPoints (USER32.@) */ @@ -365,21 +251,9 @@ INT WINAPI MapWindowPoints( HWND hwnd_from, HWND hwnd_to, POINT *points, UINT co /******************************************************************* * ClientToScreen (USER32.@) */ -BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt ) +BOOL WINAPI ClientToScreen( HWND hwnd, POINT *pt ) { - POINT offset; - BOOL mirrored; - - if (!hwnd) - { - SetLastError( ERROR_INVALID_WINDOW_HANDLE ); - return FALSE; - } - if (!WINPOS_GetWinOffset( hwnd, 0, &mirrored, &offset )) return FALSE; - lppnt->x += offset.x; - lppnt->y += offset.y; - if (mirrored) lppnt->x = -lppnt->x; - return TRUE; + return NtUserClientToScreen( hwnd, pt ); } diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 3ecbc043fc8..3df544b1bb1 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2669,6 +2669,25 @@ other_process: /* one of the parents may belong to another process, do it the h return ret; } +/* see ClientToScreen */ +static BOOL client_to_screen( HWND hwnd, POINT *pt ) +{ + POINT offset; + BOOL mirrored; + + if (!hwnd) + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return FALSE; + } + + if (!get_windows_offset( hwnd, 0, get_thread_dpi(), &mirrored, &offset )) return FALSE; + pt->x += offset.x; + pt->y += offset.y; + if (mirrored) pt->x = -pt->x; + return TRUE; +} + /* see ScreenToClient */ BOOL screen_to_client( HWND hwnd, POINT *pt ) { @@ -5090,6 +5109,9 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code ) { switch (code) { + case NtUserCallHwndParam_ClientToScreen: + return client_to_screen( hwnd, (POINT *)param ); + case NtUserCallHwndParam_EnableWindow: return enable_window( hwnd, param ); diff --git a/include/ntuser.h b/include/ntuser.h index 41abc1e2e14..6fed7a836e0 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -832,6 +832,7 @@ static inline BOOL NtUserIsWindowVisible( HWND hwnd ) /* NtUserCallHwndParam codes, not compatible with Windows */ enum { + NtUserCallHwndParam_ClientToScreen, NtUserCallHwndParam_EnableWindow, NtUserCallHwndParam_GetClassLongA, NtUserCallHwndParam_GetClassLongW, @@ -865,6 +866,11 @@ enum NtUserSpyGetMsgName, }; +static inline BOOL NtUserClientToScreen( HWND hwnd, POINT *pt ) +{ + return NtUserCallHwndParam( hwnd, (UINT_PTR)pt, NtUserCallHwndParam_ClientToScreen ); +} + static inline BOOL NtUserEnableWindow( HWND hwnd, BOOL enable ) { return NtUserCallHwndParam( hwnd, enable, NtUserCallHwndParam_EnableWindow );