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