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