[USER32_APITEST] -Add more tests for versioned classes.
[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 proc3 = _GetWndproc(L"VersionTestClass1", hmod);
192 proc4 = _GetWndproc((LPCWSTR)(DWORD_PTR)a, hmod);
193 DeactivateActCtx(0, cookie1);
194 proc5 = _GetWndproc(L"VersionTestClass1", hmod);
195 ok( a != 0, "\n");
196 ok( b == 0, "\n");
197 ok( c != 0, "\n");
198 ok( a == c, "\n");
199 ok (proc1 == DefWindowProcA, "\n");
200 ok (proc2 == NULL, "Got 0x%p, expected NULL\n", proc2);
201 ok (proc3 == DefWindowProcW, "Got 0x%p, expected 0x%p\n", proc3, DefWindowProcW);
202 ok (proc4 == DefWindowProcW, "Got 0x%p, expected 0x%p\n", proc4, DefWindowProcW);
203 ok (proc5 == DefWindowProcA, "\n");
204
205 a = _GetClassAtom(L"Button", hmod);
206 b = _RegisterClass(L"Button", hmod, CS_GLOBALCLASS, DefWindowProcA);
207 proc1 = _GetWndproc(L"Button", (HMODULE)0xdead);
208 ActivateActCtx(h2, &cookie1);
209 c = _RegisterClass(L"Button", hmod, CS_GLOBALCLASS, DefWindowProcA);
210 proc2 = _GetWndproc(L"Button", (HMODULE)0xdead);
211 d = _GetClassAtom(L"3.3.3.3!Button", (HMODULE)0xdead);
212 proc3 = _GetWndproc(L"3.3.3.3!Button", (HMODULE)0xdead);
213 ok( a != 0, "\n");
214 ok( b == 0, "\n");
215 ok( c != 0, "\n");
216 ok( d != 0, "\n");
217 ok( a == c, "\n");
218 ok( d == a, "\n");
219 ok( proc1 != NULL, "\n");
220 ok( proc1 != DefWindowProcA, "Got 0x%p, expected not 0x%p\n", proc1, DefWindowProcA);
221 ok( proc2 == DefWindowProcA, "Got 0x%p, expected 0x%p\n", proc2, DefWindowProcA);
222 ok( proc3 == DefWindowProcA, "Got 0x%p, expected 0x%p\n", proc3, DefWindowProcA);
223
224 a = _RegisterClass(L"VersionTestClass2", hmod, CS_GLOBALCLASS, DefWindowProcW);
225 proc1 = _GetWndproc(L"VersionTestClass2", (HMODULE)0xdead);
226 b = _RegisterClass(L"VersionTestClass2", hmod, 0, DefWindowProcA);
227 proc2 = _GetWndproc(L"VersionTestClass2", hmod);
228 proc3 = _GetWndproc(L"VersionTestClass2", (HMODULE)0xdead);
229 ok (a != 0, "\n");
230 ok (b != 0, "\n");
231 ok (a == b, "\n");
232 ok (proc1 == DefWindowProcW, "Got 0x%p, expected 0x%p\n", proc1, DefWindowProcW);
233 ok (proc2 == DefWindowProcA, "Got 0x%p, expected 0x%p\n", proc2, DefWindowProcA);
234 ok (proc3 == DefWindowProcW, "Got 0x%p, expected 0x%p\n", proc2, DefWindowProcA);
235
236 a = _RegisterClass(L"VersionTestClass3", hmod, 0, DefWindowProcW);
237 swprintf(buffer, L"#%d", a);
238 proc1 = _GetWndproc((LPCWSTR)(DWORD_PTR)a, hmod);
239 proc2 = _GetWndproc(buffer, hmod);
240 ok (a != 0, "\n");
241 ok (proc1 == DefWindowProcW, "\n");
242 ok (proc2 == 0, "Got 0x%p for %S, expected 0\n", proc2, buffer);
243 DeactivateActCtx(0, cookie1);
244
245 a = _RegisterClass(L"VersionTestClass3", hmod, 0, DefWindowProcW);
246 swprintf(buffer, L"#%d", a);
247 proc1 = _GetWndproc((LPCWSTR)(DWORD_PTR)a, hmod);
248 proc2 = _GetWndproc(buffer, hmod);
249 ok (a != 0, "\n");
250 ok (proc1 == DefWindowProcW, "\n");
251 ok (proc2 == 0, "Got 0x%p for %S, expected 0\n", proc2, buffer);
252
253 ActivateActCtx(h2, &cookie1);
254 a = _RegisterClassA("VersionTestClass7", hmod, 0, DefWindowProcW);
255 b = _GetClassAtomA("VersionTestClass7", hmod);
256 proc1 = _GetWndprocA("VersionTestClass7", hmod);
257 proc2 = _GetWndprocA((LPCSTR)(DWORD_PTR)a, hmod);
258 ok(a != 0, "\n");
259 ok(b != 0, "\n");
260 ok(a == b, "\n");
261 ok (proc1 == DefWindowProcW, "\n");
262 ok (proc2 == DefWindowProcW, "\n");
263
264 DeactivateActCtx(0, cookie1);
265
266 proc1 = _GetWndproc(L"Button", 0);
267 ActivateActCtx(h2, &cookie1);
268 ActivateActCtx(h1, &cookie2);
269 proc2 = _GetWndproc(L"Button", 0);
270 DeactivateActCtx(0, cookie2);
271 ActivateActCtx(0, &cookie2);
272 proc3 = _GetWndproc(L"Button", 0);
273 DeactivateActCtx(0, cookie2);
274 DeactivateActCtx(0, cookie1);
275 ok (proc1 != 0, "\n");
276 ok (proc2 != 0, "\n");
277 ok (proc4 != 0, "\n");
278 ok (proc1 == proc2, "\n");
279 ok (proc1 == proc3, "\n");
280
281 }
282
283 START_TEST(RegisterClassEx)
284 {
285 TestGlobalClasses();
286 TestVersionedClasses();
287 }