[WIN32NT_APITEST] Add some NtUserCreateWindowEx tests by Sylvain Deverre. ROSTESTS-237
[reactos.git] / rostests / apitests / win32nt / ntuser / NtUserCreateWindowEx.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for NtUserCreateWindowEx
5 */
6
7 #include <win32nt.h>
8
9 static
10 inline
11 HWND
12 CreateWnd(HINSTANCE hinst,
13 PLARGE_STRING clsName,
14 PLARGE_STRING clsVer,
15 PLARGE_STRING wndName)
16 {
17 return NtUserCreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
18 clsName,
19 clsVer,
20 wndName,
21 WS_CAPTION,
22 CW_USEDEFAULT,
23 CW_USEDEFAULT,
24 100,
25 100,
26 NULL,
27 NULL,
28 hinst,
29 0,
30 0,
31 NULL);
32 }
33
34 /* WndProc for class1 */
35
36 LRESULT CALLBACK wndProc1(HWND hwnd, UINT msg, WPARAM wPrm, LPARAM lPrm)
37 {
38 return DefWindowProc(hwnd, msg, wPrm, lPrm);
39 }
40
41 /* WndProc for class2 */
42 LRESULT CALLBACK wndProc2(HWND hwnd, UINT msg, WPARAM wPrm, LPARAM lPrm)
43 {
44 return DefWindowProc(hwnd, msg, wPrm, lPrm);
45 }
46
47
48 START_TEST(NtUserCreateWindowEx)
49 {
50 HINSTANCE hinst = GetModuleHandle(NULL);
51 WNDCLASSEXW wclex = {0};
52 WNDCLASSEXW wclex2 = {0};
53 WNDCLASSEXW res = {0};
54
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
61 /* LARGE_STRING for NtUserCreateWindowEx */
62 LARGE_STRING l_dummy = {14, 32, 0, L"DummyMe"};
63 LARGE_STRING l_wndName = {32, 32, 0, L""};
64 LARGE_STRING l_cls = {cls.Length, 32, 0, cls.Buffer};
65 LARGE_STRING l_ver_cls = {ver_cls.Length, 32, 0, ver_cls.Buffer};
66 WCHAR bufMe[255] = {0};
67 UNICODE_STRING capture = {255, 255, bufMe};
68 PWSTR pwstr = NULL;
69 CLSMENUNAME clsMenuName, outClsMnu = {0};
70 ATOM atom, atom2, atom3;
71 HWND hwnd;
72
73 clsMenuName.pszClientAnsiMenuName = "MuMnu";
74 clsMenuName.pwszClientUnicodeMenuName = menu.Buffer;
75 clsMenuName.pusMenuName = &menu;
76
77 wclex.cbSize = sizeof(WNDCLASSEXW);
78 wclex.style = 0;
79 wclex.lpfnWndProc = wndProc1;
80 wclex.cbClsExtra = 2;
81 wclex.cbWndExtra = 4;
82 wclex.hInstance = hinst;
83 wclex.hIcon = NULL;
84 wclex.hCursor = NULL;
85 wclex.hbrBackground = CreateSolidBrush(RGB(4,7,5));
86 wclex.lpszMenuName = menu.Buffer;
87 wclex.lpszClassName = cls.Buffer;
88 wclex.hIconSm = NULL;
89 memcpy(&wclex2, &wclex, sizeof(wclex));
90 wclex2.lpfnWndProc = wndProc2;
91
92 /* Register our first version */
93 atom = NtUserRegisterClassExWOW(&wclex, /* wndClass */
94 &cls, /* ClassName */
95 &cls, /* Version */
96 &clsMenuName, /* MenuName */
97 0,
98 0,
99 NULL);
100 TEST(atom != 0);
101
102 /* Register second version */
103 atom2 = NtUserRegisterClassExWOW(&wclex2, /* wndClass */
104 &cls, /* ClassName */
105 &ver_cls, /* Version */
106 &clsMenuName, /* MenuName */
107 0,
108 0,
109 NULL);
110
111 atom3 = NtUserRegisterClassExWOW(&wclex2, /* wndClass */
112 &another_cls, /* ClassName */
113 &another_cls, /* Version */
114 &clsMenuName, /* MenuName */
115 0,
116 0,
117 NULL);
118
119 TEST(NtUserGetWOWClass(hinst, &ver_cls) != 0);
120
121 TEST(atom2 != 0);
122 TEST(atom == atom2 && (atom | atom2) != 0);
123
124 /* Now, create our first window */
125 hwnd = CreateWnd(hinst, &l_cls, &l_cls, &l_wndName);
126 TEST(hwnd != 0);
127 if(hwnd)
128 {
129 /* Test some settings about the window */
130 TEST((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == wndProc1);
131
132 /* Check class name isn't versioned */
133 TEST(NtUserGetClassName(hwnd, TRUE, &capture) != 0);
134 TEST(wcscmp(capture.Buffer, cls.Buffer) == 0);
135 TEST(wcscmp(capture.Buffer, ver_cls.Buffer) != 0);
136 ZeroMemory(capture.Buffer, 255);
137
138 /* Check what return GetClassLong */
139 TEST(GetClassLong(hwnd, GCW_ATOM) == atom);
140 TEST(NtUserSetClassLong(hwnd, GCW_ATOM, atom3, FALSE) == atom);
141 NtUserGetClassName(hwnd, TRUE, &capture);
142 TEST(wcscmp(capture.Buffer, another_cls.Buffer) == 0);
143
144 /* Finally destroy it */
145 DestroyWindow(hwnd);
146 }
147
148 /* Create our second version */
149 hwnd = CreateWnd(hinst, &l_cls, &l_ver_cls, &l_wndName);
150 TEST(hwnd != 0);
151 if (hwnd)
152 {
153 /* Test settings about window */
154 TEST((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == wndProc2);
155
156 /* Check class name isn't versioned */
157 TEST(NtUserGetClassName(hwnd, TRUE, &capture) != 0);
158 TEST(wcscmp(capture.Buffer, cls.Buffer) == 0);
159 TEST(wcscmp(capture.Buffer, ver_cls.Buffer) != 0);
160 ZeroMemory(capture.Buffer, 255);
161
162 /* Check what return GetClassLong */
163 TEST(GetClassLong(hwnd, GCW_ATOM) == atom);
164
165 /* Finally destroy it */
166 DestroyWindow(hwnd);
167 }
168
169 /* Create a nonexistent window */
170 hwnd = CreateWnd(hinst, &l_cls, &l_dummy, &l_wndName);
171 TEST(hwnd == 0);
172 if (hwnd) DestroyWindow(hwnd);
173
174 /* Get non-versioned class info */
175 res.cbSize = sizeof(res);
176 SetLastError(0);
177 TEST(NtUserGetClassInfo(hinst, &cls, &res, &pwstr, 0) != 0);
178 TEST(GetLastError() == 0);
179 TEST(res.cbSize == wclex.cbSize);
180 TEST(res.style == wclex.style);
181 TEST(res.lpfnWndProc == wclex.lpfnWndProc);
182 TEST(res.cbClsExtra == wclex.cbClsExtra);
183 TEST(res.cbWndExtra == wclex.cbWndExtra);
184 TEST(res.hInstance == wclex.hInstance);
185 TEST(res.hIcon == wclex.hIcon);
186 TEST(res.hCursor == wclex.hCursor);
187 TEST(res.hbrBackground == wclex.hbrBackground);
188 TEST(res.lpszMenuName == 0);
189 TEST(res.lpszClassName == 0);
190 TEST(res.hIconSm == wclex.hIconSm);
191
192 /* Get versioned class info */
193 TEST(NtUserGetClassInfo(hinst, &ver_cls, &res, &pwstr, 0) != 0);
194 TEST(GetLastError() == 0);
195 TEST(res.cbSize == wclex2.cbSize);
196 TEST(res.style == wclex2.style);
197 TEST(res.lpfnWndProc == wclex2.lpfnWndProc);
198 TEST(res.cbClsExtra == wclex2.cbClsExtra);
199 TEST(res.cbWndExtra == wclex2.cbWndExtra);
200 TEST(res.hInstance == wclex2.hInstance);
201 TEST(res.hIcon == wclex2.hIcon);
202 TEST(res.hCursor == wclex2.hCursor);
203 TEST(res.hbrBackground == wclex2.hbrBackground);
204 TEST(res.lpszMenuName == 0);
205 TEST(res.lpszClassName == 0);
206 TEST(res.hIconSm == wclex2.hIconSm);
207
208 /* Create a new window from our old class. Since we set a new class atom,
209 * it should be set to our new atom
210 */
211 hwnd = NULL;
212 hwnd = CreateWnd(hinst, &l_cls, &l_cls, &l_wndName);
213 TEST(hwnd != NULL);
214 if (hwnd)
215 {
216 TEST(GetClassLong(hwnd, GCW_ATOM) == atom3);
217 TEST(NtUserGetClassName(hwnd, TRUE, &capture) != 0);
218 TEST(wcscmp(capture.Buffer, another_cls.Buffer) == 0);
219 DestroyWindow(hwnd);
220 }
221
222 /* Test class destruction */
223 TEST(NtUserUnregisterClass(&cls, hinst, (PCLSMENUNAME)0xbad) != 0);
224 TEST(NtUserUnregisterClass(&ver_cls, hinst, &outClsMnu) != 0);
225 TEST(NtUserUnregisterClass(&another_cls, hinst, &outClsMnu) != 0);
226 TEST(NtUserUnregisterClass(&menu, hinst, &outClsMnu) == 0);
227
228 }