user32: Implement LogicalToPhysicalPointForPerMonitorDPI() and PhysicalToLogicalPointForPerMonitorDPI().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
fb563978d8
commit
7fdf90e395
|
@ -3366,6 +3366,43 @@ DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT
|
|||
return ULongToHandle( prev );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* LogicalToPhysicalPointForPerMonitorDPI (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI LogicalToPhysicalPointForPerMonitorDPI( HWND hwnd, POINT *pt )
|
||||
{
|
||||
UINT system_dpi = get_system_dpi();
|
||||
UINT dpi = GetDpiForWindow( hwnd );
|
||||
RECT rect;
|
||||
|
||||
GetWindowRect( hwnd, &rect );
|
||||
if (pt->x < rect.left || pt->y < rect.top || pt->x > rect.right || pt->y > rect.bottom) return FALSE;
|
||||
pt->x = MulDiv( pt->x, system_dpi, dpi );
|
||||
pt->y = MulDiv( pt->y, system_dpi, dpi );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* PhysicalToLogicalPointForPerMonitorDPI (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI PhysicalToLogicalPointForPerMonitorDPI( HWND hwnd, POINT *pt )
|
||||
{
|
||||
DPI_AWARENESS_CONTEXT context;
|
||||
UINT system_dpi = get_system_dpi();
|
||||
UINT dpi = GetDpiForWindow( hwnd );
|
||||
RECT rect;
|
||||
|
||||
/* get window rect in physical coords */
|
||||
context = SetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
|
||||
GetWindowRect( hwnd, &rect );
|
||||
SetThreadDpiAwarenessContext( context );
|
||||
|
||||
if (pt->x < rect.left || pt->y < rect.top || pt->x > rect.right || pt->y > rect.bottom) return FALSE;
|
||||
pt->x = MulDiv( pt->x, dpi, system_dpi );
|
||||
pt->y = MulDiv( pt->y, dpi, system_dpi );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* GetAutoRotationState [USER32.@]
|
||||
*/
|
||||
|
|
|
@ -45,6 +45,7 @@ static BOOL (WINAPI *pSetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
|
|||
static BOOL (WINAPI *pGetProcessDpiAwarenessInternal)(HANDLE,DPI_AWARENESS*);
|
||||
static BOOL (WINAPI *pSetProcessDpiAwarenessInternal)(DPI_AWARENESS);
|
||||
static UINT (WINAPI *pGetDpiForSystem)(void);
|
||||
static UINT (WINAPI *pGetDpiForWindow)(HWND);
|
||||
static DPI_AWARENESS_CONTEXT (WINAPI *pGetThreadDpiAwarenessContext)(void);
|
||||
static DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
|
||||
static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND);
|
||||
|
@ -52,6 +53,8 @@ static DPI_AWARENESS (WINAPI *pGetAwarenessFromDpiAwarenessContext)(DPI_AWARENES
|
|||
static BOOL (WINAPI *pIsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
|
||||
static INT (WINAPI *pGetSystemMetricsForDpi)(INT,UINT);
|
||||
static BOOL (WINAPI *pSystemParametersInfoForDpi)(UINT,UINT,void*,UINT,UINT);
|
||||
static BOOL (WINAPI *pLogicalToPhysicalPointForPerMonitorDPI)(HWND,POINT*);
|
||||
static BOOL (WINAPI *pPhysicalToLogicalPointForPerMonitorDPI)(HWND,POINT*);
|
||||
|
||||
static BOOL strict;
|
||||
static int dpi, real_dpi;
|
||||
|
@ -3177,6 +3180,140 @@ static void test_dpi_stock_objects( HDC hdc )
|
|||
pSetThreadDpiAwarenessContext( context );
|
||||
}
|
||||
|
||||
static void scale_rect_dpi( RECT *rect, UINT src_dpi, UINT target_dpi )
|
||||
{
|
||||
rect->left = MulDiv( rect->left, target_dpi, src_dpi );
|
||||
rect->top = MulDiv( rect->top, target_dpi, src_dpi );
|
||||
rect->right = MulDiv( rect->right, target_dpi, src_dpi );
|
||||
rect->bottom = MulDiv( rect->bottom, target_dpi, src_dpi );
|
||||
}
|
||||
|
||||
static void test_dpi_mapping(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
UINT win_dpi;
|
||||
POINT point;
|
||||
BOOL ret, todo;
|
||||
RECT rect, orig, client, expect;
|
||||
ULONG_PTR i, j;
|
||||
DPI_AWARENESS_CONTEXT context = pGetThreadDpiAwarenessContext();
|
||||
|
||||
if (!pLogicalToPhysicalPointForPerMonitorDPI)
|
||||
{
|
||||
win_skip( "LogicalToPhysicalPointForPerMonitorDPI not supported\n" );
|
||||
return;
|
||||
}
|
||||
for (i = DPI_AWARENESS_UNAWARE; i <= DPI_AWARENESS_PER_MONITOR_AWARE; i++)
|
||||
{
|
||||
pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
|
||||
hwnd = CreateWindowA( "SysParamsTestClass", "test", WS_OVERLAPPEDWINDOW,
|
||||
193, 177, 295, 303, 0, 0, GetModuleHandleA(0), NULL );
|
||||
ok( hwnd != 0, "creating window failed err %u\n", GetLastError());
|
||||
GetWindowRect( hwnd, &orig );
|
||||
GetClientRect( hwnd, &client );
|
||||
for (j = DPI_AWARENESS_UNAWARE; j <= DPI_AWARENESS_PER_MONITOR_AWARE; j++)
|
||||
{
|
||||
pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
|
||||
GetWindowRect( hwnd, &rect );
|
||||
expect = orig;
|
||||
todo = (real_dpi != USER_DEFAULT_SCREEN_DPI);
|
||||
if (i == DPI_AWARENESS_UNAWARE && j != DPI_AWARENESS_UNAWARE)
|
||||
scale_rect_dpi( &expect, USER_DEFAULT_SCREEN_DPI, real_dpi );
|
||||
else if (i != DPI_AWARENESS_UNAWARE && j == DPI_AWARENESS_UNAWARE)
|
||||
scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
|
||||
else
|
||||
todo = FALSE;
|
||||
todo_wine_if (todo)
|
||||
ok( EqualRect( &expect, &rect ), "%lu/%lu: wrong window rect %s expected %s\n",
|
||||
i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
|
||||
GetClientRect( hwnd, &rect );
|
||||
expect = client;
|
||||
MapWindowPoints( hwnd, 0, (POINT *)&expect, 2 );
|
||||
if (i == DPI_AWARENESS_UNAWARE && j != DPI_AWARENESS_UNAWARE)
|
||||
scale_rect_dpi( &expect, USER_DEFAULT_SCREEN_DPI, real_dpi );
|
||||
else if (i != DPI_AWARENESS_UNAWARE && j == DPI_AWARENESS_UNAWARE)
|
||||
scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
|
||||
MapWindowPoints( 0, hwnd, (POINT *)&expect, 2 );
|
||||
OffsetRect( &expect, -expect.left, -expect.top );
|
||||
todo_wine_if (todo)
|
||||
ok( EqualRect( &expect, &rect ), "%lu/%lu: wrong client rect %s expected %s\n",
|
||||
i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
|
||||
win_dpi = pGetDpiForWindow( hwnd );
|
||||
if (i == DPI_AWARENESS_UNAWARE)
|
||||
ok( win_dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", win_dpi );
|
||||
else if (i == DPI_AWARENESS_SYSTEM_AWARE)
|
||||
ok( win_dpi == real_dpi, "wrong dpi %u / %u\n", win_dpi, real_dpi );
|
||||
point.x = 373;
|
||||
point.y = 377;
|
||||
ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
|
||||
ok( point.x == MulDiv( 373, real_dpi, win_dpi ) &&
|
||||
point.y == MulDiv( 377, real_dpi, win_dpi ),
|
||||
"%lu/%lu: wrong pos %d,%d dpi %u\n", i, j, point.x, point.y, win_dpi );
|
||||
point.x = 405;
|
||||
point.y = 423;
|
||||
ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
|
||||
ok( point.x == MulDiv( 405, win_dpi, real_dpi ) &&
|
||||
point.y == MulDiv( 423, win_dpi, real_dpi ),
|
||||
"%lu/%lu: wrong pos %d,%d dpi %u\n", i, j, point.x, point.y, win_dpi );
|
||||
/* point outside the window fails, but note that Windows (wrongly) checks against the
|
||||
* window rect transformed relative to the thread's awareness */
|
||||
GetWindowRect( hwnd, &rect );
|
||||
point.x = rect.left - 1;
|
||||
point.y = rect.top;
|
||||
ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
|
||||
point.x++;
|
||||
point.y--;
|
||||
ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
|
||||
point.y++;
|
||||
ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
|
||||
point.x = rect.right;
|
||||
point.y = rect.bottom + 1;
|
||||
ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
|
||||
point.x++;
|
||||
point.y--;
|
||||
ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
|
||||
point.x--;
|
||||
ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
|
||||
/* get physical window rect */
|
||||
pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
|
||||
GetWindowRect( hwnd, &rect );
|
||||
pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
|
||||
point.x = rect.left - 1;
|
||||
point.y = rect.top;
|
||||
ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
|
||||
point.x++;
|
||||
point.y--;
|
||||
ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
|
||||
point.y++;
|
||||
ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
|
||||
point.x = rect.right;
|
||||
point.y = rect.bottom + 1;
|
||||
ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
|
||||
point.x++;
|
||||
point.y--;
|
||||
ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
|
||||
point.x--;
|
||||
ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
|
||||
ok( ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
|
||||
}
|
||||
DestroyWindow( hwnd );
|
||||
}
|
||||
pSetThreadDpiAwarenessContext( context );
|
||||
}
|
||||
|
||||
static void test_dpi_aware(void)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -3373,6 +3510,7 @@ static void test_dpi_aware(void)
|
|||
test_GetSystemMetrics();
|
||||
test_metrics_for_dpi( 96 );
|
||||
test_metrics_for_dpi( 192 );
|
||||
test_dpi_mapping();
|
||||
}
|
||||
|
||||
static void test_window_dpi(void)
|
||||
|
@ -3448,6 +3586,7 @@ START_TEST(sysparams)
|
|||
pIsProcessDPIAware = (void*)GetProcAddress(hdll, "IsProcessDPIAware");
|
||||
pSetProcessDPIAware = (void*)GetProcAddress(hdll, "SetProcessDPIAware");
|
||||
pGetDpiForSystem = (void*)GetProcAddress(hdll, "GetDpiForSystem");
|
||||
pGetDpiForWindow = (void*)GetProcAddress(hdll, "GetDpiForWindow");
|
||||
pSetProcessDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessContext");
|
||||
pGetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "GetProcessDpiAwarenessInternal");
|
||||
pSetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessInternal");
|
||||
|
@ -3458,6 +3597,8 @@ START_TEST(sysparams)
|
|||
pIsValidDpiAwarenessContext = (void*)GetProcAddress(hdll, "IsValidDpiAwarenessContext");
|
||||
pGetSystemMetricsForDpi = (void*)GetProcAddress(hdll, "GetSystemMetricsForDpi");
|
||||
pSystemParametersInfoForDpi = (void*)GetProcAddress(hdll, "SystemParametersInfoForDpi");
|
||||
pLogicalToPhysicalPointForPerMonitorDPI = (void*)GetProcAddress(hdll, "LogicalToPhysicalPointForPerMonitorDPI");
|
||||
pPhysicalToLogicalPointForPerMonitorDPI = (void*)GetProcAddress(hdll, "PhysicalToLogicalPointForPerMonitorDPI");
|
||||
|
||||
hInstance = GetModuleHandleA( NULL );
|
||||
hdc = GetDC(0);
|
||||
|
|
|
@ -508,6 +508,7 @@
|
|||
@ stdcall LockWindowUpdate(long)
|
||||
@ stdcall LockWorkStation()
|
||||
@ stdcall LogicalToPhysicalPoint(long ptr)
|
||||
@ stdcall LogicalToPhysicalPointForPerMonitorDPI(long ptr)
|
||||
@ stdcall LookupIconIdFromDirectory(ptr long)
|
||||
@ stdcall LookupIconIdFromDirectoryEx(ptr long long long long)
|
||||
@ stub MBToWCSEx
|
||||
|
@ -559,6 +560,7 @@
|
|||
@ stdcall PeekMessageA(ptr long long long long)
|
||||
@ stdcall PeekMessageW(ptr long long long long)
|
||||
@ stdcall PhysicalToLogicalPoint(long ptr)
|
||||
@ stdcall PhysicalToLogicalPointForPerMonitorDPI(long ptr)
|
||||
@ stub PlaySoundEvent
|
||||
@ stdcall PostMessageA(long long long long)
|
||||
@ stdcall PostMessageW(long long long long)
|
||||
|
|
|
@ -3896,6 +3896,7 @@ WINUSERAPI INT WINAPI LoadStringA(HINSTANCE,UINT,LPSTR,INT);
|
|||
WINUSERAPI INT WINAPI LoadStringW(HINSTANCE,UINT,LPWSTR,INT);
|
||||
#define LoadString WINELIB_NAME_AW(LoadString)
|
||||
WINUSERAPI BOOL WINAPI LogicalToPhysicalPoint(HWND,POINT*);
|
||||
WINUSERAPI BOOL WINAPI LogicalToPhysicalPointForPerMonitorDPI(HWND,POINT*);
|
||||
WINUSERAPI BOOL WINAPI LockSetForegroundWindow(UINT);
|
||||
WINUSERAPI BOOL WINAPI LockWindowUpdate(HWND);
|
||||
WINUSERAPI BOOL WINAPI LockWorkStation(void);
|
||||
|
@ -3951,6 +3952,7 @@ WINUSERAPI BOOL WINAPI PeekMessageA(LPMSG,HWND,UINT,UINT,UINT);
|
|||
WINUSERAPI BOOL WINAPI PeekMessageW(LPMSG,HWND,UINT,UINT,UINT);
|
||||
#define PeekMessage WINELIB_NAME_AW(PeekMessage)
|
||||
WINUSERAPI BOOL WINAPI PhysicalToLogicalPoint(HWND,POINT*);
|
||||
WINUSERAPI BOOL WINAPI PhysicalToLogicalPointForPerMonitorDPI(HWND,POINT*);
|
||||
#define PostAppMessageA(thread,msg,wparam,lparam) PostThreadMessageA((DWORD)(thread),msg,wparam,lparam)
|
||||
#define PostAppMessageW(thread,msg,wparam,lparam) PostThreadMessageW((DWORD)(thread),msg,wparam,lparam)
|
||||
#define PostAppMessage WINELIB_NAME_AW(PostAppMessage)
|
||||
|
|
Loading…
Reference in New Issue