Use the idFirstChild specified in the MDIClient's CLIENTCREATESTRUCT
Dmitry Timoshkov
dmitry at baikal.ru
Tue Feb 1 23:24:55 CST 2005
Hello,
this patch fixes an app which goes in infinite loop when it tries to find
an MDI child with an id specified in the MDIClient's CLIENTCREATESTRUCT.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Use the idFirstChild specified in the MDIClient's CLIENTCREATESTRUCT
when creating MDI children. Add a test case for the desired behaviour.
diff -up cvs/hq/wine/dlls/user/tests/win.c wine/dlls/user/tests/win.c
--- cvs/hq/wine/dlls/user/tests/win.c 2005-01-02 15:17:20.000000000 +0800
+++ wine/dlls/user/tests/win.c 2005-02-02 12:40:02.000000000 +0800
@@ -928,7 +928,7 @@ static void test_shell_window(void)
static const char mdi_lParam_test_message[] = "just a test string";
-static void test_MDI_create(HWND parent, HWND mdi_client)
+static void test_MDI_create(HWND parent, HWND mdi_client, INT first_id)
{
MDICREATESTRUCTA mdi_cs;
HWND mdi_child;
@@ -947,12 +947,14 @@ static void test_MDI_create(HWND parent,
mdi_cs.lParam = (LPARAM)mdi_lParam_test_message;
mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
mdi_cs.style = 0x7fffffff; /* without WS_POPUP */
mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -965,6 +967,7 @@ static void test_MDI_create(HWND parent,
else
{
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
}
@@ -985,6 +988,7 @@ static void test_MDI_create(HWND parent,
}
else
{
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
}
@@ -996,6 +1000,7 @@ static void test_MDI_create(HWND parent,
mdi_client, GetModuleHandle(0),
(LPARAM)mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -1006,6 +1011,7 @@ static void test_MDI_create(HWND parent,
mdi_client, GetModuleHandle(0),
(LPARAM)mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -1022,6 +1028,7 @@ static void test_MDI_create(HWND parent,
else
{
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
}
@@ -1043,6 +1050,7 @@ static void test_MDI_create(HWND parent,
}
else
{
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
}
@@ -1054,6 +1062,7 @@ static void test_MDI_create(HWND parent,
mdi_client, 0, GetModuleHandle(0),
(LPVOID)mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -1064,6 +1073,7 @@ static void test_MDI_create(HWND parent,
mdi_client, 0, GetModuleHandle(0),
(LPVOID)mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -1080,6 +1090,7 @@ static void test_MDI_create(HWND parent,
else
{
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
}
@@ -1101,6 +1112,7 @@ static void test_MDI_create(HWND parent,
}
else
{
+ ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0);
ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
}
@@ -1124,6 +1136,7 @@ static void test_MDI_create(HWND parent,
mdi_client, 0, GetModuleHandle(0),
(LPVOID)mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
DestroyWindow(mdi_child);
mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child",
@@ -1133,6 +1146,7 @@ static void test_MDI_create(HWND parent,
mdi_client, 0, GetModuleHandle(0),
(LPVOID)mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
DestroyWindow(mdi_child);
/* maximized child */
@@ -1143,6 +1157,7 @@ static void test_MDI_create(HWND parent,
mdi_client, 0, GetModuleHandle(0),
(LPVOID)mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
DestroyWindow(mdi_child);
trace("Creating maximized child with a caption\n");
@@ -1153,6 +1168,7 @@ static void test_MDI_create(HWND parent,
mdi_client, 0, GetModuleHandle(0),
(LPVOID)mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
DestroyWindow(mdi_child);
trace("Creating maximized child with a caption and a thick frame\n");
@@ -1163,6 +1179,7 @@ static void test_MDI_create(HWND parent,
mdi_client, 0, GetModuleHandle(0),
(LPVOID)mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
+ ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID));
DestroyWindow(mdi_child);
}
@@ -1466,7 +1483,7 @@ static LRESULT WINAPI mdi_main_wnd_procA
hwnd, 0, GetModuleHandle(0),
(LPVOID)&client_cs);
assert(mdi_client);
- test_MDI_create(hwnd, mdi_client);
+ test_MDI_create(hwnd, mdi_client, client_cs.idFirstChild);
DestroyWindow(mdi_client);
/* MDIClient with MDIS_ALLCHILDSTYLES */
@@ -1478,7 +1495,7 @@ static LRESULT WINAPI mdi_main_wnd_procA
hwnd, 0, GetModuleHandle(0),
(LPVOID)&client_cs);
assert(mdi_client);
- test_MDI_create(hwnd, mdi_client);
+ test_MDI_create(hwnd, mdi_client, client_cs.idFirstChild);
DestroyWindow(mdi_client);
break;
}
diff -up cvs/hq/wine/include/win.h wine/include/win.h
--- cvs/hq/wine/include/win.h 2005-01-31 08:54:06.000000000 +0800
+++ wine/include/win.h 2005-02-02 12:55:21.000000000 +0800
@@ -95,7 +95,7 @@ extern BOOL WIN_CreateDesktopWindow(void
extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL );
extern HWND *WIN_ListParents( HWND hwnd );
extern HWND *WIN_ListChildren( HWND hwnd );
-extern void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta );
+extern void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id );
/* internal SendInput codes (FIXME) */
#define WINE_INTERNAL_INPUT_MOUSE (16+INPUT_MOUSE)
diff -up cvs/hq/wine/windows/mdi.c wine/windows/mdi.c
--- cvs/hq/wine/windows/mdi.c 2005-01-26 17:56:05.000000000 +0800
+++ wine/windows/mdi.c 2005-02-02 13:02:31.000000000 +0800
@@ -247,17 +247,17 @@ static HWND MDI_GetWindow(MDICLIENTINFO
*
* It seems that the default height is about 2/3 of the client rect
*/
-void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta )
+void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id )
{
INT nstagger;
RECT rect;
- INT spacing = GetSystemMetrics(SM_CYCAPTION) +
- GetSystemMetrics(SM_CYFRAME) - 1;
+ INT spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME) - 1;
- if (total < 0)
+ if (total < 0) /* we are called from CreateWindow */
{
MDICLIENTINFO *ci = get_client_info(hwndClient);
total = ci ? ci->nTotalCreated : 0;
+ *id = ci->idFirstChild + ci->nActiveChildren;
}
GetClientRect( hwndClient, &rect );
@@ -688,7 +688,7 @@ static LONG MDICascade( HWND client, MDI
TRACE("move %p to (%ld,%ld) size [%ld,%ld]\n",
win_array[i], pos[0].x, pos[0].y, pos[1].x, pos[1].y);
- MDI_CalcDefaultChildPos(client, n++, pos, delta);
+ MDI_CalcDefaultChildPos(client, n++, pos, delta, NULL);
SetWindowPos( win_array[i], 0, pos[0].x, pos[0].y, pos[1].x, pos[1].y,
SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
}
diff -up cvs/hq/wine/windows/win.c wine/windows/win.c
--- cvs/hq/wine/windows/win.c 2005-01-31 08:54:08.000000000 +0800
+++ wine/windows/win.c 2005-02-02 12:54:15.000000000 +0800
@@ -760,9 +760,11 @@ static void WIN_FixCoordinates( CREATEST
{
if (cs->dwExStyle & WS_EX_MDICHILD)
{
+ UINT id = 0;
POINT pos[2];
- MDI_CalcDefaultChildPos(cs->hwndParent, -1, pos, 0);
+ MDI_CalcDefaultChildPos(cs->hwndParent, -1, pos, 0, &id);
+ if (!(cs->style & WS_POPUP)) cs->hMenu = (HMENU)id;
if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
{
More information about the wine-patches
mailing list