From ca58c8179fef4f89fbc304ba8cbad86432c8dfca Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 23 Oct 2006 14:04:12 +0200 Subject: [PATCH] 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 8934a5421c1..d43247c8dd1 100644 --- a/dlls/user/dialog.c +++ b/dlls/user/dialog.c @@ -463,6 +463,8 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate, { 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( HINSTANCE hInst, LPCVOID dlgTemplate, 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( HINSTANCE hInst, LPCVOID dlgTemplate, 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( HINSTANCE hInst, LPCVOID dlgTemplate, 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 c7bb73f4bb6..2df59fc0eaa 100644 --- a/dlls/user/dialog16.c +++ b/dlls/user/dialog16.c @@ -290,6 +290,8 @@ static HWND DIALOG_CreateIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate, { HWND hwnd; RECT rect; + POINT pos; + SIZE size; WND * wndPtr; DLG_TEMPLATE template; DIALOGINFO * dlgInfo; @@ -356,40 +358,63 @@ static HWND DIALOG_CreateIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate, 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( HINSTANCE16 hInst, LPCVOID dlgTemplate, 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)