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.
|
* 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 );
|
WND *win = WIN_GetPtr( hwnd );
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
|
@ -678,12 +678,51 @@ BOOL WIN_GetRectangles( HWND hwnd, RECT *rectWindow, RECT *rectClient )
|
||||||
}
|
}
|
||||||
if (rectWindow) *rectWindow = rect;
|
if (rectWindow) *rectWindow = rect;
|
||||||
if (rectClient) *rectClient = rect;
|
if (rectClient) *rectClient = rect;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (win == WND_OTHER_PROCESS)
|
if (win != WND_OTHER_PROCESS)
|
||||||
{
|
{
|
||||||
|
RECT window_rect = win->rectWindow, client_rect = win->rectClient;
|
||||||
|
|
||||||
|
switch (relative)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
WND *parent = WIN_GetPtr( win->parent );
|
||||||
|
if (parent == WND_DESKTOP) break;
|
||||||
|
if (!parent || parent == WND_OTHER_PROCESS)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if (rectWindow) *rectWindow = window_rect;
|
||||||
|
if (rectClient) *rectClient = client_rect;
|
||||||
|
WIN_ReleasePtr( win );
|
||||||
|
}
|
||||||
|
|
||||||
|
other_process:
|
||||||
SERVER_START_REQ( get_window_rectangles )
|
SERVER_START_REQ( get_window_rectangles )
|
||||||
{
|
{
|
||||||
req->handle = wine_server_user_handle( hwnd );
|
req->handle = wine_server_user_handle( hwnd );
|
||||||
|
req->relative = relative;
|
||||||
if ((ret = !wine_server_call_err( req )))
|
if ((ret = !wine_server_call_err( req )))
|
||||||
{
|
{
|
||||||
if (rectWindow)
|
if (rectWindow)
|
||||||
|
@ -703,13 +742,6 @@ BOOL WIN_GetRectangles( HWND hwnd, RECT *rectWindow, RECT *rectClient )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (rectWindow) *rectWindow = win->rectWindow;
|
|
||||||
if (rectClient) *rectClient = win->rectClient;
|
|
||||||
WIN_ReleasePtr( win );
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <winuser.h>
|
#include <winuser.h>
|
||||||
|
|
||||||
#include "user_private.h"
|
#include "user_private.h"
|
||||||
|
#include "wine/server_protocol.h"
|
||||||
|
|
||||||
struct tagCLASS;
|
struct tagCLASS;
|
||||||
struct tagDIALOGINFO;
|
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_IsCurrentThread( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||||
extern HWND WIN_SetOwner( HWND hwnd, HWND owner ) 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 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 LRESULT WIN_DestroyWindow( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||||
extern void WIN_DestroyThreadWindows( 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;
|
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 WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
|
||||||
{
|
{
|
||||||
BOOL ret = WIN_GetRectangles( hwnd, rect, NULL );
|
BOOL ret = WIN_GetRectangles( hwnd, COORDS_SCREEN, rect, NULL );
|
||||||
if (ret)
|
if (ret) TRACE( "hwnd %p %s\n", hwnd, wine_dbgstr_rect(rect) );
|
||||||
{
|
|
||||||
MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 );
|
|
||||||
TRACE( "hwnd %p (%s)\n", hwnd, wine_dbgstr_rect(rect) );
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,15 +231,7 @@ int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
|
BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
|
||||||
{
|
{
|
||||||
BOOL ret;
|
return WIN_GetRectangles( hwnd, COORDS_CLIENT, NULL, rect );
|
||||||
|
|
||||||
if ((ret = WIN_GetRectangles( hwnd, NULL, rect )))
|
|
||||||
{
|
|
||||||
rect->right -= rect->left;
|
|
||||||
rect->bottom -= rect->top;
|
|
||||||
rect->left = rect->top = 0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -407,7 +395,7 @@ HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
|
||||||
|
|
||||||
for (i = 0; list[i]; i++)
|
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 (!PtInRect( &rect, pt )) continue;
|
||||||
if (uFlags & (CWP_SKIPINVISIBLE|CWP_SKIPDISABLED))
|
if (uFlags & (CWP_SKIPINVISIBLE|CWP_SKIPDISABLED))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1930,9 +1930,10 @@ BOOL CDECL X11DRV_CreateDesktopWindow( HWND hwnd )
|
||||||
SERVER_START_REQ( get_window_rectangles )
|
SERVER_START_REQ( get_window_rectangles )
|
||||||
{
|
{
|
||||||
req->handle = wine_server_user_handle( hwnd );
|
req->handle = wine_server_user_handle( hwnd );
|
||||||
|
req->relative = COORDS_CLIENT;
|
||||||
wine_server_call( req );
|
wine_server_call( req );
|
||||||
width = reply->window.right - reply->window.left;
|
width = reply->window.right;
|
||||||
height = reply->window.bottom - reply->window.top;
|
height = reply->window.bottom;
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
|
|
@ -3268,6 +3268,8 @@ struct get_window_rectangles_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
user_handle_t handle;
|
user_handle_t handle;
|
||||||
|
int relative;
|
||||||
|
char __pad_20[4];
|
||||||
};
|
};
|
||||||
struct get_window_rectangles_reply
|
struct get_window_rectangles_reply
|
||||||
{
|
{
|
||||||
|
@ -3276,6 +3278,13 @@ struct get_window_rectangles_reply
|
||||||
rectangle_t visible;
|
rectangle_t visible;
|
||||||
rectangle_t client;
|
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;
|
struct set_cursor_reply set_cursor_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 407
|
#define SERVER_PROTOCOL_VERSION 408
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -2344,11 +2344,19 @@ enum message_type
|
||||||
/* Get the window and client rectangles of a window */
|
/* Get the window and client rectangles of a window */
|
||||||
@REQ(get_window_rectangles)
|
@REQ(get_window_rectangles)
|
||||||
user_handle_t handle; /* handle to the window */
|
user_handle_t handle; /* handle to the window */
|
||||||
|
int relative; /* coords relative to (see below) */
|
||||||
@REPLY
|
@REPLY
|
||||||
rectangle_t window; /* window rectangle */
|
rectangle_t window; /* window rectangle */
|
||||||
rectangle_t visible; /* visible part of the window rectangle */
|
rectangle_t visible; /* visible part of the window rectangle */
|
||||||
rectangle_t client; /* client rectangle */
|
rectangle_t client; /* client rectangle */
|
||||||
@END
|
@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 */
|
/* 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( FIELD_OFFSET(struct set_window_pos_reply, new_ex_style) == 12 );
|
||||||
C_ASSERT( sizeof(struct set_window_pos_reply) == 16 );
|
C_ASSERT( sizeof(struct set_window_pos_reply) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_request, handle) == 12 );
|
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, window) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_reply, visible) == 24 );
|
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_reply, visible) == 24 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_window_rectangles_reply, client) == 40 );
|
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 )
|
static void dump_get_window_rectangles_request( const struct get_window_rectangles_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " handle=%08x", req->handle );
|
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 )
|
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 );
|
struct window *win = get_window( req->handle );
|
||||||
|
|
||||||
if (win)
|
if (!win) return;
|
||||||
{
|
|
||||||
reply->window = win->window_rect;
|
reply->window = win->window_rect;
|
||||||
reply->visible = win->visible_rect;
|
reply->visible = win->visible_rect;
|
||||||
reply->client = win->client_rect;
|
reply->client = win->client_rect;
|
||||||
|
|
||||||
|
switch (req->relative)
|
||||||
|
{
|
||||||
|
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