2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for NtUserCreateWindowEx
12 CreateWnd(HINSTANCE hinst
,
13 PLARGE_STRING clsName
,
15 PLARGE_STRING wndName
)
17 return NtUserCreateWindowEx(WS_EX_OVERLAPPEDWINDOW
,
34 /* WndProc for class1 */
36 LRESULT CALLBACK
wndProc1(HWND hwnd
, UINT msg
, WPARAM wPrm
, LPARAM lPrm
)
38 return DefWindowProc(hwnd
, msg
, wPrm
, lPrm
);
41 /* WndProc for class2 */
42 LRESULT CALLBACK
wndProc2(HWND hwnd
, UINT msg
, WPARAM wPrm
, LPARAM lPrm
)
44 return DefWindowProc(hwnd
, msg
, wPrm
, lPrm
);
48 START_TEST(NtUserCreateWindowEx
)
50 HINSTANCE hinst
= GetModuleHandle(NULL
);
51 WNDCLASSEXW wclex
= {0};
52 WNDCLASSEXW wclex2
= {0};
53 WNDCLASSEXW res
= {0};
55 /* Unicode strings for NtRegisterClassExWOW */
56 UNICODE_STRING cls
= {14, 32, L
"MyClass"};
57 UNICODE_STRING ver_cls
= {12, 32, L
"v2test"};
58 UNICODE_STRING another_cls
= {10, 32, L
"Dummy"};
59 UNICODE_STRING menu
= {10, 10, L
"MuMnu"};
60 UNICODE_STRING null_cls
= {2, 2, L
""};
62 /* LARGE_STRING for NtUserCreateWindowEx */
63 LARGE_STRING l_dummy
= {14, 32, 0, L
"DummyMe"};
64 LARGE_STRING l_empty
= {0, 0, 0, L
""};
65 LARGE_STRING l_wndName
= {32, 32, 0, L
""};
66 LARGE_STRING l_cls
= {cls
.Length
, 32, 0, cls
.Buffer
};
67 LARGE_STRING l_ver_cls
= {ver_cls
.Length
, 32, 0, ver_cls
.Buffer
};
68 WCHAR bufMe
[255] = {0};
69 UNICODE_STRING capture
= {255, 255, bufMe
};
71 CLSMENUNAME clsMenuName
, outClsMnu
= {0};
72 ATOM atom
, atom2
, atom3
;
75 clsMenuName
.pszClientAnsiMenuName
= "MuMnu";
76 clsMenuName
.pwszClientUnicodeMenuName
= menu
.Buffer
;
77 clsMenuName
.pusMenuName
= &menu
;
79 wclex
.cbSize
= sizeof(WNDCLASSEXW
);
81 wclex
.lpfnWndProc
= wndProc1
;
84 wclex
.hInstance
= hinst
;
87 wclex
.hbrBackground
= CreateSolidBrush(RGB(4,7,5));
88 wclex
.lpszMenuName
= menu
.Buffer
;
89 wclex
.lpszClassName
= cls
.Buffer
;
91 memcpy(&wclex2
, &wclex
, sizeof(wclex
));
92 wclex2
.lpfnWndProc
= wndProc2
;
94 /* Register our first version */
95 atom
= NtUserRegisterClassExWOW(&wclex
, /* wndClass */
98 &clsMenuName
, /* MenuName */
104 /* Register second version */
105 atom2
= NtUserRegisterClassExWOW(&wclex2
, /* wndClass */
106 &cls
, /* ClassName */
107 &ver_cls
, /* Version */
108 &clsMenuName
, /* MenuName */
113 atom3
= NtUserRegisterClassExWOW(&wclex2
, /* wndClass */
114 &another_cls
, /* ClassName */
115 &another_cls
, /* Version */
116 &clsMenuName
, /* MenuName */
121 TEST(NtUserRegisterClassExWOW(&wclex2
, /* wndClass */
122 &cls
, /* ClassName */
124 &clsMenuName
, /* MenuName */
129 TEST(NtUserRegisterClassExWOW(&wclex2
, /* wndClass */
130 &cls
, /* ClassName */
131 &null_cls
, /* Version */
132 &clsMenuName
, /* MenuName */
137 TEST(NtUserGetWOWClass(hinst
, &ver_cls
) != 0);
138 TEST(NtUserGetWOWClass(hinst
, &ver_cls
) != NtUserGetWOWClass(hinst
, &cls
)); TEST(atom2
!= 0);
139 TEST(atom
== atom2
&& (atom
| atom2
) != 0);
141 /* Create a window without versioned class */
142 TEST(CreateWnd(hinst
, &l_cls
, NULL
, &l_wndName
) == 0);
143 TEST(CreateWnd(hinst
, &l_cls
, &l_wndName
, &l_wndName
) == 0);
145 /* Now, create our first window */
146 hwnd
= CreateWnd(hinst
, &l_cls
, &l_cls
, &l_wndName
);
150 /* Test some settings about the window */
151 TEST((WNDPROC
)GetWindowLongPtrW(hwnd
, GWLP_WNDPROC
) == wndProc1
);
153 /* Check class name isn't versioned */
154 TEST(NtUserGetClassName(hwnd
, TRUE
, &capture
) != 0);
155 TEST(wcscmp(capture
.Buffer
, cls
.Buffer
) == 0);
156 TEST(wcscmp(capture
.Buffer
, ver_cls
.Buffer
) != 0);
157 ZeroMemory(capture
.Buffer
, 255);
159 /* Check what return GetClassLong */
160 TEST(GetClassLong(hwnd
, GCW_ATOM
) == atom
);
161 TEST(NtUserSetClassLong(hwnd
, GCW_ATOM
, atom3
, FALSE
) == atom
);
162 NtUserGetClassName(hwnd
, TRUE
, &capture
);
163 TEST(wcscmp(capture
.Buffer
, another_cls
.Buffer
) == 0);
165 /* Finally destroy it */
169 /* Create our second version */
170 hwnd
= CreateWnd(hinst
, &l_cls
, &l_ver_cls
, &l_wndName
);
174 /* Test settings about window */
175 TEST((WNDPROC
)GetWindowLongPtrW(hwnd
, GWLP_WNDPROC
) == wndProc2
);
177 /* Check class name isn't versioned */
178 TEST(NtUserGetClassName(hwnd
, TRUE
, &capture
) != 0);
179 TEST(wcscmp(capture
.Buffer
, cls
.Buffer
) == 0);
180 TEST(wcscmp(capture
.Buffer
, ver_cls
.Buffer
) != 0);
181 ZeroMemory(capture
.Buffer
, 255);
183 /* Check what return GetClassLong */
184 TEST(GetClassLong(hwnd
, GCW_ATOM
) == atom
);
186 TEST(NtUserFindWindowEx(NULL
, NULL
, &cls
, (UNICODE_STRING
*)&l_empty
, 0) == hwnd
);
188 /* Finally destroy it */
192 /* Create a nonexistent window */
193 hwnd
= CreateWnd(hinst
, &l_cls
, &l_dummy
, &l_wndName
);
195 if (hwnd
) DestroyWindow(hwnd
);
197 /* Get non-versioned class info */
198 res
.cbSize
= sizeof(res
);
200 TEST(NtUserGetClassInfo(hinst
, &cls
, &res
, &pwstr
, 0) != 0);
201 TEST(GetLastError() == 0);
202 TEST(res
.cbSize
== wclex
.cbSize
);
203 TEST(res
.style
== wclex
.style
);
204 TEST(res
.lpfnWndProc
== wclex
.lpfnWndProc
);
205 TEST(res
.cbClsExtra
== wclex
.cbClsExtra
);
206 TEST(res
.cbWndExtra
== wclex
.cbWndExtra
);
207 TEST(res
.hInstance
== wclex
.hInstance
);
208 TEST(res
.hIcon
== wclex
.hIcon
);
209 TEST(res
.hCursor
== wclex
.hCursor
);
210 TEST(res
.hbrBackground
== wclex
.hbrBackground
);
211 TEST(res
.lpszMenuName
== 0);
212 TEST(res
.lpszClassName
== 0);
213 TEST(res
.hIconSm
== wclex
.hIconSm
);
215 /* Get versioned class info */
216 TEST(NtUserGetClassInfo(hinst
, &ver_cls
, &res
, &pwstr
, 0) == atom2
);
217 TEST(GetLastError() == 0);
218 TEST(res
.cbSize
== wclex2
.cbSize
);
219 TEST(res
.style
== wclex2
.style
);
220 TEST(res
.lpfnWndProc
== wclex2
.lpfnWndProc
);
221 TEST(res
.cbClsExtra
== wclex2
.cbClsExtra
);
222 TEST(res
.cbWndExtra
== wclex2
.cbWndExtra
);
223 TEST(res
.hInstance
== wclex2
.hInstance
);
224 TEST(res
.hIcon
== wclex2
.hIcon
);
225 TEST(res
.hCursor
== wclex2
.hCursor
);
226 TEST(res
.hbrBackground
== wclex2
.hbrBackground
);
227 TEST(res
.lpszMenuName
== 0);
228 TEST(res
.lpszClassName
== 0);
229 TEST(res
.hIconSm
== wclex2
.hIconSm
);
231 /* Create a new window from our old class. Since we set a new class atom,
232 * it should be set to our new atom
235 hwnd
= CreateWnd(hinst
, &l_cls
, &l_cls
, &l_wndName
);
239 TEST(GetClassLong(hwnd
, GCW_ATOM
) == atom3
);
240 TEST(NtUserGetClassName(hwnd
, TRUE
, &capture
) != 0);
241 TEST(wcscmp(capture
.Buffer
, another_cls
.Buffer
) == 0);
245 /* Test class destruction */
246 TEST(NtUserUnregisterClass(&cls
, hinst
, (PCLSMENUNAME
)0xbad) != 0);
247 TEST(NtUserUnregisterClass(&ver_cls
, hinst
, &outClsMnu
) != 0);
248 TEST(NtUserUnregisterClass(&another_cls
, hinst
, &outClsMnu
) != 0);
249 TEST(NtUserUnregisterClass(&menu
, hinst
, &outClsMnu
) == 0);
251 /* Make sure that the classes got destroyed */
252 TEST(NtUserGetWOWClass(hinst
, &cls
) == 0);
253 TEST(NtUserGetWOWClass(hinst
, &ver_cls
) == 0);
254 TEST(NtUserGetWOWClass(hinst
, &another_cls
) == 0);