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