user32: Add support for fetching window rectangles relative to various origins.
This commit is contained in:
parent
2349a5eb4f
commit
7295b6746d
|
@ -652,7 +652,7 @@ ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits )
|
|||
*
|
||||
* Get the window and client rectangles.
|
||||
*/
|
||||
BOOL WIN_GetRectangles( HWND hwnd, RECT *rectWindow, RECT *rectClient )
|
||||
BOOL WIN_GetRectangles( HWND hwnd, enum coords_relative relative, RECT *rectWindow, RECT *rectClient )
|
||||
{
|
||||
WND *win = WIN_GetPtr( hwnd );
|
||||
BOOL ret = TRUE;
|
||||
|
@ -678,38 +678,70 @@ BOOL WIN_GetRectangles( HWND hwnd, RECT *rectWindow, RECT *rectClient )
|
|||
}
|
||||
if (rectWindow) *rectWindow = rect;
|
||||
if (rectClient) *rectClient = rect;
|
||||
return TRUE;
|
||||
}
|
||||
else if (win == WND_OTHER_PROCESS)
|
||||
if (win != WND_OTHER_PROCESS)
|
||||
{
|
||||
SERVER_START_REQ( get_window_rectangles )
|
||||
RECT window_rect = win->rectWindow, client_rect = win->rectClient;
|
||||
|
||||
switch (relative)
|
||||
{
|
||||
req->handle = wine_server_user_handle( hwnd );
|
||||
if ((ret = !wine_server_call_err( req )))
|
||||
case COORDS_CLIENT:
|
||||
OffsetRect( &window_rect, -win->rectClient.left, -win->rectClient.top );
|
||||
OffsetRect( &client_rect, -win->rectClient.left, -win->rectClient.top );
|
||||
break;
|
||||
case COORDS_WINDOW:
|
||||
OffsetRect( &window_rect, -win->rectWindow.left, -win->rectWindow.top );
|
||||
OffsetRect( &client_rect, -win->rectWindow.left, -win->rectWindow.top );
|
||||
break;
|
||||
case COORDS_PARENT:
|
||||
break;
|
||||
case COORDS_SCREEN:
|
||||
while (win->parent)
|
||||
{
|
||||
if (rectWindow)
|
||||
WND *parent = WIN_GetPtr( win->parent );
|
||||
if (parent == WND_DESKTOP) break;
|
||||
if (!parent || parent == WND_OTHER_PROCESS)
|
||||
{
|
||||
rectWindow->left = reply->window.left;
|
||||
rectWindow->top = reply->window.top;
|
||||
rectWindow->right = reply->window.right;
|
||||
rectWindow->bottom = reply->window.bottom;
|
||||
}
|
||||
if (rectClient)
|
||||
{
|
||||
rectClient->left = reply->client.left;
|
||||
rectClient->top = reply->client.top;
|
||||
rectClient->right = reply->client.right;
|
||||
rectClient->bottom = reply->client.bottom;
|
||||
WIN_ReleasePtr( win );
|
||||
goto other_process;
|
||||
}
|
||||
WIN_ReleasePtr( win );
|
||||
win = parent;
|
||||
OffsetRect( &window_rect, -win->rectClient.left, -win->rectClient.top );
|
||||
OffsetRect( &client_rect, -win->rectClient.left, -win->rectClient.top );
|
||||
}
|
||||
break;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rectWindow) *rectWindow = win->rectWindow;
|
||||
if (rectClient) *rectClient = win->rectClient;
|
||||
if (rectWindow) *rectWindow = window_rect;
|
||||
if (rectClient) *rectClient = client_rect;
|
||||
WIN_ReleasePtr( win );
|
||||
}
|
||||
|
||||
other_process:
|
||||
SERVER_START_REQ( get_window_rectangles )
|
||||
{
|
||||
req->handle = wine_server_user_handle( hwnd );
|
||||
req->relative = relative;
|
||||
if ((ret = !wine_server_call_err( req )))
|
||||
{
|
||||
if (rectWindow)
|
||||
{
|
||||
rectWindow->left = reply->window.left;
|
||||
rectWindow->top = reply->window.top;
|
||||
rectWindow->right = reply->window.right;
|
||||
rectWindow->bottom = reply->window.bottom;
|
||||
}
|
||||
if (rectClient)
|
||||
{
|
||||
rectClient->left = reply->client.left;
|
||||
rectClient->top = reply->client.top;
|
||||
rectClient->right = reply->client.right;
|
||||
rectClient->bottom = reply->client.bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <winuser.h>
|
||||
|
||||
#include "user_private.h"
|
||||
#include "wine/server_protocol.h"
|
||||
|
||||
struct tagCLASS;
|
||||
struct tagDIALOGINFO;
|
||||
|
@ -81,7 +82,7 @@ extern HWND WIN_IsCurrentProcess( HWND hwnd ) DECLSPEC_HIDDEN;
|
|||
extern HWND WIN_IsCurrentThread( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern HWND WIN_SetOwner( HWND hwnd, HWND owner ) DECLSPEC_HIDDEN;
|
||||
extern ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits ) DECLSPEC_HIDDEN;
|
||||
extern BOOL WIN_GetRectangles( HWND hwnd, RECT *rectWindow, RECT *rectClient ) DECLSPEC_HIDDEN;
|
||||
extern BOOL WIN_GetRectangles( HWND hwnd, enum coords_relative relative, RECT *rectWindow, RECT *rectClient ) DECLSPEC_HIDDEN;
|
||||
extern LRESULT WIN_DestroyWindow( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern void WIN_DestroyThreadWindows( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, BOOL unicode ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -93,12 +93,8 @@ void WINAPI SwitchToThisWindow( HWND hwnd, BOOL alt_tab )
|
|||
*/
|
||||
BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
|
||||
{
|
||||
BOOL ret = WIN_GetRectangles( hwnd, rect, NULL );
|
||||
if (ret)
|
||||
{
|
||||
MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 );
|
||||
TRACE( "hwnd %p (%s)\n", hwnd, wine_dbgstr_rect(rect) );
|
||||
}
|
||||
BOOL ret = WIN_GetRectangles( hwnd, COORDS_SCREEN, rect, NULL );
|
||||
if (ret) TRACE( "hwnd %p %s\n", hwnd, wine_dbgstr_rect(rect) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -235,15 +231,7 @@ int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
|
|||
*/
|
||||
BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if ((ret = WIN_GetRectangles( hwnd, NULL, rect )))
|
||||
{
|
||||
rect->right -= rect->left;
|
||||
rect->bottom -= rect->top;
|
||||
rect->left = rect->top = 0;
|
||||
}
|
||||
return ret;
|
||||
return WIN_GetRectangles( hwnd, COORDS_CLIENT, NULL, rect );
|
||||
}
|
||||
|
||||
|
||||
|
@ -407,7 +395,7 @@ HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
|
|||
|
||||
for (i = 0; list[i]; i++)
|
||||
{
|
||||
if (!WIN_GetRectangles( list[i], &rect, NULL )) continue;
|
||||
if (!WIN_GetRectangles( list[i], COORDS_PARENT, &rect, NULL )) continue;
|
||||
if (!PtInRect( &rect, pt )) continue;
|
||||
if (uFlags & (CWP_SKIPINVISIBLE|CWP_SKIPDISABLED))
|
||||
{
|
||||
|
|
|
@ -1930,9 +1930,10 @@ BOOL CDECL X11DRV_CreateDesktopWindow( HWND hwnd )
|
|||
SERVER_START_REQ( get_window_rectangles )
|
||||
{
|
||||
req->handle = wine_server_user_handle( hwnd );
|
||||
req->relative = COORDS_CLIENT;
|
||||
wine_server_call( req );
|
||||
width = reply->window.right - reply->window.left;
|
||||
height = reply->window.bottom - reply->window.top;
|
||||
width = reply->window.right;
|
||||
height = reply->window.bottom;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
|
|
|
@ -3268,6 +3268,8 @@ struct get_window_rectangles_request
|
|||
{
|
||||
struct request_header __header;
|
||||
user_handle_t handle;
|
||||
int relative;
|
||||
char __pad_20[4];
|
||||
};
|
||||
struct get_window_rectangles_reply
|
||||
{
|
||||
|
@ -3276,6 +3278,13 @@ struct get_window_rectangles_reply
|
|||
rectangle_t visible;
|
||||
rectangle_t client;
|
||||
};
|
||||
enum coords_relative
|
||||
{
|
||||
COORDS_CLIENT,
|
||||
COORDS_WINDOW,
|
||||
COORDS_PARENT,
|
||||
COORDS_SCREEN
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -5506,6 +5515,6 @@ union generic_reply
|
|||
struct set_cursor_reply set_cursor_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 407
|
||||
#define SERVER_PROTOCOL_VERSION 408
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -2344,11 +2344,19 @@ enum message_type
|
|||
/* Get the window and client rectangles of a window */
|
||||
@REQ(get_window_rectangles)
|
||||
user_handle_t handle; /* handle to the window */
|
||||
int relative; /* coords relative to (see below) */
|
||||
@REPLY
|
||||
rectangle_t window; /* window rectangle */
|
||||
rectangle_t visible; /* visible part of the window rectangle */
|
||||
rectangle_t client; /* client rectangle */
|
||||
@END
|
||||
enum coords_relative
|
||||
{
|
||||
COORDS_CLIENT, /* relative to client area */
|
||||
COORDS_WINDOW, /* relative to whole window area */
|
||||
COORDS_PARENT, /* relative to parent's client area */
|
||||
COORDS_SCREEN /* relative to screen origin */
|
||||
};
|
||||
|
||||
|
||||
/* Get the window text */
|
||||
|
|
|
@ -1589,7 +1589,8 @@ C_ASSERT( FIELD_OFFSET(struct set_window_pos_reply, new_style) == 8 );
|
|||
C_ASSERT( FIELD_OFFSET(struct set_window_pos_reply, new_ex_style) == 12 );
|
||||
C_ASSERT( sizeof(struct set_window_pos_reply) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, handle) == 12 );
|
||||
C_ASSERT( sizeof(struct get_window_rectangles_request) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, relative) == 16 );
|
||||
C_ASSERT( sizeof(struct get_window_rectangles_request) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_reply, window) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_reply, visible) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_reply, client) == 40 );
|
||||
|
|
|
@ -2795,6 +2795,7 @@ static void dump_set_window_pos_reply( const struct set_window_pos_reply *req )
|
|||
static void dump_get_window_rectangles_request( const struct get_window_rectangles_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%08x", req->handle );
|
||||
fprintf( stderr, ", relative=%d", req->relative );
|
||||
}
|
||||
|
||||
static void dump_get_window_rectangles_reply( const struct get_window_rectangles_reply *req )
|
||||
|
|
|
@ -2122,11 +2122,34 @@ DECL_HANDLER(get_window_rectangles)
|
|||
{
|
||||
struct window *win = get_window( req->handle );
|
||||
|
||||
if (win)
|
||||
if (!win) return;
|
||||
|
||||
reply->window = win->window_rect;
|
||||
reply->visible = win->visible_rect;
|
||||
reply->client = win->client_rect;
|
||||
|
||||
switch (req->relative)
|
||||
{
|
||||
reply->window = win->window_rect;
|
||||
reply->visible = win->visible_rect;
|
||||
reply->client = win->client_rect;
|
||||
case COORDS_CLIENT:
|
||||
offset_rect( &reply->window, -win->client_rect.left, -win->client_rect.top );
|
||||
offset_rect( &reply->visible, -win->client_rect.left, -win->client_rect.top );
|
||||
offset_rect( &reply->client, -win->client_rect.left, -win->client_rect.top );
|
||||
break;
|
||||
case COORDS_WINDOW:
|
||||
offset_rect( &reply->window, -win->window_rect.left, -win->window_rect.top );
|
||||
offset_rect( &reply->visible, -win->window_rect.left, -win->window_rect.top );
|
||||
offset_rect( &reply->client, -win->window_rect.left, -win->window_rect.top );
|
||||
break;
|
||||
case COORDS_PARENT:
|
||||
break;
|
||||
case COORDS_SCREEN:
|
||||
client_to_screen_rect( win->parent, &reply->window );
|
||||
client_to_screen_rect( win->parent, &reply->visible );
|
||||
client_to_screen_rect( win->parent, &reply->client );
|
||||
break;
|
||||
default:
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue