1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Test for SubclassWindow/UnsubclassWindow 5 * PROGRAMMER: Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 6 */ 7 8 #ifdef HAVE_APITEST 9 #include <apitest.h> 10 #define ATLASSUME(x) /*empty*/ 11 #define ATLASSERT(x) /*empty*/ 12 #else 13 #include "atltest.h" 14 #define ATLASSUME(x) do { \ 15 trace("ATLASSUME(%s) %s.\n", #x, ((x) ? "success" : "failure")); \ 16 } while (0) 17 #define ATLASSERT(x) do { \ 18 trace("ATLASSERT(%s) %s.\n", #x, ((x) ? "success" : "failure")); \ 19 } while (0) 20 #endif 21 22 #include <atlbase.h> 23 #include <atlwin.h> 24 25 #ifdef _WIN64 26 #define INVALID_HWND ((HWND)(ULONG_PTR)0xDEADBEEFDEADBEEFULL) 27 #else 28 #define INVALID_HWND ((HWND)(ULONG_PTR)0xDEADBEEF) 29 #endif 30 31 static BOOL s_flag = TRUE; 32 33 class CMyCtrl1 : public CWindowImpl<CMyCtrl1, CWindow> 34 { 35 public: 36 static LPCWSTR GetWndClassName() 37 { 38 if (s_flag) 39 return L"EDIT"; 40 else 41 return L"STATIC"; 42 } 43 44 CMyCtrl1() 45 { 46 } 47 virtual ~CMyCtrl1() 48 { 49 } 50 51 BEGIN_MSG_MAP(CMyCtrl1) 52 END_MSG_MAP() 53 }; 54 55 class CMyCtrl2 56 : public CContainedWindowT<CWindowImpl<CMyCtrl2, CWindow> > 57 { 58 public: 59 static LPCWSTR GetWndClassName() 60 { 61 if (s_flag) 62 return L"EDIT"; 63 else 64 return L"STATIC"; 65 } 66 67 CMyCtrl2() : CContainedWindowT<CWindowImpl<CMyCtrl2, CWindow> >(this) 68 { 69 } 70 virtual ~CMyCtrl2() 71 { 72 } 73 74 BEGIN_MSG_MAP(CMyCtrl2) 75 END_MSG_MAP() 76 }; 77 78 static HWND MyCreateWindow(DWORD style) 79 { 80 return CreateWindowW(L"EDIT", NULL, style, 81 CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, 82 NULL, NULL, GetModuleHandleW(NULL), NULL); 83 } 84 85 static LRESULT CALLBACK 86 MyWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 87 { 88 return 0; 89 } 90 91 START_TEST(SubclassWindow) 92 { 93 const DWORD style = WS_POPUPWINDOW | ES_MULTILINE; 94 HWND hwnd1, hwnd2; 95 WNDPROC fn1, fn2; 96 BOOL b; 97 trace("DefWindowProcA == %p\n", DefWindowProcA); 98 trace("DefWindowProcW == %p\n", DefWindowProcW); 99 trace("MyWindowProc == %p\n", MyWindowProc); 100 101 // 102 // Ctrl1 103 // 104 { 105 CMyCtrl1 Ctrl1; 106 s_flag = TRUE; // "EDIT" 107 hwnd1 = MyCreateWindow(style); 108 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 109 fn1 = Ctrl1.m_pfnSuperWindowProc; 110 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 111 b = Ctrl1.SubclassWindow(hwnd1); 112 ok_int(b, TRUE); 113 ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); 114 fn1 = Ctrl1.m_pfnSuperWindowProc; 115 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 116 hwnd2 = Ctrl1.UnsubclassWindow(); 117 ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); 118 fn2 = Ctrl1.m_pfnSuperWindowProc; 119 ok(fn1 != fn2, "fn1 == fn2\n"); 120 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 121 DestroyWindow(hwnd2); 122 ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); 123 } 124 125 { 126 CMyCtrl1 Ctrl1; 127 s_flag = TRUE; // "EDIT" 128 hwnd1 = MyCreateWindow(style); 129 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 130 fn1 = Ctrl1.m_pfnSuperWindowProc; 131 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 132 b = Ctrl1.SubclassWindow(hwnd1); 133 ok_int(b, TRUE); 134 ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); 135 fn1 = Ctrl1.m_pfnSuperWindowProc; 136 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 137 DestroyWindow(hwnd1); // destroy now 138 hwnd2 = Ctrl1.UnsubclassWindow(); 139 ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); 140 fn2 = Ctrl1.m_pfnSuperWindowProc; 141 ok(fn2 == fn1, "fn2 was %p\n", fn2); 142 DestroyWindow(hwnd2); 143 ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); 144 } 145 146 { 147 CMyCtrl1 Ctrl1; 148 s_flag = FALSE; // "STATIC" 149 hwnd1 = MyCreateWindow(style); 150 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 151 fn1 = Ctrl1.m_pfnSuperWindowProc; 152 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 153 b = Ctrl1.SubclassWindow(hwnd1); 154 ok_int(b, TRUE); 155 ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); 156 fn1 = Ctrl1.m_pfnSuperWindowProc; 157 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 158 hwnd2 = Ctrl1.UnsubclassWindow(); 159 ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); 160 fn2 = Ctrl1.m_pfnSuperWindowProc; 161 ok(fn1 != fn2, "fn1 == fn2\n"); 162 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 163 DestroyWindow(hwnd2); 164 ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); 165 } 166 167 { 168 CMyCtrl1 Ctrl1; 169 s_flag = FALSE; // "STATIC" 170 hwnd1 = MyCreateWindow(style); 171 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 172 fn1 = Ctrl1.m_pfnSuperWindowProc; 173 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 174 b = Ctrl1.SubclassWindow(hwnd1); 175 ok_int(b, TRUE); 176 ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); 177 fn1 = Ctrl1.m_pfnSuperWindowProc; 178 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 179 DestroyWindow(hwnd1); // destroy now 180 hwnd2 = Ctrl1.UnsubclassWindow(); 181 ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); 182 fn2 = Ctrl1.m_pfnSuperWindowProc; 183 ok(fn1 == fn2, "fn1 != fn2\n"); 184 DestroyWindow(hwnd2); 185 ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); 186 } 187 188 { 189 CMyCtrl1 Ctrl1; 190 s_flag = TRUE; // "EDIT" 191 hwnd1 = MyCreateWindow(style); 192 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 193 fn1 = Ctrl1.m_pfnSuperWindowProc; 194 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 195 b = Ctrl1.SubclassWindow(hwnd1); 196 ok_int(b, TRUE); 197 ok(Ctrl1.m_hWnd == hwnd1, "Ctrl1.m_hWnd was %p\n", Ctrl1.m_hWnd); 198 Ctrl1.m_pfnSuperWindowProc = MyWindowProc; 199 hwnd2 = Ctrl1.UnsubclassWindow(); 200 ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); 201 fn2 = Ctrl1.m_pfnSuperWindowProc; 202 ok(fn1 == fn2, "fn2 was %p\n", fn2); 203 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 204 DestroyWindow(hwnd2); 205 ok(Ctrl1.m_hWnd == NULL, "hwnd != NULL\n"); 206 } 207 208 // 209 // Ctrl2 (Not Forced) 210 // 211 { 212 CMyCtrl2 Ctrl2; 213 s_flag = TRUE; // "EDIT" 214 hwnd1 = MyCreateWindow(style); 215 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 216 fn1 = Ctrl2.m_pfnSuperWindowProc; 217 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 218 b = Ctrl2.SubclassWindow(hwnd1); 219 ok_int(b, TRUE); 220 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 221 fn1 = Ctrl2.m_pfnSuperWindowProc; 222 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 223 hwnd2 = Ctrl2.UnsubclassWindow(FALSE); 224 ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); 225 fn2 = Ctrl2.m_pfnSuperWindowProc; 226 ok(fn1 != fn2, "fn1 == fn2\n"); 227 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 228 DestroyWindow(hwnd2); 229 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 230 } 231 232 { 233 CMyCtrl2 Ctrl2; 234 s_flag = TRUE; // "EDIT" 235 hwnd1 = MyCreateWindow(style); 236 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 237 fn1 = Ctrl2.m_pfnSuperWindowProc; 238 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 239 b = Ctrl2.SubclassWindow(hwnd1); 240 ok_int(b, TRUE); 241 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 242 fn1 = Ctrl2.m_pfnSuperWindowProc; 243 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 244 DestroyWindow(hwnd1); // destroy now 245 hwnd2 = Ctrl2.UnsubclassWindow(FALSE); 246 ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); 247 fn2 = Ctrl2.m_pfnSuperWindowProc; 248 ok(fn1 == fn2, "fn1 == fn2\n"); 249 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 250 DestroyWindow(hwnd2); 251 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 252 } 253 254 { 255 CMyCtrl2 Ctrl2; 256 s_flag = FALSE; // "STATIC" 257 hwnd1 = MyCreateWindow(style); 258 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 259 fn1 = Ctrl2.m_pfnSuperWindowProc; 260 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 261 b = Ctrl2.SubclassWindow(hwnd1); 262 ok_int(b, TRUE); 263 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 264 fn1 = Ctrl2.m_pfnSuperWindowProc; 265 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 266 hwnd2 = Ctrl2.UnsubclassWindow(FALSE); 267 ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); 268 fn2 = Ctrl2.m_pfnSuperWindowProc; 269 ok(fn1 != fn2, "fn1 == fn2\n"); 270 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 271 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 272 DestroyWindow(hwnd2); 273 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 274 } 275 276 { 277 CMyCtrl2 Ctrl2; 278 s_flag = FALSE; // "STATIC" 279 hwnd1 = MyCreateWindow(style); 280 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 281 fn1 = Ctrl2.m_pfnSuperWindowProc; 282 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 283 b = Ctrl2.SubclassWindow(hwnd1); 284 ok_int(b, TRUE); 285 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 286 fn1 = Ctrl2.m_pfnSuperWindowProc; 287 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 288 DestroyWindow(hwnd1); // destroy now 289 hwnd2 = Ctrl2.UnsubclassWindow(FALSE); 290 ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); 291 fn2 = Ctrl2.m_pfnSuperWindowProc; 292 ok(fn2 != DefWindowProc, "fn2 was %p\n", fn2); // ntdll.dll!NtdllEditWndProc_W 293 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 294 DestroyWindow(hwnd2); 295 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 296 } 297 298 { 299 CMyCtrl2 Ctrl2; 300 s_flag = TRUE; // "EDIT" 301 hwnd1 = MyCreateWindow(style); 302 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 303 fn1 = Ctrl2.m_pfnSuperWindowProc; 304 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 305 b = Ctrl2.SubclassWindow(hwnd1); 306 ok_int(b, TRUE); 307 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 308 Ctrl2.m_pfnSuperWindowProc = MyWindowProc; 309 hwnd2 = Ctrl2.UnsubclassWindow(FALSE); 310 ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); 311 fn2 = Ctrl2.m_pfnSuperWindowProc; 312 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 313 ok(Ctrl2.m_hWnd == NULL, "hwnd != NULL\n"); 314 DestroyWindow(hwnd2); 315 ok(Ctrl2.m_hWnd == NULL, "hwnd != NULL\n"); 316 } 317 318 // 319 // Ctrl2 (Forced) 320 // 321 { 322 CMyCtrl2 Ctrl2; 323 s_flag = TRUE; // "EDIT" 324 hwnd1 = MyCreateWindow(style); 325 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 326 fn1 = Ctrl2.m_pfnSuperWindowProc; 327 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 328 b = Ctrl2.SubclassWindow(hwnd1); 329 ok_int(b, TRUE); 330 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 331 fn1 = Ctrl2.m_pfnSuperWindowProc; 332 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 333 hwnd2 = Ctrl2.UnsubclassWindow(TRUE); 334 ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); 335 fn2 = Ctrl2.m_pfnSuperWindowProc; 336 ok(fn1 != fn2, "fn1 == fn2\n"); 337 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 338 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 339 DestroyWindow(hwnd2); 340 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 341 } 342 343 { 344 CMyCtrl2 Ctrl2; 345 s_flag = TRUE; // "EDIT" 346 hwnd1 = MyCreateWindow(style); 347 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 348 fn1 = Ctrl2.m_pfnSuperWindowProc; 349 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 350 b = Ctrl2.SubclassWindow(hwnd1); 351 ok_int(b, TRUE); 352 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 353 fn1 = Ctrl2.m_pfnSuperWindowProc; 354 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 355 DestroyWindow(hwnd1); // destroy now 356 hwnd2 = Ctrl2.UnsubclassWindow(TRUE); 357 ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); 358 fn2 = Ctrl2.m_pfnSuperWindowProc; 359 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 360 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 361 DestroyWindow(hwnd2); 362 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 363 } 364 365 { 366 CMyCtrl2 Ctrl2; 367 s_flag = FALSE; // "STATIC" 368 hwnd1 = MyCreateWindow(style); 369 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 370 fn1 = Ctrl2.m_pfnSuperWindowProc; 371 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 372 b = Ctrl2.SubclassWindow(hwnd1); 373 ok_int(b, TRUE); 374 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 375 fn1 = Ctrl2.m_pfnSuperWindowProc; 376 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 377 hwnd2 = Ctrl2.UnsubclassWindow(TRUE); 378 ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); 379 fn2 = Ctrl2.m_pfnSuperWindowProc; 380 ok(fn1 != fn2, "fn1 == fn2\n"); 381 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 382 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 383 DestroyWindow(hwnd2); 384 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 385 } 386 387 { 388 CMyCtrl2 Ctrl2; 389 s_flag = FALSE; // "STATIC" 390 hwnd1 = MyCreateWindow(style); 391 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 392 fn1 = Ctrl2.m_pfnSuperWindowProc; 393 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 394 b = Ctrl2.SubclassWindow(hwnd1); 395 ok_int(b, TRUE); 396 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 397 fn1 = Ctrl2.m_pfnSuperWindowProc; 398 ok(fn1 != DefWindowProc, "fn1 was %p\n", fn1); 399 DestroyWindow(hwnd1); // destroy now 400 hwnd2 = Ctrl2.UnsubclassWindow(TRUE); 401 ok(hwnd2 == NULL, "hwnd2 was %p\n", hwnd2); 402 fn2 = Ctrl2.m_pfnSuperWindowProc; 403 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 404 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 405 DestroyWindow(hwnd2); 406 ok(Ctrl2.m_hWnd == NULL, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 407 } 408 409 { 410 CMyCtrl2 Ctrl2; 411 s_flag = TRUE; // "EDIT" 412 hwnd1 = MyCreateWindow(style); 413 ok(hwnd1 != NULL, "hwnd1 was NULL\n"); 414 fn1 = Ctrl2.m_pfnSuperWindowProc; 415 ok(fn1 == DefWindowProc, "fn1 was %p\n", fn1); 416 b = Ctrl2.SubclassWindow(hwnd1); 417 ok_int(b, TRUE); 418 ok(Ctrl2.m_hWnd == hwnd1, "Ctrl2.m_hWnd was %p\n", Ctrl2.m_hWnd); 419 Ctrl2.m_pfnSuperWindowProc = MyWindowProc; 420 hwnd2 = Ctrl2.UnsubclassWindow(TRUE); 421 ok(hwnd1 == hwnd2, "hwnd1 != hwnd2\n"); 422 fn2 = Ctrl2.m_pfnSuperWindowProc; 423 ok(fn2 == DefWindowProc, "fn2 was %p\n", fn2); 424 ok(Ctrl2.m_hWnd == NULL, "hwnd != NULL\n"); 425 DestroyWindow(hwnd2); 426 ok(Ctrl2.m_hWnd == NULL, "hwnd != NULL\n"); 427 } 428 } 429