ReactOS  0.4.15-dev-506-ga3ec01c
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 
9 static
10 inline
11 HWND
13  PLARGE_STRING clsName,
14  PLARGE_STRING clsVer,
15  PLARGE_STRING wndName)
16 {
18  clsName,
19  clsVer,
20  wndName,
21  WS_CAPTION,
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 }
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:2426
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define TRUE
Definition: types.h:120
int cbWndExtra
Definition: winuser.h:3195
#define RGB(r, g, b)
Definition: precomp.h:62
LPSTR pszClientAnsiMenuName
Definition: ntuser.h:466
WORD ATOM
Definition: dimm.idl:113
uint16_t * PWSTR
Definition: typedefs.h:55
#define CALLBACK
Definition: compat.h:27
LPWSTR pwszClientUnicodeMenuName
Definition: ntuser.h:467
static HWND CreateWnd(HINSTANCE hinst, PLARGE_STRING clsName, PLARGE_STRING clsVer, PLARGE_STRING wndName)
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1648
HICON hIcon
Definition: winuser.h:3197
UINT_PTR WPARAM
Definition: windef.h:207
struct _WNDCLASSEXW WNDCLASSEXW
#define GetWindowLongPtrW
Definition: winuser.h:4804
BOOL WINAPI DestroyWindow(_In_ HWND)
#define GCW_ATOM
Definition: winuser.h:656
START_TEST(NtUserCreateWindowEx)
LPCWSTR lpszMenuName
Definition: winuser.h:3200
#define CW_USEDEFAULT
Definition: winuser.h:225
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
int cbClsExtra
Definition: winuser.h:3194
LRESULT CALLBACK wndProc1(HWND hwnd, UINT msg, WPARAM wPrm, LPARAM lPrm)
LRESULT CALLBACK wndProc2(HWND hwnd, UINT msg, WPARAM wPrm, LPARAM lPrm)
LPCWSTR lpszClassName
Definition: winuser.h:3201
#define DefWindowProc
Definition: ros2win.h:31
#define WS_CAPTION
Definition: pedump.c:624
PCLS NTAPI NtUserGetWOWClass(HINSTANCE hInstance, PUNICODE_STRING ClassName)
Definition: class.c:2882
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define TEST(x)
Definition: precomp.h:20
HBRUSH hbrBackground
Definition: winuser.h:3199
UINT cbSize
Definition: winuser.h:3191
ULONG_PTR NTAPI NtUserSetClassLong(HWND hWnd, INT Offset, ULONG_PTR dwNewLong, BOOL Ansi)
Definition: class.c:2575
#define SetLastError(x)
Definition: compat.h:418
HINSTANCE hInstance
Definition: winuser.h:3196
RTL_ATOM NTAPI NtUserRegisterClassExWOW(WNDCLASSEXW *lpwcx, PUNICODE_STRING pustrClassName, PUNICODE_STRING pustrCVersion, PCLSMENUNAME pClassMenuName, DWORD fnID, DWORD Flags, LPDWORD pWow)
Definition: class.c:2413
static const WCHAR L[]
Definition: oid.c:1250
HWND NTAPI NtUserFindWindowEx(HWND hwndParent, HWND hwndChildAfter, PUNICODE_STRING ucClassName, PUNICODE_STRING ucWindowName, DWORD dwUnknown)
Definition: window.c:2878
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HCURSOR hCursor
Definition: winuser.h:3198
UINT style
Definition: winuser.h:3192
WNDPROC lpfnWndProc
Definition: winuser.h:3193
#define GWLP_WNDPROC
Definition: treelist.c:66
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2881
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define WS_EX_OVERLAPPEDWINDOW
Definition: winuser.h:398
PUNICODE_STRING pusMenuName
Definition: ntuser.h:468
#define GetModuleHandle
Definition: winbase.h:3667
INT NTAPI NtUserGetClassName(HWND hWnd, BOOL Real, PUNICODE_STRING ClassName)
unsigned int UINT
Definition: ndis.h:50
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
BOOL NTAPI NtUserUnregisterClass(PUNICODE_STRING ClassNameOrAtom, HINSTANCE hInstance, PCLSMENUNAME pClassMenuName)
HICON hIconSm
Definition: winuser.h:3202
#define GetClassLong
Definition: winuser.h:5756
#define msg(x)
Definition: auth_time.c:54
GLuint res
Definition: glext.h:9613
static HINSTANCE hinst
Definition: edit.c:551
LONG_PTR LRESULT
Definition: windef.h:209
BOOL NTAPI NtUserGetClassInfo(HINSTANCE hInstance, PUNICODE_STRING ClassName, LPWNDCLASSEXW wcex, LPWSTR *ppszMenuName, BOOL Ansi)
Definition: class.c:2720