Alexandre Julliard : user:
Take multiple monitors into account when placing a window.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Oct 23 10:00:52 CDT 2006
Module: wine
Branch: master
Commit: 4c0ae56c0ec9b60e5ba850d2df20ca0cafc6970b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4c0ae56c0ec9b60e5ba850d2df20ca0cafc6970b
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Oct 23 14:03:41 2006 +0200
user: Take multiple monitors into account when placing a window.
---
dlls/user/win.c | 119 +++++++++++++++++++++++--------------------------------
1 files changed, 50 insertions(+), 69 deletions(-)
diff --git a/dlls/user/win.c b/dlls/user/win.c
index a6f1b37..d52cac0 100644
--- a/dlls/user/win.c
+++ b/dlls/user/win.c
@@ -667,10 +667,10 @@ void WIN_DestroyThreadWindows( HWND hwnd
*
* Fix the coordinates - Helper for WIN_CreateWindowEx.
* returns default show mode in sw.
- * Note: the feature presented as undocumented *is* in the MSDN since 1993.
*/
static void WIN_FixCoordinates( CREATESTRUCTA *cs, INT *sw)
{
+#define IS_DEFAULT(x) ((x) == CW_USEDEFAULT || (x) == CW_USEDEFAULT16)
POINT pos[2];
if (cs->dwExStyle & WS_EX_MDICHILD)
@@ -683,97 +683,78 @@ static void WIN_FixCoordinates( CREATEST
TRACE("MDI child id %04x\n", id);
}
- if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16 ||
- cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
+ if (cs->style & (WS_CHILD | WS_POPUP))
{
- if (cs->style & (WS_CHILD | WS_POPUP))
+ if (cs->dwExStyle & WS_EX_MDICHILD)
{
- if (cs->dwExStyle & WS_EX_MDICHILD)
+ if (IS_DEFAULT(cs->x))
{
- if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
- {
- cs->x = pos[0].x;
- cs->y = pos[0].y;
- }
- if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16 || !cs->cx)
- cs->cx = pos[1].x;
- if (cs->cy == CW_USEDEFAULT || cs->cy == CW_USEDEFAULT16 || !cs->cy)
- cs->cy = pos[1].y;
- }
- else
- {
- if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
- cs->x = cs->y = 0;
- if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
- cs->cx = cs->cy = 0;
+ cs->x = pos[0].x;
+ cs->y = pos[0].y;
}
+ if (IS_DEFAULT(cs->cx) || !cs->cx) cs->cx = pos[1].x;
+ if (IS_DEFAULT(cs->cy) || !cs->cy) cs->cy = pos[1].y;
}
- else /* overlapped window */
+ else
{
- STARTUPINFOW info;
+ if (IS_DEFAULT(cs->x)) cs->x = cs->y = 0;
+ if (IS_DEFAULT(cs->cx)) cs->cx = cs->cy = 0;
+ }
+ }
+ else /* overlapped window */
+ {
+ HMONITOR monitor;
+ MONITORINFO mon_info;
+ STARTUPINFOW info;
+ POINT pt;
- GetStartupInfoW( &info );
+ if (!IS_DEFAULT(cs->x) && !IS_DEFAULT(cs->cx) && !IS_DEFAULT(cs->cy)) return;
- if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
+ if (!(monitor = MonitorFromWindow( cs->hwndParent, MONITOR_DEFAULTTOPRIMARY )))
+ {
+ pt.x = pt.y = 0; /* default to primary monitor */
+ if (!IS_DEFAULT(cs->x))
{
- /* Never believe Microsoft's documentation... CreateWindowEx doc says
- * that if an overlapped window is created with WS_VISIBLE style bit
- * set and the x parameter is set to CW_USEDEFAULT, the system ignores
- * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
- * reveals that
- *
- * 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
- * 2) it does not ignore the y parameter as the docs claim; instead, it
- * uses it as second parameter to ShowWindow() unless y is either
- * CW_USEDEFAULT or CW_USEDEFAULT16.
- *
- * The fact that we didn't do 2) caused bogus windows pop up when wine
- * was running apps that were using this obscure feature. Example -
- * calc.exe that comes with Win98 (only Win98, it's different from
- * the one that comes with Win95 and NT)
- */
- if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) *sw = cs->y;
- cs->x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
- cs->y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
+ pt.x = cs->x;
+ pt.y = cs->y;
}
+ monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTOPRIMARY );
+ }
+ mon_info.cbSize = sizeof(mon_info);
+ GetMonitorInfoW( monitor, &mon_info );
+ GetStartupInfoW( &info );
- if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
+ if (IS_DEFAULT(cs->x))
+ {
+ if (!IS_DEFAULT(cs->y)) *sw = cs->y;
+ cs->x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : mon_info.rcWork.left;
+ cs->y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : mon_info.rcWork.top;
+ }
+
+ if (IS_DEFAULT(cs->cx))
+ {
+ if (info.dwFlags & STARTF_USESIZE)
{
- if (info.dwFlags & STARTF_USESIZE)
- {
- cs->cx = info.dwXSize;
- cs->cy = info.dwYSize;
- }
- else /* if no other hint from the app, pick 3/4 of the screen real estate */
- {
- RECT r;
- SystemParametersInfoW( SPI_GETWORKAREA, 0, &r, 0);
- cs->cx = (((r.right - r.left) * 3) / 4) - cs->x;
- cs->cy = (((r.bottom - r.top) * 3) / 4) - cs->y;
- }
+ cs->cx = info.dwXSize;
+ cs->cy = info.dwYSize;
}
- /* Handle case where only the cy values is set to default */
- else if (cs->cy == CW_USEDEFAULT || cs->cy == CW_USEDEFAULT16)
+ else
{
- RECT r;
- SystemParametersInfoW( SPI_GETWORKAREA, 0, &r, 0);
- cs->cy = (((r.bottom - r.top) * 3) / 4) - cs->y;
+ cs->cx = (mon_info.rcWork.right - mon_info.rcWork.left) * 3 / 4 - cs->x;
+ cs->cy = (mon_info.rcWork.bottom - mon_info.rcWork.top) * 3 / 4 - cs->y;
}
}
- }
- else
- {
/* neither x nor cx are default. Check the y values .
* In the trace we see Outlook and Outlook Express using
* cy set to CW_USEDEFAULT when opening the address book.
*/
- if (cs->cy == CW_USEDEFAULT || cs->cy == CW_USEDEFAULT16) {
- RECT r;
+ else if (IS_DEFAULT(cs->cy))
+ {
FIXME("Strange use of CW_USEDEFAULT in nHeight\n");
- SystemParametersInfoW( SPI_GETWORKAREA, 0, &r, 0);
- cs->cy = (((r.bottom - r.top) * 3) / 4) - cs->y;
+ cs->cy = (mon_info.rcWork.bottom - mon_info.rcWork.top) * 3 / 4 - cs->y;
}
}
+#undef IS_DEFAULT
}
/***********************************************************************
More information about the wine-cvs
mailing list