Alexandre Julliard : user:
Take multiple monitors into account when placing a dialog.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Oct 23 10:00:59 CDT 2006
Module: wine
Branch: master
Commit: ca58c8179fef4f89fbc304ba8cbad86432c8dfca
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ca58c8179fef4f89fbc304ba8cbad86432c8dfca
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Oct 23 14:04:12 2006 +0200
user: Take multiple monitors into account when placing a dialog.
---
dlls/user/dialog.c | 63 ++++++++++++++++++++++++++++++++++----------------
dlls/user/dialog16.c | 61 ++++++++++++++++++++++++++++++++++--------------
2 files changed, 86 insertions(+), 38 deletions(-)
diff --git a/dlls/user/dialog.c b/dlls/user/dialog.c
index 8934a54..d43247c 100644
--- a/dlls/user/dialog.c
+++ b/dlls/user/dialog.c
@@ -463,6 +463,8 @@ static HWND DIALOG_CreateIndirect( HINST
{
HWND hwnd;
RECT rect;
+ POINT pos;
+ SIZE size;
DLG_TEMPLATE template;
DIALOGINFO * dlgInfo = NULL;
DWORD units = GetDialogBaseUnits();
@@ -524,40 +526,63 @@ static HWND DIALOG_CreateIndirect( HINST
if (template.style & DS_CONTROL)
template.exStyle |= WS_EX_CONTROLPARENT;
AdjustWindowRectEx( &rect, template.style, (hMenu != 0), template.exStyle );
- rect.right -= rect.left;
- rect.bottom -= rect.top;
+ pos.x = rect.left;
+ pos.y = rect.top;
+ size.cx = rect.right - rect.left;
+ size.cy = rect.bottom - rect.top;
if (template.x == CW_USEDEFAULT16)
{
- rect.left = rect.top = CW_USEDEFAULT;
+ pos.x = pos.y = CW_USEDEFAULT;
}
else
{
+ HMONITOR monitor = 0;
+ MONITORINFO mon_info;
+
+ mon_info.cbSize = sizeof(mon_info);
if (template.style & DS_CENTER)
{
- rect.left = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2;
- rect.top = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2;
+ if (!(monitor = MonitorFromWindow( owner ? owner : GetActiveWindow(),
+ MONITOR_DEFAULTTOPRIMARY )))
+ {
+ pos.x = pos.y = 0; /* default to primary monitor */
+ monitor = MonitorFromPoint( pos, MONITOR_DEFAULTTOPRIMARY );
+ }
+ GetMonitorInfoW( monitor, &mon_info );
+ pos.x = (mon_info.rcWork.left + mon_info.rcWork.right - size.cx) / 2;
+ pos.y = (mon_info.rcWork.top + mon_info.rcWork.bottom - size.cy) / 2;
+ }
+ else if (template.style & DS_CENTERMOUSE)
+ {
+ GetCursorPos( &pos );
+ monitor = MonitorFromPoint( pos, MONITOR_DEFAULTTOPRIMARY );
+ GetMonitorInfoW( monitor, &mon_info );
}
else
{
- rect.left += MulDiv(template.x, xBaseUnit, 4);
- rect.top += MulDiv(template.y, yBaseUnit, 8);
+ pos.x += MulDiv(template.x, xBaseUnit, 4);
+ pos.y += MulDiv(template.y, yBaseUnit, 8);
+ if (!(template.style & (WS_CHILD|DS_ABSALIGN))) ClientToScreen( owner, &pos );
}
if ( !(template.style & WS_CHILD) )
{
INT dX, dY;
- if( !(template.style & DS_ABSALIGN) )
- ClientToScreen( owner, (POINT *)&rect );
-
/* try to fit it into the desktop */
- if( (dX = rect.left + rect.right + GetSystemMetrics(SM_CXDLGFRAME)
- - GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX;
- if( (dY = rect.top + rect.bottom + GetSystemMetrics(SM_CYDLGFRAME)
- - GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY;
- if( rect.left < 0 ) rect.left = 0;
- if( rect.top < 0 ) rect.top = 0;
+ if (!monitor)
+ {
+ SetRect( &rect, pos.x, pos.y, pos.x + size.cx, pos.y + size.cy );
+ monitor = MonitorFromRect( &rect, MONITOR_DEFAULTTOPRIMARY );
+ GetMonitorInfoW( monitor, &mon_info );
+ }
+ if ((dX = pos.x + size.cx + GetSystemMetrics(SM_CXDLGFRAME) - mon_info.rcWork.right) > 0)
+ pos.x -= dX;
+ if ((dY = pos.y + size.cy + GetSystemMetrics(SM_CYDLGFRAME) - mon_info.rcWork.bottom) > 0)
+ pos.y -= dY;
+ if( pos.x < mon_info.rcWork.left ) pos.x = mon_info.rcWork.left;
+ if( pos.y < mon_info.rcWork.top ) pos.y = mon_info.rcWork.top;
}
}
@@ -570,8 +595,7 @@ static HWND DIALOG_CreateIndirect( HINST
if (unicode)
{
hwnd = CreateWindowExW(template.exStyle, template.className, template.caption,
- template.style & ~WS_VISIBLE,
- rect.left, rect.top, rect.right, rect.bottom,
+ template.style & ~WS_VISIBLE, pos.x, pos.y, size.cx, size.cy,
owner, hMenu, hInst, NULL );
}
else
@@ -592,8 +616,7 @@ static HWND DIALOG_CreateIndirect( HINST
WideCharToMultiByte( CP_ACP, 0, template.caption, -1, caption, len, NULL, NULL );
}
hwnd = CreateWindowExA(template.exStyle, class, caption,
- template.style & ~WS_VISIBLE,
- rect.left, rect.top, rect.right, rect.bottom,
+ template.style & ~WS_VISIBLE, pos.x, pos.y, size.cx, size.cy,
owner, hMenu, hInst, NULL );
if (HIWORD(class)) HeapFree( GetProcessHeap(), 0, class );
if (HIWORD(caption)) HeapFree( GetProcessHeap(), 0, caption );
diff --git a/dlls/user/dialog16.c b/dlls/user/dialog16.c
index c7bb73f..2df59fc 100644
--- a/dlls/user/dialog16.c
+++ b/dlls/user/dialog16.c
@@ -290,6 +290,8 @@ static HWND DIALOG_CreateIndirect16( HIN
{
HWND hwnd;
RECT rect;
+ POINT pos;
+ SIZE size;
WND * wndPtr;
DLG_TEMPLATE template;
DIALOGINFO * dlgInfo;
@@ -356,40 +358,63 @@ static HWND DIALOG_CreateIndirect16( HIN
rect.bottom = MulDiv(template.cy, dlgInfo->yBaseUnit, 8);
if (template.style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
AdjustWindowRectEx( &rect, template.style, (dlgInfo->hMenu != 0), exStyle );
- rect.right -= rect.left;
- rect.bottom -= rect.top;
+ pos.x = rect.left;
+ pos.y = rect.top;
+ size.cx = rect.right - rect.left;
+ size.cy = rect.bottom - rect.top;
if (template.x == CW_USEDEFAULT16)
{
- rect.left = rect.top = CW_USEDEFAULT16;
+ pos.x = pos.y = CW_USEDEFAULT16;
}
else
{
+ HMONITOR monitor = 0;
+ MONITORINFO mon_info;
+
+ mon_info.cbSize = sizeof(mon_info);
if (template.style & DS_CENTER)
{
- rect.left = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2;
- rect.top = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2;
+ if (!(monitor = MonitorFromWindow( owner ? owner : GetActiveWindow(),
+ MONITOR_DEFAULTTOPRIMARY )))
+ {
+ pos.x = pos.y = 0; /* default to primary monitor */
+ monitor = MonitorFromPoint( pos, MONITOR_DEFAULTTOPRIMARY );
+ }
+ GetMonitorInfoW( monitor, &mon_info );
+ pos.x = (mon_info.rcWork.left + mon_info.rcWork.right - size.cx) / 2;
+ pos.y = (mon_info.rcWork.top + mon_info.rcWork.bottom - size.cy) / 2;
+ }
+ else if (template.style & DS_CENTERMOUSE)
+ {
+ GetCursorPos( &pos );
+ monitor = MonitorFromPoint( pos, MONITOR_DEFAULTTOPRIMARY );
+ GetMonitorInfoW( monitor, &mon_info );
}
else
{
- rect.left += MulDiv(template.x, dlgInfo->xBaseUnit, 4);
- rect.top += MulDiv(template.y, dlgInfo->yBaseUnit, 8);
+ pos.x += MulDiv(template.x, dlgInfo->xBaseUnit, 4);
+ pos.y += MulDiv(template.y, dlgInfo->yBaseUnit, 8);
+ if (!(template.style & (WS_CHILD|DS_ABSALIGN))) ClientToScreen( owner, &pos );
}
if ( !(template.style & WS_CHILD) )
{
- INT16 dX, dY;
-
- if( !(template.style & DS_ABSALIGN) )
- ClientToScreen( owner, (POINT *)&rect );
+ INT dX, dY;
/* try to fit it into the desktop */
- if( (dX = rect.left + rect.right + GetSystemMetrics(SM_CXDLGFRAME)
- - GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX;
- if( (dY = rect.top + rect.bottom + GetSystemMetrics(SM_CYDLGFRAME)
- - GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY;
- if( rect.left < 0 ) rect.left = 0;
- if( rect.top < 0 ) rect.top = 0;
+ if (!monitor)
+ {
+ SetRect( &rect, pos.x, pos.y, pos.x + size.cx, pos.y + size.cy );
+ monitor = MonitorFromRect( &rect, MONITOR_DEFAULTTOPRIMARY );
+ GetMonitorInfoW( monitor, &mon_info );
+ }
+ if ((dX = pos.x + size.cx + GetSystemMetrics(SM_CXDLGFRAME) - mon_info.rcWork.right) > 0)
+ pos.x -= dX;
+ if ((dY = pos.y + size.cy + GetSystemMetrics(SM_CYDLGFRAME) - mon_info.rcWork.bottom) > 0)
+ pos.y -= dY;
+ if( pos.x < mon_info.rcWork.left ) pos.x = mon_info.rcWork.left;
+ if( pos.y < mon_info.rcWork.top ) pos.y = mon_info.rcWork.top;
}
}
@@ -401,7 +426,7 @@ static HWND DIALOG_CreateIndirect16( HIN
hwnd = WIN_Handle32( CreateWindowEx16(exStyle, template.className,
template.caption, template.style & ~WS_VISIBLE,
- rect.left, rect.top, rect.right, rect.bottom,
+ pos.x, pos.y, size.cx, size.cy,
HWND_16(owner), HMENU_16(dlgInfo->hMenu),
hInst, NULL ));
if (!hwnd)
More information about the wine-cvs
mailing list