user: Take multiple monitors into account when placing a dialog.

This commit is contained in:
Alexandre Julliard 2006-10-23 14:04:12 +02:00
parent 4c0ae56c0e
commit ca58c8179f
2 changed files with 86 additions and 38 deletions

View File

@ -463,6 +463,8 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
{ {
HWND hwnd; HWND hwnd;
RECT rect; RECT rect;
POINT pos;
SIZE size;
DLG_TEMPLATE template; DLG_TEMPLATE template;
DIALOGINFO * dlgInfo = NULL; DIALOGINFO * dlgInfo = NULL;
DWORD units = GetDialogBaseUnits(); DWORD units = GetDialogBaseUnits();
@ -524,40 +526,63 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
if (template.style & DS_CONTROL) if (template.style & DS_CONTROL)
template.exStyle |= WS_EX_CONTROLPARENT; template.exStyle |= WS_EX_CONTROLPARENT;
AdjustWindowRectEx( &rect, template.style, (hMenu != 0), template.exStyle ); AdjustWindowRectEx( &rect, template.style, (hMenu != 0), template.exStyle );
rect.right -= rect.left; pos.x = rect.left;
rect.bottom -= rect.top; pos.y = rect.top;
size.cx = rect.right - rect.left;
size.cy = rect.bottom - rect.top;
if (template.x == CW_USEDEFAULT16) if (template.x == CW_USEDEFAULT16)
{ {
rect.left = rect.top = CW_USEDEFAULT; pos.x = pos.y = CW_USEDEFAULT;
} }
else else
{ {
HMONITOR monitor = 0;
MONITORINFO mon_info;
mon_info.cbSize = sizeof(mon_info);
if (template.style & DS_CENTER) if (template.style & DS_CENTER)
{ {
rect.left = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2; if (!(monitor = MonitorFromWindow( owner ? owner : GetActiveWindow(),
rect.top = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2; 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 else
{ {
rect.left += MulDiv(template.x, xBaseUnit, 4); pos.x += MulDiv(template.x, xBaseUnit, 4);
rect.top += MulDiv(template.y, yBaseUnit, 8); pos.y += MulDiv(template.y, yBaseUnit, 8);
if (!(template.style & (WS_CHILD|DS_ABSALIGN))) ClientToScreen( owner, &pos );
} }
if ( !(template.style & WS_CHILD) ) if ( !(template.style & WS_CHILD) )
{ {
INT dX, dY; INT dX, dY;
if( !(template.style & DS_ABSALIGN) )
ClientToScreen( owner, (POINT *)&rect );
/* try to fit it into the desktop */ /* try to fit it into the desktop */
if( (dX = rect.left + rect.right + GetSystemMetrics(SM_CXDLGFRAME) if (!monitor)
- GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX; {
if( (dY = rect.top + rect.bottom + GetSystemMetrics(SM_CYDLGFRAME) SetRect( &rect, pos.x, pos.y, pos.x + size.cx, pos.y + size.cy );
- GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY; monitor = MonitorFromRect( &rect, MONITOR_DEFAULTTOPRIMARY );
if( rect.left < 0 ) rect.left = 0; GetMonitorInfoW( monitor, &mon_info );
if( rect.top < 0 ) rect.top = 0; }
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) if (unicode)
{ {
hwnd = CreateWindowExW(template.exStyle, template.className, template.caption, hwnd = CreateWindowExW(template.exStyle, template.className, template.caption,
template.style & ~WS_VISIBLE, template.style & ~WS_VISIBLE, pos.x, pos.y, size.cx, size.cy,
rect.left, rect.top, rect.right, rect.bottom,
owner, hMenu, hInst, NULL ); owner, hMenu, hInst, NULL );
} }
else else
@ -592,8 +616,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
WideCharToMultiByte( CP_ACP, 0, template.caption, -1, caption, len, NULL, NULL ); WideCharToMultiByte( CP_ACP, 0, template.caption, -1, caption, len, NULL, NULL );
} }
hwnd = CreateWindowExA(template.exStyle, class, caption, hwnd = CreateWindowExA(template.exStyle, class, caption,
template.style & ~WS_VISIBLE, template.style & ~WS_VISIBLE, pos.x, pos.y, size.cx, size.cy,
rect.left, rect.top, rect.right, rect.bottom,
owner, hMenu, hInst, NULL ); owner, hMenu, hInst, NULL );
if (HIWORD(class)) HeapFree( GetProcessHeap(), 0, class ); if (HIWORD(class)) HeapFree( GetProcessHeap(), 0, class );
if (HIWORD(caption)) HeapFree( GetProcessHeap(), 0, caption ); if (HIWORD(caption)) HeapFree( GetProcessHeap(), 0, caption );

View File

@ -290,6 +290,8 @@ static HWND DIALOG_CreateIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate,
{ {
HWND hwnd; HWND hwnd;
RECT rect; RECT rect;
POINT pos;
SIZE size;
WND * wndPtr; WND * wndPtr;
DLG_TEMPLATE template; DLG_TEMPLATE template;
DIALOGINFO * dlgInfo; DIALOGINFO * dlgInfo;
@ -356,40 +358,63 @@ static HWND DIALOG_CreateIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate,
rect.bottom = MulDiv(template.cy, dlgInfo->yBaseUnit, 8); rect.bottom = MulDiv(template.cy, dlgInfo->yBaseUnit, 8);
if (template.style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME; if (template.style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
AdjustWindowRectEx( &rect, template.style, (dlgInfo->hMenu != 0), exStyle ); AdjustWindowRectEx( &rect, template.style, (dlgInfo->hMenu != 0), exStyle );
rect.right -= rect.left; pos.x = rect.left;
rect.bottom -= rect.top; pos.y = rect.top;
size.cx = rect.right - rect.left;
size.cy = rect.bottom - rect.top;
if (template.x == CW_USEDEFAULT16) if (template.x == CW_USEDEFAULT16)
{ {
rect.left = rect.top = CW_USEDEFAULT16; pos.x = pos.y = CW_USEDEFAULT16;
} }
else else
{ {
HMONITOR monitor = 0;
MONITORINFO mon_info;
mon_info.cbSize = sizeof(mon_info);
if (template.style & DS_CENTER) if (template.style & DS_CENTER)
{ {
rect.left = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2; if (!(monitor = MonitorFromWindow( owner ? owner : GetActiveWindow(),
rect.top = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2; 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 else
{ {
rect.left += MulDiv(template.x, dlgInfo->xBaseUnit, 4); pos.x += MulDiv(template.x, dlgInfo->xBaseUnit, 4);
rect.top += MulDiv(template.y, dlgInfo->yBaseUnit, 8); pos.y += MulDiv(template.y, dlgInfo->yBaseUnit, 8);
if (!(template.style & (WS_CHILD|DS_ABSALIGN))) ClientToScreen( owner, &pos );
} }
if ( !(template.style & WS_CHILD) ) if ( !(template.style & WS_CHILD) )
{ {
INT16 dX, dY; INT dX, dY;
if( !(template.style & DS_ABSALIGN) )
ClientToScreen( owner, (POINT *)&rect );
/* try to fit it into the desktop */ /* try to fit it into the desktop */
if( (dX = rect.left + rect.right + GetSystemMetrics(SM_CXDLGFRAME) if (!monitor)
- GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX; {
if( (dY = rect.top + rect.bottom + GetSystemMetrics(SM_CYDLGFRAME) SetRect( &rect, pos.x, pos.y, pos.x + size.cx, pos.y + size.cy );
- GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY; monitor = MonitorFromRect( &rect, MONITOR_DEFAULTTOPRIMARY );
if( rect.left < 0 ) rect.left = 0; GetMonitorInfoW( monitor, &mon_info );
if( rect.top < 0 ) rect.top = 0; }
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, hwnd = WIN_Handle32( CreateWindowEx16(exStyle, template.className,
template.caption, template.style & ~WS_VISIBLE, 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), HWND_16(owner), HMENU_16(dlgInfo->hMenu),
hInst, NULL )); hInst, NULL ));
if (!hwnd) if (!hwnd)