e07e76371a86036b375fb02531b981d3badb88a4
[reactos.git] / rostests / apitests / user32 / RegisterClassEx.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for RegisterClassEx
5 * PROGRAMMERS: Giannis Adamopoulos
6 */
7
8 #include <apitest.h>
9 #define WIN32_NO_STATUS
10 #include <ndk/rtlfuncs.h>
11
12 #include <wchar.h>
13 #include <wingdi.h>
14 #include <winuser.h>
15 #include "helper.h"
16 #include <undocuser.h>
17
18 static ATOM _RegisterClass(LPCWSTR lpwszClassName, HINSTANCE hInstance, UINT style, WNDPROC lpfnWndProc)
19 {
20 WNDCLASSEXW wcex = {sizeof(WNDCLASSEXW), style, lpfnWndProc};
21 wcex.lpszClassName = lpwszClassName;
22 wcex.hInstance = hInstance;
23 return RegisterClassExW(&wcex);
24 }
25
26 static ATOM _GetClassAtom(LPCWSTR lpwszClassName, HINSTANCE hInstance)
27 {
28 WNDCLASSEXW wcex = {sizeof(WNDCLASSEXW)};
29 return (ATOM)GetClassInfoExW(hInstance, lpwszClassName, &wcex);
30 }
31
32 static WNDPROC _GetWndproc(LPCWSTR lpwszClassName, HINSTANCE hInstance)
33 {
34 WNDCLASSEXW wcex = {sizeof(WNDCLASSEXW)};
35 BOOL ret = GetClassInfoExW(hInstance, lpwszClassName, &wcex);
36 return ret ? wcex.lpfnWndProc : NULL;
37 }
38
39 static ATOM _RegisterClassA(LPCSTR lpzClassName, HINSTANCE hInstance, UINT style, WNDPROC lpfnWndProc)
40 {
41 WNDCLASSEXA wcex = {sizeof(WNDCLASSEX), style, lpfnWndProc};
42 wcex.lpszClassName = lpzClassName;
43 wcex.hInstance = hInstance;
44 return RegisterClassExA(&wcex);
45 }
46
47 static ATOM _GetClassAtomA(LPCSTR lpszClassName, HINSTANCE hInstance)
48 {
49 WNDCLASSEXA wcex = {sizeof(WNDCLASSEX)};
50 return (ATOM)GetClassInfoExA(hInstance, lpszClassName, &wcex);
51 }
52
53 static WNDPROC _GetWndprocA(LPCSTR lpszClassName, HINSTANCE hInstance)
54 {
55 WNDCLASSEXA wcex = {sizeof(WNDCLASSEX)};
56 BOOL ret = GetClassInfoExA(hInstance, lpszClassName, &wcex);
57 return ret ? wcex.lpfnWndProc : NULL;
58 }
59
60 HANDLE _CreateActCtxFromFile(LPCWSTR FileName)
61 {
62 ACTCTXW ActCtx = {sizeof(ACTCTX)};
63 WCHAR buffer[MAX_PATH] , *separator;
64
65 ok (GetModuleFileNameW(NULL, buffer, MAX_PATH), "GetModuleFileName failed\n");
66 separator = wcsrchr(buffer, L'\\');
67 if (separator)
68 wcscpy(separator + 1, FileName);
69
70 ActCtx.lpSource = buffer;
71
72 return CreateActCtxW(&ActCtx);
73 }
74
75 VOID TestGlobalClasses(VOID)
76 {
77 HMODULE hmod = GetModuleHandle(NULL);
78 ATOM a,b,c,d,e;
79
80 a = _GetClassAtom(L"TestClass1", hmod);
81 b = _RegisterClass(L"TestClass1", hmod, 0, DefWindowProcW);
82 c = _GetClassAtom(L"TestClass1", hmod);
83 UnregisterClass(L"TestClass1", hmod);
84 d = _GetClassAtom(L"TestClass1", hmod);
85 ok( a == 0, "\n");
86 ok( b != 0, "\n");
87 ok( c != 0, "\n");
88 ok( d == 0, "\n");
89 ok (b == c, "\n");
90
91 a = _GetClassAtom(L"TestClass2", hmod);
92 b = _RegisterClass(L"TestClass2", hmod, CS_GLOBALCLASS, DefWindowProcW);
93 c = _GetClassAtom(L"TestClass2", hmod);
94 UnregisterClass(L"TestClass2", hmod);
95 d = _GetClassAtom(L"TestClass2", hmod);
96 ok( a == 0, "\n");
97 ok( b != 0, "\n");
98 ok( c != 0, "\n");
99 ok( d == 0, "\n");
100 ok (b == c, "\n");
101
102 a = _RegisterClass(L"TestClass3", hmod, 0, DefWindowProcW);
103 b = _RegisterClass(L"TestClass3", hmod, 0, DefWindowProcW);
104 c = _RegisterClass(L"TestClass3", hmod, CS_GLOBALCLASS, DefWindowProcW);
105 UnregisterClass(L"TestClass3", hmod);
106 d = _GetClassAtom(L"TestClass3", hmod);
107 ok( a != 0, "\n");
108 ok( b == 0, "\n");
109 ok( c == 0, "\n");
110 ok( d == 0, "\n");
111
112 a = _RegisterClass(L"TestClass4", hmod, CS_GLOBALCLASS, DefWindowProcW);
113 b = _RegisterClass(L"TestClass4", hmod, 0, DefWindowProcW);
114 c = _RegisterClass(L"TestClass4", hmod, 0, DefWindowProcW);
115 UnregisterClass(L"TestClass4", hmod);
116 d = _GetClassAtom(L"TestClass4", hmod);
117 UnregisterClass(L"TestClass4", hmod);
118 e = _GetClassAtom(L"TestClass4", hmod);
119 ok( a != 0, "\n");
120 ok( b != 0, "\n");
121 ok( c == 0, "\n");
122 ok( d != 0, "\n");
123 ok( e == 0, "\n");
124
125 a = _GetClassAtom(L"ComboBox", hmod);
126 b = _RegisterClass(L"ComboBox", hmod, 0, DefWindowProcW);
127 c = _RegisterClass(L"ComboBox", hmod, CS_GLOBALCLASS, DefWindowProcW);
128 UnregisterClass(L"ComboBox", hmod);
129 d = _GetClassAtom(L"ComboBox", hmod);
130 UnregisterClass(L"TestClass4", hmod);
131 e = _GetClassAtom(L"TestClass4", hmod);
132 ok( a != 0, "\n");
133 ok( b != 0, "\n");
134 ok( c == 0, "\n");
135 ok( d != 0, "\n");
136 ok( e == 0, "\n");
137
138 a = _GetClassAtom(L"ScrollBar", hmod);
139 UnregisterClass(L"ScrollBar", hmod);
140 b = _GetClassAtom(L"ScrollBar", hmod);
141 c = _RegisterClass(L"ScrollBar", hmod, CS_GLOBALCLASS, DefWindowProcW);
142 d = _GetClassAtom(L"ScrollBar", hmod);
143 ok( a != 0, "\n");
144 ok( b == 0, "\n");
145 ok( c != 0, "\n");
146 ok( d != 0, "\n");
147 ok( a == c, "\n");
148 ok( a == d, "\n"); /* In Windows 10 the last 4 tests fail */
149
150 a = _GetClassAtom(L"ListBox", (HMODULE)0xdead);
151 UnregisterClass(L"ListBox", (HMODULE)0xdead);
152 b = _GetClassAtom(L"ListBox", (HMODULE)0xdead);
153 ok( a != 0, "\n");
154 ok( b == 0, "\n");
155
156 a = _RegisterClass(L"TestClass5", (HMODULE)0xdead, CS_GLOBALCLASS, DefWindowProcW);
157 b = _GetClassAtom(L"TestClass5", hmod);
158 UnregisterClass(L"TestClass5", hmod);
159 c = _GetClassAtom(L"TestClass5", (HMODULE)0xdead);
160 d = _GetClassAtom(L"TestClass5", hmod);
161 ok( a != 0, "\n");
162 ok( b != 0, "\n");
163 ok( c == 0, "\n");
164 ok( d == 0, "\n");
165 }
166
167 VOID TestVersionedClasses(VOID)
168 {
169 HMODULE hmod = GetModuleHandle(NULL);
170 HANDLE h1, h2;
171 ULONG_PTR cookie1, cookie2;
172 ATOM a,b,c,d;
173 WNDPROC proc1,proc2,proc3, proc4, proc5;
174 WCHAR buffer[50];
175
176
177 h1 = _CreateActCtxFromFile(L"verclasstest1.manifest");
178 h2 = _CreateActCtxFromFile(L"verclasstest2.manifest");
179 if (h1 == INVALID_HANDLE_VALUE || h2 == INVALID_HANDLE_VALUE)
180 {
181 skip("Loading manifests failed. Skipping TestVersionedClasses\n");
182 return;
183 }
184
185 a = _RegisterClass(L"VersionTestClass1", hmod, 0, DefWindowProcA);
186 proc1 = _GetWndproc(L"VersionTestClass1", hmod);
187 b = _RegisterClass(L"VersionTestClass1", hmod, 0, DefWindowProcW);
188 ActivateActCtx(h1, &cookie1);
189 proc2 = _GetWndproc(L"VersionTestClass1", hmod);
190 c = _RegisterClass(L"VersionTestClass1", hmod, 0, DefWindowProcW);
191 d = _GetClassAtom(L"VersionTestClass1", hmod);
192 proc3 = _GetWndproc(L"VersionTestClass1", hmod);
193 proc4 = _GetWndproc((LPCWSTR)(DWORD_PTR)a, hmod);
194 DeactivateActCtx(0, cookie1);
195 proc5 = _GetWndproc(L"VersionTestClass1", hmod);
196 ok( a != 0, "\n");
197 ok( b == 0, "\n");
198 ok( c != 0, "\n");
199 ok( d != 0, "\n");
200 ok( a == c, "\n");
201 ok( a == d, "\n");
202 ok (proc1 == DefWindowProcA, "\n");
203 ok (proc2 == NULL, "Got 0x%p, expected NULL\n", proc2);
204 ok (proc3 == DefWindowProcW, "Got 0x%p, expected 0x%p\n", proc3, DefWindowProcW);
205 ok (proc4 == DefWindowProcW, "Got 0x%p, expected 0x%p\n", proc4, DefWindowProcW);
206 ok (proc5 == DefWindowProcA, "\n");
207
208 a = _GetClassAtom(L"Button", hmod);
209 b = _RegisterClass(L"Button", hmod, CS_GLOBALCLASS, DefWindowProcA);
210 proc1 = _GetWndproc(L"Button", (HMODULE)0xdead);
211 ActivateActCtx(h2, &cookie1);
212 c = _RegisterClass(L"Button", hmod, CS_GLOBALCLASS, DefWindowProcA);
213 proc2 = _GetWndproc(L"Button", (HMODULE)0xdead);
214 d = _GetClassAtom(L"3.3.3.3!Button", (HMODULE)0xdead);
215 proc3 = _GetWndproc(L"3.3.3.3!Button", (HMODULE)0xdead);
216 ok( a != 0, "\n");
217 ok( b == 0, "\n");
218 ok( c != 0, "\n");
219 ok( d != 0, "\n");
220 ok( a == c, "\n");
221 ok( d == a, "\n");
222 ok( proc1 != NULL, "\n");
223 ok( proc1 != DefWindowProcA, "Got 0x%p, expected not 0x%p\n", proc1, DefWindowProcA);
224 ok( proc2 == DefWindowProcA, "Got 0x%p, expected 0x%p\n", proc2, DefWindowProcA);
225 ok( proc3 == DefWindowProcA, "Got 0x%p, expected 0x%p\n", proc3, DefWindowProcA);
226
227 a = _RegisterClass(L"VersionTestClass2", hmod, CS_GLOBALCLASS, DefWindowProcW);
228 proc1 = _GetWndproc(L"VersionTestClass2", (HMODULE)0xdead);
229 b = _RegisterClass(L"VersionTestClass2", hmod, 0, DefWindowProcA);
230 proc2 = _GetWndproc(L"VersionTestClass2", hmod);
231 proc3 = _GetWndproc(L"VersionTestClass2", (HMODULE)0xdead);
232 ok (a != 0, "\n");
233 ok (b != 0, "\n");
234 ok (a == b, "\n");
235 ok (proc1 == DefWindowProcW, "Got 0x%p, expected 0x%p\n", proc1, DefWindowProcW);
236 ok (proc2 == DefWindowProcA, "Got 0x%p, expected 0x%p\n", proc2, DefWindowProcA);
237 ok (proc3 == DefWindowProcW, "Got 0x%p, expected 0x%p\n", proc2, DefWindowProcA);
238
239 a = _RegisterClass(L"VersionTestClass3", hmod, 0, DefWindowProcW);
240 swprintf(buffer, L"#%d", a);
241 proc1 = _GetWndproc((LPCWSTR)(DWORD_PTR)a, hmod);
242 proc2 = _GetWndproc(buffer, hmod);
243 ok (a != 0, "\n");
244 ok (proc1 == DefWindowProcW, "\n");
245 ok (proc2 == 0, "Got 0x%p for %S, expected 0\n", proc2, buffer);
246 DeactivateActCtx(0, cookie1);
247
248 a = _RegisterClass(L"VersionTestClass3", hmod, 0, DefWindowProcW);
249 swprintf(buffer, L"#%d", a);
250 proc1 = _GetWndproc((LPCWSTR)(DWORD_PTR)a, hmod);
251 proc2 = _GetWndproc(buffer, hmod);
252 ok (a != 0, "\n");
253 ok (proc1 == DefWindowProcW, "\n");
254 ok (proc2 == 0, "Got 0x%p for %S, expected 0\n", proc2, buffer);
255
256 ActivateActCtx(h2, &cookie1);
257 a = _RegisterClassA("VersionTestClass7", hmod, 0, DefWindowProcW);
258 b = _GetClassAtomA("VersionTestClass7", hmod);
259 proc1 = _GetWndprocA("VersionTestClass7", hmod);
260 proc2 = _GetWndprocA((LPCSTR)(DWORD_PTR)a, hmod);
261 ok(a != 0, "\n");
262 ok(b != 0, "\n");
263 ok(a == b, "\n");
264 ok (proc1 == DefWindowProcW, "\n");
265 ok (proc2 == DefWindowProcW, "\n");
266
267 DeactivateActCtx(0, cookie1);
268
269 proc1 = _GetWndproc(L"Button", 0);
270 ActivateActCtx(h2, &cookie1);
271 ActivateActCtx(h1, &cookie2);
272 proc2 = _GetWndproc(L"Button", 0);
273 DeactivateActCtx(0, cookie2);
274 ActivateActCtx(0, &cookie2);
275 proc3 = _GetWndproc(L"Button", 0);
276 DeactivateActCtx(0, cookie2);
277 DeactivateActCtx(0, cookie1);
278 ok (proc1 != 0, "\n");
279 ok (proc2 != 0, "\n");
280 ok (proc4 != 0, "\n");
281 ok (proc1 == proc2, "\n");
282 ok (proc1 == proc3, "\n");
283
284 }
285
286 START_TEST(RegisterClassEx)
287 {
288 TestGlobalClasses();
289 TestVersionedClasses();
290 }