1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for SetParent
5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 static HWND hWndList[5 + 1];
11 static const int hWndCount = sizeof(hWndList) / sizeof(hWndList[0]) - 1;
12 static DWORD dwThreadId;
13
14 #define ok_hwnd(val, exp) do \
15 { \
16 HWND _val = (val), _exp = (exp); \
17 int _ival = get_iwnd(_val, FALSE); \
18 int _iexp = get_iwnd(_exp, FALSE); \
19 ok(_val == _exp, #val " = %p (%d), expected %p (%d)\n", _val, _ival, _exp, _iexp); \
20 } while (0)
21
22 static
23 int
get_iwnd(_In_ HWND hWnd,_In_ BOOL set)24 get_iwnd(
25 _In_ HWND hWnd,
26 _In_ BOOL set)
27 {
28 int i;
29 if (!hWnd)
30 return 0;
31 for (i = 1; i <= hWndCount; i++)
32 {
33 if (hWndList[i] == hWnd)
34 return i;
35 }
36 if (!set)
37 return 0;
38 for (i = 1; i <= hWndCount; i++)
39 {
40 if (hWndList[i] == NULL)
41 {
42 hWndList[i] = hWnd;
43 return i;
44 }
45 }
46 ok(0, "Too many windows!\n");
47 return 0;
48 }
49
50 static
51 BOOL
52 CALLBACK
EnumProc(_In_ HWND hWnd,_In_ LPARAM lParam)53 EnumProc(
54 _In_ HWND hWnd,
55 _In_ LPARAM lParam)
56 {
57 HWND hLookingFor = (HWND)lParam;
58 return hWnd != hLookingFor;
59 }
60
61 static
62 LRESULT
63 CALLBACK
WndProc(_In_ HWND hWnd,_In_ UINT message,_In_ WPARAM wParam,_In_ LPARAM lParam)64 WndProc(
65 _In_ HWND hWnd,
66 _In_ UINT message,
67 _In_ WPARAM wParam,
68 _In_ LPARAM lParam)
69 {
70 HWND hTest;
71 int iwnd = get_iwnd(hWnd, TRUE);
72
73 ok(GetCurrentThreadId() == dwThreadId, "Thread 0x%lx instead of 0x%lx\n", GetCurrentThreadId(), dwThreadId);
74 if (message > WM_USER || IsDWmMsg(message) || IseKeyMsg(message))
75 return DefWindowProcW(hWnd, message, wParam, lParam);
76
77 RECORD_MESSAGE(iwnd, message, SENT, wParam, lParam);
78
79 switch(message)
80 {
81 case WM_DESTROY:
82 if (GetParent(hWnd))
83 {
84 /* child window */
85 ok(EnumThreadWindows(dwThreadId, EnumProc, (LPARAM)hWnd), "Child window %p (%d) enumerated\n", hWnd, iwnd);
86 ok(!EnumChildWindows(GetParent(hWnd), EnumProc, (LPARAM)hWnd), "Child window %p (%d) not enumerated\n", hWnd, iwnd);
87 ok(!EnumThreadWindows(dwThreadId, EnumProc, (LPARAM)GetParent(hWnd)), "Parent window of %p (%d) not enumerated\n", hWnd, iwnd);
88 }
89 else
90 {
91 /* top-level window */
92 ok(!EnumThreadWindows(dwThreadId, EnumProc, (LPARAM)hWnd), "Window %p (%d) not enumerated in WM_DESTROY\n", hWnd, iwnd);
93 }
94 if (hWnd == hWndList[3])
95 {
96 hTest = SetParent(hWndList[4], hWndList[2]);
97 ok_hwnd(hTest, hWndList[1]);
98 hTest = SetParent(hWndList[5], hWndList[1]);
99 ok_hwnd(hTest, hWndList[2]);
100
101 ok_hwnd(GetParent(hWndList[1]), NULL);
102 ok_hwnd(GetParent(hWndList[2]), NULL);
103 ok_hwnd(GetParent(hWndList[3]), hWndList[1]);
104 ok_hwnd(GetParent(hWndList[4]), hWndList[2]);
105 ok_hwnd(GetParent(hWndList[5]), hWndList[1]);
106 }
107 break;
108 }
109
110 return DefWindowProcW(hWnd, message, wParam, lParam);
111 }
112
113
START_TEST(SetParent)114 START_TEST(SetParent)
115 {
116 HWND hWnd;
117 MSG msg;
118
119 SetCursorPos(0,0);
120
121 dwThreadId = GetCurrentThreadId();
122 hWndList[0] = INVALID_HANDLE_VALUE;
123 RegisterSimpleClass(WndProc, L"CreateTest");
124
125 hWnd = CreateWindowExW(0, L"CreateTest", NULL, 0, 10, 10, 20, 20, NULL, NULL, 0, NULL);
126 ok(hWnd != NULL, "CreateWindow failed\n");
127 ok(hWnd == hWndList[1], "Got %p, expected %p\n", hWnd, hWndList[1]);
128
129 hWnd = CreateWindowExW(0, L"CreateTest", NULL, 0, 40, 10, 20, 20, NULL, NULL, 0, NULL);
130 ok(hWnd != NULL, "CreateWindow failed\n");
131 ok(hWnd == hWndList[2], "Got %p, expected %p\n", hWnd, hWndList[2]);
132
133 hWnd = CreateWindowExW(0, L"CreateTest", NULL, WS_CHILD, 60, 10, 20, 20, hWndList[1], NULL, 0, NULL);
134 ok(hWnd != NULL, "CreateWindow failed\n");
135 ok(hWnd == hWndList[3], "Got %p, expected %p\n", hWnd, hWndList[3]);
136
137 hWnd = CreateWindowExW(0, L"CreateTest", NULL, WS_CHILD, 80, 10, 20, 20, hWndList[1], NULL, 0, NULL);
138 ok(hWnd != NULL, "CreateWindow failed\n");
139 ok(hWnd == hWndList[4], "Got %p, expected %p\n", hWnd, hWndList[4]);
140
141 hWnd = CreateWindowExW(0, L"CreateTest", NULL, WS_CHILD, 60, 10, 20, 20, hWndList[2], NULL, 0, NULL);
142 ok(hWnd != NULL, "CreateWindow failed\n");
143 ok(hWnd == hWndList[5], "Got %p, expected %p\n", hWnd, hWndList[5]);
144
145 trace("\n");
146 while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
147 {
148 int iwnd = get_iwnd(msg.hwnd, FALSE);
149 if(!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
150 RECORD_MESSAGE(iwnd, msg.message, POST, 0, 0);
151 DispatchMessageA( &msg );
152 }
153 trace("\n");
154 TRACE_CACHE();
155 trace("\n");
156
157 ok_hwnd(GetParent(hWndList[1]), NULL);
158 ok_hwnd(GetParent(hWndList[2]), NULL);
159 ok_hwnd(GetParent(hWndList[3]), hWndList[1]);
160 ok_hwnd(GetParent(hWndList[4]), hWndList[1]);
161 ok_hwnd(GetParent(hWndList[5]), hWndList[2]);
162
163 DestroyWindow(hWndList[1]);
164 ok(!IsWindow(hWndList[1]), "\n");
165 ok( IsWindow(hWndList[2]), "\n");
166 ok(!IsWindow(hWndList[3]), "\n");
167 ok( IsWindow(hWndList[4]), "\n");
168 ok(!IsWindow(hWndList[5]), "\n");
169
170 ok_hwnd(GetParent(hWndList[1]), NULL);
171 ok_hwnd(GetParent(hWndList[2]), NULL);
172 ok_hwnd(GetParent(hWndList[3]), NULL);
173 ok_hwnd(GetParent(hWndList[4]), hWndList[2]);
174 ok_hwnd(GetParent(hWndList[5]), NULL);
175
176 trace("\n");
177 while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
178 {
179 int iwnd = get_iwnd(msg.hwnd, FALSE);
180 if(!(msg.message > WM_USER || IsDWmMsg(msg.message) || IseKeyMsg(msg.message)))
181 RECORD_MESSAGE(iwnd, msg.message, POST, 0, 0);
182 DispatchMessageA( &msg );
183 }
184 trace("\n");
185 TRACE_CACHE();
186 }
187