ReactOS 0.4.15-dev-8127-g6338913
NtUserCreateWindowEx.c
Go to the documentation of this file.
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
9static
10inline
11HWND
13 PLARGE_STRING clsName,
14 PLARGE_STRING clsVer,
15 PLARGE_STRING wndName)
16{
18 clsName,
19 clsVer,
20 wndName,
24 100,
25 100,
26 NULL,
27 NULL,
28 hinst,
29 0,
30 0,
31 NULL);
32}
33
34/* WndProc for class1 */
35
37{
38 return DefWindowProc(hwnd, msg, wPrm, lPrm);
39}
40
41/* WndProc for class2 */
43{
44 return DefWindowProc(hwnd, msg, wPrm, lPrm);
45}
46
47
49{
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 UNICODE_STRING null_cls = {2, 2, L""};
61
62 /* LARGE_STRING for NtUserCreateWindowEx */
63 LARGE_STRING l_dummy = {14, 32, 0, L"DummyMe"};
64 LARGE_STRING l_empty = {0, 0, 0, L""};
65 LARGE_STRING l_wndName = {32, 32, 0, L""};
66 LARGE_STRING l_cls = {cls.Length, 32, 0, cls.Buffer};
67 LARGE_STRING l_ver_cls = {ver_cls.Length, 32, 0, ver_cls.Buffer};
68 WCHAR bufMe[255] = {0};
69 UNICODE_STRING capture = {255, 255, bufMe};
70 PWSTR pwstr = NULL;
71 CLSMENUNAME clsMenuName, outClsMnu = {0};
72 ATOM atom, atom2, atom3;
73 HWND hwnd;
74
75 clsMenuName.pszClientAnsiMenuName = "MuMnu";
76 clsMenuName.pwszClientUnicodeMenuName = menu.Buffer;
77 clsMenuName.pusMenuName = &menu;
78
79 wclex.cbSize = sizeof(WNDCLASSEXW);
80 wclex.style = 0;
81 wclex.lpfnWndProc = wndProc1;
82 wclex.cbClsExtra = 2;
83 wclex.cbWndExtra = 4;
84 wclex.hInstance = hinst;
85 wclex.hIcon = NULL;
86 wclex.hCursor = NULL;
87 wclex.hbrBackground = CreateSolidBrush(RGB(4,7,5));
88 wclex.lpszMenuName = menu.Buffer;
89 wclex.lpszClassName = cls.Buffer;
90 wclex.hIconSm = NULL;
91 memcpy(&wclex2, &wclex, sizeof(wclex));
92 wclex2.lpfnWndProc = wndProc2;
93
94 /* Register our first version */
95 atom = NtUserRegisterClassExWOW(&wclex, /* wndClass */
96 &cls, /* ClassName */
97 &cls, /* Version */
98 &clsMenuName, /* MenuName */
99 0,
100 0,
101 NULL);
102 TEST(atom != 0);
103
104 /* Register second version */
105 atom2 = NtUserRegisterClassExWOW(&wclex2, /* wndClass */
106 &cls, /* ClassName */
107 &ver_cls, /* Version */
108 &clsMenuName, /* MenuName */
109 0,
110 0,
111 NULL);
112
113 atom3 = NtUserRegisterClassExWOW(&wclex2, /* wndClass */
114 &another_cls, /* ClassName */
115 &another_cls, /* Version */
116 &clsMenuName, /* MenuName */
117 0,
118 0,
119 NULL);
120
121 TEST(NtUserRegisterClassExWOW(&wclex2, /* wndClass */
122 &cls, /* ClassName */
123 NULL, /* Version */
124 &clsMenuName, /* MenuName */
125 0,
126 0,
127 NULL) == 0);
128
129 TEST(NtUserRegisterClassExWOW(&wclex2, /* wndClass */
130 &cls, /* ClassName */
131 &null_cls, /* Version */
132 &clsMenuName, /* MenuName */
133 0,
134 0,
135 NULL) == 0);
136
137 TEST(NtUserGetWOWClass(hinst, &ver_cls) != 0);
138 TEST(NtUserGetWOWClass(hinst, &ver_cls) != NtUserGetWOWClass(hinst, &cls)); TEST(atom2 != 0);
139 TEST(atom == atom2 && (atom | atom2) != 0);
140
141 /* Create a window without versioned class */
142 TEST(CreateWnd(hinst, &l_cls, NULL, &l_wndName) == 0);
143 TEST(CreateWnd(hinst, &l_cls, &l_wndName, &l_wndName) == 0);
144
145 /* Now, create our first window */
146 hwnd = CreateWnd(hinst, &l_cls, &l_cls, &l_wndName);
147 TEST(hwnd != 0);
148 if(hwnd)
149 {
150 /* Test some settings about the window */
152
153 /* Check class name isn't versioned */
154 TEST(NtUserGetClassName(hwnd, TRUE, &capture) != 0);
155 TEST(wcscmp(capture.Buffer, cls.Buffer) == 0);
156 TEST(wcscmp(capture.Buffer, ver_cls.Buffer) != 0);
157 ZeroMemory(capture.Buffer, 255);
158
159 /* Check what return GetClassLong */
160 TEST(GetClassLong(hwnd, GCW_ATOM) == atom);
161 TEST(NtUserSetClassLong(hwnd, GCW_ATOM, atom3, FALSE) == atom);
162 NtUserGetClassName(hwnd, TRUE, &capture);
163 TEST(wcscmp(capture.Buffer, another_cls.Buffer) == 0);
164
165 /* Finally destroy it */
167 }
168
169 /* Create our second version */
170 hwnd = CreateWnd(hinst, &l_cls, &l_ver_cls, &l_wndName);
171 TEST(hwnd != 0);
172 if (hwnd)
173 {
174 /* Test settings about window */
176
177 /* Check class name isn't versioned */
178 TEST(NtUserGetClassName(hwnd, TRUE, &capture) != 0);
179 TEST(wcscmp(capture.Buffer, cls.Buffer) == 0);
180 TEST(wcscmp(capture.Buffer, ver_cls.Buffer) != 0);
181 ZeroMemory(capture.Buffer, 255);
182
183 /* Check what return GetClassLong */
184 TEST(GetClassLong(hwnd, GCW_ATOM) == atom);
185
186 TEST(NtUserFindWindowEx(NULL, NULL, &cls, (UNICODE_STRING*)&l_empty, 0) == hwnd);
187
188 /* Finally destroy it */
190 }
191
192 /* Create a nonexistent window */
193 hwnd = CreateWnd(hinst, &l_cls, &l_dummy, &l_wndName);
194 TEST(hwnd == 0);
195 if (hwnd) DestroyWindow(hwnd);
196
197 /* Get non-versioned class info */
198 res.cbSize = sizeof(res);
199 SetLastError(0);
200 TEST(NtUserGetClassInfo(hinst, &cls, &res, &pwstr, 0) != 0);
201 TEST(GetLastError() == 0);
202 TEST(res.cbSize == wclex.cbSize);
203 TEST(res.style == wclex.style);
204 TEST(res.lpfnWndProc == wclex.lpfnWndProc);
205 TEST(res.cbClsExtra == wclex.cbClsExtra);
206 TEST(res.cbWndExtra == wclex.cbWndExtra);
207 TEST(res.hInstance == wclex.hInstance);
208 TEST(res.hIcon == wclex.hIcon);
209 TEST(res.hCursor == wclex.hCursor);
210 TEST(res.hbrBackground == wclex.hbrBackground);
211 TEST(res.lpszMenuName == 0);
212 TEST(res.lpszClassName == 0);
213 TEST(res.hIconSm == wclex.hIconSm);
214
215 /* Get versioned class info */
216 TEST(NtUserGetClassInfo(hinst, &ver_cls, &res, &pwstr, 0) == atom2);
217 TEST(GetLastError() == 0);
218 TEST(res.cbSize == wclex2.cbSize);
219 TEST(res.style == wclex2.style);
220 TEST(res.lpfnWndProc == wclex2.lpfnWndProc);
221 TEST(res.cbClsExtra == wclex2.cbClsExtra);
222 TEST(res.cbWndExtra == wclex2.cbWndExtra);
223 TEST(res.hInstance == wclex2.hInstance);
224 TEST(res.hIcon == wclex2.hIcon);
225 TEST(res.hCursor == wclex2.hCursor);
226 TEST(res.hbrBackground == wclex2.hbrBackground);
227 TEST(res.lpszMenuName == 0);
228 TEST(res.lpszClassName == 0);
229 TEST(res.hIconSm == wclex2.hIconSm);
230
231 /* Create a new window from our old class. Since we set a new class atom,
232 * it should be set to our new atom
233 */
234 hwnd = NULL;
235 hwnd = CreateWnd(hinst, &l_cls, &l_cls, &l_wndName);
236 TEST(hwnd != NULL);
237 if (hwnd)
238 {
239 TEST(GetClassLong(hwnd, GCW_ATOM) == atom3);
240 TEST(NtUserGetClassName(hwnd, TRUE, &capture) != 0);
241 TEST(wcscmp(capture.Buffer, another_cls.Buffer) == 0);
243 }
244
245 /* Test class destruction */
246 TEST(NtUserUnregisterClass(&cls, hinst, (PCLSMENUNAME)0xbad) != 0);
247 TEST(NtUserUnregisterClass(&ver_cls, hinst, &outClsMnu) != 0);
248 TEST(NtUserUnregisterClass(&another_cls, hinst, &outClsMnu) != 0);
249 TEST(NtUserUnregisterClass(&menu, hinst, &outClsMnu) == 0);
250
251 /* Make sure that the classes got destroyed */
252 TEST(NtUserGetWOWClass(hinst, &cls) == 0);
253 TEST(NtUserGetWOWClass(hinst, &ver_cls) == 0);
254 TEST(NtUserGetWOWClass(hinst, &another_cls) == 0);
255}
LRESULT CALLBACK wndProc1(HWND hwnd, UINT msg, WPARAM wPrm, LPARAM lPrm)
LRESULT CALLBACK wndProc2(HWND hwnd, UINT msg, WPARAM wPrm, LPARAM lPrm)
static HWND CreateWnd(HINSTANCE hinst, PLARGE_STRING clsName, PLARGE_STRING clsVer, PLARGE_STRING wndName)
#define START_TEST(x)
Definition: atltest.h:75
#define msg(x)
Definition: auth_time.c:54
WORD ATOM
Definition: dimm.idl:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SetLastError(x)
Definition: compat.h:752
#define CALLBACK
Definition: compat.h:35
#define RGB(r, g, b)
Definition: precomp.h:71
GLuint res
Definition: glext.h:9613
BOOL NTAPI NtUserGetClassInfo(HINSTANCE hInstance, PUNICODE_STRING ClassName, LPWNDCLASSEXW wcex, LPWSTR *ppszMenuName, BOOL Ansi)
Definition: class.c:2731
PCLS NTAPI NtUserGetWOWClass(HINSTANCE hInstance, PUNICODE_STRING ClassName)
Definition: class.c:2893
BOOL NTAPI NtUserUnregisterClass(PUNICODE_STRING ClassNameOrAtom, HINSTANCE hInstance, PCLSMENUNAME pClassMenuName)
INT NTAPI NtUserGetClassName(HWND hWnd, BOOL Real, PUNICODE_STRING ClassName)
HWND NTAPI NtUserCreateWindowEx(DWORD dwExStyle, PLARGE_STRING plstrClassName, PLARGE_STRING plstrClsVersion, PLARGE_STRING plstrWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam, DWORD dwFlags, PVOID acbiBuffer)
Definition: window.c:2666
ULONG_PTR NTAPI NtUserSetClassLong(HWND hWnd, INT Offset, ULONG_PTR dwNewLong, BOOL Ansi)
Definition: class.c:2586
RTL_ATOM NTAPI NtUserRegisterClassExWOW(WNDCLASSEXW *lpwcx, PUNICODE_STRING pustrClassName, PUNICODE_STRING pustrCVersion, PCLSMENUNAME pClassMenuName, DWORD fnID, DWORD Flags, LPDWORD pWow)
Definition: class.c:2424
HWND NTAPI NtUserFindWindowEx(HWND hwndParent, HWND hwndChildAfter, PUNICODE_STRING ucClassName, PUNICODE_STRING ucWindowName, DWORD dwUnknown)
Definition: window.c:3143
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define TEST(x)
Definition: precomp.h:20
static HINSTANCE hinst
Definition: edit.c:551
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
#define WS_CAPTION
Definition: pedump.c:624
#define DefWindowProc
Definition: ros2win.h:31
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
PUNICODE_STRING pusMenuName
Definition: ntuser.h:500
LPSTR pszClientAnsiMenuName
Definition: ntuser.h:498
LPWSTR pwszClientUnicodeMenuName
Definition: ntuser.h:499
LPCWSTR lpszClassName
Definition: winuser.h:3226
LPCWSTR lpszMenuName
Definition: winuser.h:3225
HBRUSH hbrBackground
Definition: winuser.h:3224
WNDPROC lpfnWndProc
Definition: winuser.h:3218
UINT cbSize
Definition: winuser.h:3216
int cbWndExtra
Definition: winuser.h:3220
HCURSOR hCursor
Definition: winuser.h:3223
HICON hIconSm
Definition: winuser.h:3227
HINSTANCE hInstance
Definition: winuser.h:3221
UINT style
Definition: winuser.h:3217
int cbClsExtra
Definition: winuser.h:3219
HICON hIcon
Definition: winuser.h:3222
#define GWLP_WNDPROC
Definition: treelist.c:66
uint16_t * PWSTR
Definition: typedefs.h:56
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GetModuleHandle
Definition: winbase.h:3827
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
#define GetWindowLongPtrW
Definition: winuser.h:4829
#define GetClassLong
Definition: winuser.h:5781
#define CW_USEDEFAULT
Definition: winuser.h:225
struct _WNDCLASSEXW WNDCLASSEXW
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2906
#define WS_EX_OVERLAPPEDWINDOW
Definition: winuser.h:398
BOOL WINAPI DestroyWindow(_In_ HWND)
#define GCW_ATOM
Definition: winuser.h:661
__wchar_t WCHAR
Definition: xmlstorage.h:180