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