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