reactos/modules/rostests/apitests/win32nt/ntuser/NtUserCreateWindowEx.c

256 lines
9.1 KiB
C

/*
* PROJECT: ReactOS api tests
* LICENSE: GPL - See COPYING in the top level directory
* PURPOSE: Test for NtUserCreateWindowEx
*/
#include <win32nt.h>
static
inline
HWND
CreateWnd(HINSTANCE hinst,
PLARGE_STRING clsName,
PLARGE_STRING clsVer,
PLARGE_STRING wndName)
{
return NtUserCreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
clsName,
clsVer,
wndName,
WS_CAPTION,
CW_USEDEFAULT,
CW_USEDEFAULT,
100,
100,
NULL,
NULL,
hinst,
0,
0,
NULL);
}
/* WndProc for class1 */
LRESULT CALLBACK wndProc1(HWND hwnd, UINT msg, WPARAM wPrm, LPARAM lPrm)
{
return DefWindowProc(hwnd, msg, wPrm, lPrm);
}
/* WndProc for class2 */
LRESULT CALLBACK wndProc2(HWND hwnd, UINT msg, WPARAM wPrm, LPARAM lPrm)
{
return DefWindowProc(hwnd, msg, wPrm, lPrm);
}
START_TEST(NtUserCreateWindowEx)
{
HINSTANCE hinst = GetModuleHandle(NULL);
WNDCLASSEXW wclex = {0};
WNDCLASSEXW wclex2 = {0};
WNDCLASSEXW res = {0};
/* Unicode strings for NtRegisterClassExWOW */
UNICODE_STRING cls = {14, 32, L"MyClass"};
UNICODE_STRING ver_cls = {12, 32, L"v2test"};
UNICODE_STRING another_cls = {10, 32, L"Dummy"};
UNICODE_STRING menu = {10, 10, L"MuMnu"};
UNICODE_STRING null_cls = {2, 2, L""};
/* LARGE_STRING for NtUserCreateWindowEx */
LARGE_STRING l_dummy = {14, 32, 0, L"DummyMe"};
LARGE_STRING l_empty = {0, 0, 0, L""};
LARGE_STRING l_wndName = {32, 32, 0, L""};
LARGE_STRING l_cls = {cls.Length, 32, 0, cls.Buffer};
LARGE_STRING l_ver_cls = {ver_cls.Length, 32, 0, ver_cls.Buffer};
WCHAR bufMe[255] = {0};
UNICODE_STRING capture = {255, 255, bufMe};
PWSTR pwstr = NULL;
CLSMENUNAME clsMenuName, outClsMnu = {0};
ATOM atom, atom2, atom3;
HWND hwnd;
clsMenuName.pszClientAnsiMenuName = "MuMnu";
clsMenuName.pwszClientUnicodeMenuName = menu.Buffer;
clsMenuName.pusMenuName = &menu;
wclex.cbSize = sizeof(WNDCLASSEXW);
wclex.style = 0;
wclex.lpfnWndProc = wndProc1;
wclex.cbClsExtra = 2;
wclex.cbWndExtra = 4;
wclex.hInstance = hinst;
wclex.hIcon = NULL;
wclex.hCursor = NULL;
wclex.hbrBackground = CreateSolidBrush(RGB(4,7,5));
wclex.lpszMenuName = menu.Buffer;
wclex.lpszClassName = cls.Buffer;
wclex.hIconSm = NULL;
memcpy(&wclex2, &wclex, sizeof(wclex));
wclex2.lpfnWndProc = wndProc2;
/* Register our first version */
atom = NtUserRegisterClassExWOW(&wclex, /* wndClass */
&cls, /* ClassName */
&cls, /* Version */
&clsMenuName, /* MenuName */
0,
0,
NULL);
TEST(atom != 0);
/* Register second version */
atom2 = NtUserRegisterClassExWOW(&wclex2, /* wndClass */
&cls, /* ClassName */
&ver_cls, /* Version */
&clsMenuName, /* MenuName */
0,
0,
NULL);
atom3 = NtUserRegisterClassExWOW(&wclex2, /* wndClass */
&another_cls, /* ClassName */
&another_cls, /* Version */
&clsMenuName, /* MenuName */
0,
0,
NULL);
TEST(NtUserRegisterClassExWOW(&wclex2, /* wndClass */
&cls, /* ClassName */
NULL, /* Version */
&clsMenuName, /* MenuName */
0,
0,
NULL) == 0);
TEST(NtUserRegisterClassExWOW(&wclex2, /* wndClass */
&cls, /* ClassName */
&null_cls, /* Version */
&clsMenuName, /* MenuName */
0,
0,
NULL) == 0);
TEST(NtUserGetWOWClass(hinst, &ver_cls) != 0);
TEST(NtUserGetWOWClass(hinst, &ver_cls) != NtUserGetWOWClass(hinst, &cls)); TEST(atom2 != 0);
TEST(atom == atom2 && (atom | atom2) != 0);
/* Create a window without versioned class */
TEST(CreateWnd(hinst, &l_cls, NULL, &l_wndName) == 0);
TEST(CreateWnd(hinst, &l_cls, &l_wndName, &l_wndName) == 0);
/* Now, create our first window */
hwnd = CreateWnd(hinst, &l_cls, &l_cls, &l_wndName);
TEST(hwnd != 0);
if(hwnd)
{
/* Test some settings about the window */
TEST((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == wndProc1);
/* Check class name isn't versioned */
TEST(NtUserGetClassName(hwnd, TRUE, &capture) != 0);
TEST(wcscmp(capture.Buffer, cls.Buffer) == 0);
TEST(wcscmp(capture.Buffer, ver_cls.Buffer) != 0);
ZeroMemory(capture.Buffer, 255);
/* Check what return GetClassLong */
TEST(GetClassLong(hwnd, GCW_ATOM) == atom);
TEST(NtUserSetClassLong(hwnd, GCW_ATOM, atom3, FALSE) == atom);
NtUserGetClassName(hwnd, TRUE, &capture);
TEST(wcscmp(capture.Buffer, another_cls.Buffer) == 0);
/* Finally destroy it */
DestroyWindow(hwnd);
}
/* Create our second version */
hwnd = CreateWnd(hinst, &l_cls, &l_ver_cls, &l_wndName);
TEST(hwnd != 0);
if (hwnd)
{
/* Test settings about window */
TEST((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == wndProc2);
/* Check class name isn't versioned */
TEST(NtUserGetClassName(hwnd, TRUE, &capture) != 0);
TEST(wcscmp(capture.Buffer, cls.Buffer) == 0);
TEST(wcscmp(capture.Buffer, ver_cls.Buffer) != 0);
ZeroMemory(capture.Buffer, 255);
/* Check what return GetClassLong */
TEST(GetClassLong(hwnd, GCW_ATOM) == atom);
TEST(NtUserFindWindowEx(NULL, NULL, &cls, (UNICODE_STRING*)&l_empty, 0) == hwnd);
/* Finally destroy it */
DestroyWindow(hwnd);
}
/* Create a nonexistent window */
hwnd = CreateWnd(hinst, &l_cls, &l_dummy, &l_wndName);
TEST(hwnd == 0);
if (hwnd) DestroyWindow(hwnd);
/* Get non-versioned class info */
res.cbSize = sizeof(res);
SetLastError(0);
TEST(NtUserGetClassInfo(hinst, &cls, &res, &pwstr, 0) != 0);
TEST(GetLastError() == 0);
TEST(res.cbSize == wclex.cbSize);
TEST(res.style == wclex.style);
TEST(res.lpfnWndProc == wclex.lpfnWndProc);
TEST(res.cbClsExtra == wclex.cbClsExtra);
TEST(res.cbWndExtra == wclex.cbWndExtra);
TEST(res.hInstance == wclex.hInstance);
TEST(res.hIcon == wclex.hIcon);
TEST(res.hCursor == wclex.hCursor);
TEST(res.hbrBackground == wclex.hbrBackground);
TEST(res.lpszMenuName == 0);
TEST(res.lpszClassName == 0);
TEST(res.hIconSm == wclex.hIconSm);
/* Get versioned class info */
TEST(NtUserGetClassInfo(hinst, &ver_cls, &res, &pwstr, 0) == atom2);
TEST(GetLastError() == 0);
TEST(res.cbSize == wclex2.cbSize);
TEST(res.style == wclex2.style);
TEST(res.lpfnWndProc == wclex2.lpfnWndProc);
TEST(res.cbClsExtra == wclex2.cbClsExtra);
TEST(res.cbWndExtra == wclex2.cbWndExtra);
TEST(res.hInstance == wclex2.hInstance);
TEST(res.hIcon == wclex2.hIcon);
TEST(res.hCursor == wclex2.hCursor);
TEST(res.hbrBackground == wclex2.hbrBackground);
TEST(res.lpszMenuName == 0);
TEST(res.lpszClassName == 0);
TEST(res.hIconSm == wclex2.hIconSm);
/* Create a new window from our old class. Since we set a new class atom,
* it should be set to our new atom
*/
hwnd = NULL;
hwnd = CreateWnd(hinst, &l_cls, &l_cls, &l_wndName);
TEST(hwnd != NULL);
if (hwnd)
{
TEST(GetClassLong(hwnd, GCW_ATOM) == atom3);
TEST(NtUserGetClassName(hwnd, TRUE, &capture) != 0);
TEST(wcscmp(capture.Buffer, another_cls.Buffer) == 0);
DestroyWindow(hwnd);
}
/* Test class destruction */
TEST(NtUserUnregisterClass(&cls, hinst, (PCLSMENUNAME)0xbad) != 0);
TEST(NtUserUnregisterClass(&ver_cls, hinst, &outClsMnu) != 0);
TEST(NtUserUnregisterClass(&another_cls, hinst, &outClsMnu) != 0);
TEST(NtUserUnregisterClass(&menu, hinst, &outClsMnu) == 0);
/* Make sure that the classes got destroyed */
TEST(NtUserGetWOWClass(hinst, &cls) == 0);
TEST(NtUserGetWOWClass(hinst, &ver_cls) == 0);
TEST(NtUserGetWOWClass(hinst, &another_cls) == 0);
}