2015-02-24 23:15:08 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS api tests
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* PURPOSE: Test for GetDCEx
|
|
|
|
* PROGRAMMERS: Timo Kreuzer
|
|
|
|
*/
|
|
|
|
|
2017-12-02 20:17:22 +00:00
|
|
|
#include "precomp.h"
|
2015-02-24 23:15:08 +00:00
|
|
|
|
|
|
|
#define DCX_USESTYLE 0x00010000
|
|
|
|
|
|
|
|
void Test_GetDCEx_Params()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
LRESULT
|
|
|
|
CALLBACK
|
|
|
|
WndProc(
|
|
|
|
_In_ HWND hwnd,
|
|
|
|
_In_ UINT uMsg,
|
|
|
|
_In_ WPARAM wParam,
|
|
|
|
_In_ LPARAM lParam)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
ATOM
|
|
|
|
RegisterClassHelper(
|
|
|
|
PSTR pszClassName,
|
|
|
|
UINT style,
|
|
|
|
WNDPROC pfnWndProc)
|
|
|
|
{
|
|
|
|
WNDCLASSA cls;
|
|
|
|
|
|
|
|
cls.style = style;
|
|
|
|
cls.lpfnWndProc = pfnWndProc;
|
|
|
|
cls.cbClsExtra = 0;
|
|
|
|
cls.cbWndExtra = 0;
|
|
|
|
cls.hInstance = GetModuleHandleA(0);
|
|
|
|
cls.hIcon = 0;
|
|
|
|
cls.hCursor = LoadCursorA(0, IDC_ARROW);
|
|
|
|
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
|
|
|
|
cls.lpszMenuName = NULL;
|
|
|
|
cls.lpszClassName = pszClassName;
|
|
|
|
|
|
|
|
return RegisterClassA(&cls);
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
HWND
|
|
|
|
CreateWindowHelper(
|
|
|
|
PSZ pszClassName,
|
|
|
|
PSZ pszTitle)
|
|
|
|
{
|
|
|
|
return CreateWindowA(pszClassName,
|
|
|
|
pszTitle,
|
|
|
|
WS_OVERLAPPEDWINDOW,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
100,
|
|
|
|
100,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void
|
|
|
|
Test_GetDCEx_Cached()
|
|
|
|
{
|
|
|
|
static const PSTR pszClassName = "TestClass_Cached";
|
|
|
|
ATOM atomClass;
|
|
|
|
HWND hwnd;
|
|
|
|
HDC hdc1, hdc2;
|
|
|
|
HRGN hrgn;
|
|
|
|
|
|
|
|
atomClass = RegisterClassHelper(pszClassName, 0, WndProc);
|
|
|
|
ok(atomClass != 0, "Failed to register class\n");
|
|
|
|
|
|
|
|
hwnd = CreateWindowHelper(pszClassName, "Test Window1");
|
|
|
|
ok(hwnd != NULL, "Failed to create hwnd\n");
|
|
|
|
|
|
|
|
hdc1 = GetDCEx(hwnd, 0, 0);
|
|
|
|
ok(hdc1 == NULL, "GetDCEx should fail\n");
|
|
|
|
hrgn = CreateRectRgn(0, 0, 100, 100);
|
|
|
|
hdc1 = GetDCEx(hwnd, hrgn, 0);
|
|
|
|
ok(hdc1 == NULL, "GetDCEx should fail\n");
|
|
|
|
|
|
|
|
hdc1 = GetDCEx(hwnd, 0, DCX_WINDOW);
|
|
|
|
ok(hdc1 == NULL, "GetDCEx should fail\n");
|
|
|
|
hdc1 = GetDCEx(hwnd, hrgn, DCX_WINDOW);
|
|
|
|
ok(hdc1 == NULL, "GetDCEx should fail\n");
|
|
|
|
|
|
|
|
hdc1 = GetDCEx(hwnd, hrgn, DCX_INTERSECTRGN);
|
|
|
|
ok(hdc1 == NULL, "GetDCEx should fail\n");
|
|
|
|
|
|
|
|
hdc1 = GetDCEx(hwnd, hrgn, DCX_PARENTCLIP);
|
|
|
|
ok(hdc1 != NULL, "GetDCEx failed\n");
|
|
|
|
ReleaseDC(hwnd, hdc1);
|
|
|
|
|
|
|
|
hdc1 = GetDCEx(hwnd, hrgn, DCX_WINDOW | DCX_INTERSECTRGN | DCX_PARENTCLIP);
|
|
|
|
ok(hdc1 != NULL, "GetDCEx failed\n");
|
|
|
|
ReleaseDC(hwnd, hdc1);
|
|
|
|
|
|
|
|
hdc1 = GetDCEx(hwnd, 0, DCX_CACHE);
|
|
|
|
ok(hdc1 != NULL, "GetDCEx failed\n");
|
|
|
|
ReleaseDC(hwnd, hdc1);
|
|
|
|
|
|
|
|
hrgn = CreateRectRgn(0, 0, 100, 100);
|
|
|
|
hdc2 = GetDCEx(hwnd, hrgn, DCX_CACHE);
|
|
|
|
ok(hdc2 != NULL, "GetDCEx failed\n");
|
|
|
|
ReleaseDC(hwnd, hdc2);
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC\n");
|
|
|
|
|
|
|
|
hdc1 = GetDCEx(hwnd, 0, DCX_CACHE);
|
|
|
|
hdc2 = GetDCEx(hwnd, hrgn, DCX_CACHE);
|
|
|
|
ok(hdc1 != NULL, "GetDCEx failed\n");
|
|
|
|
ok(hdc2 != hdc1, "Expected a different DC\n");
|
|
|
|
ReleaseDC(hwnd, hdc1);
|
|
|
|
ReleaseDC(hwnd, hdc2);
|
|
|
|
|
|
|
|
hdc1 = GetDCEx(NULL, NULL, 0);
|
|
|
|
ok(hdc1 != NULL, "GetDCEx failed\n");
|
|
|
|
hdc2 = GetDCEx(NULL, NULL, 0);
|
|
|
|
ok(hdc2 != NULL, "GetDCEx failed\n");
|
|
|
|
ok(hdc2 != hdc1, "Expected a different DC\n");
|
|
|
|
ReleaseDC(hwnd, hdc1);
|
|
|
|
ReleaseDC(hwnd, hdc2);
|
|
|
|
|
|
|
|
ok(CombineRgn(hrgn, hrgn, hrgn, RGN_OR) == SIMPLEREGION, "region is not valid");
|
|
|
|
|
|
|
|
DestroyWindow(hwnd);
|
|
|
|
ok(UnregisterClass(pszClassName, GetModuleHandleA(0)) == TRUE,
|
|
|
|
"UnregisterClass failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void
|
|
|
|
Test_GetDCEx_CS_OWNDC()
|
|
|
|
{
|
|
|
|
static const PSTR pszClassName = "TestClass_CS_OWNDC";
|
|
|
|
ATOM atomClass;
|
|
|
|
HWND hwnd;
|
|
|
|
HDC hdc1, hdc2;
|
|
|
|
//HRGN hrgn;
|
|
|
|
|
|
|
|
atomClass = RegisterClassHelper(pszClassName, CS_OWNDC, WndProc);
|
|
|
|
ok(atomClass != 0, "Failed to register class\n");
|
|
|
|
|
|
|
|
hwnd = CreateWindowHelper(pszClassName, "Test Window1");
|
|
|
|
ok(hwnd != NULL, "Failed to create hwnd\n");
|
|
|
|
|
|
|
|
hdc1 = GetDCEx(hwnd, NULL, 0);
|
|
|
|
ok(hdc1 != NULL, "GetDCEx failed\n");
|
|
|
|
hdc2 = GetDCEx(hwnd, NULL, 0);
|
|
|
|
ok(hdc2 != NULL, "GetDCEx failed\n");
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC\n");
|
|
|
|
ok(ReleaseDC(hwnd, hdc1) == TRUE, "ReleaseDC failed\n");
|
|
|
|
ok(ReleaseDC(hwnd, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
hdc2 = GetDCEx(hwnd, NULL, 0);
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC\n");
|
|
|
|
ok(ReleaseDC(hwnd, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
hdc2 = GetDCEx(hwnd, NULL, DCX_CACHE);
|
|
|
|
ok(hdc2 != hdc1, "Expected a different DC\n");
|
|
|
|
ok(ReleaseDC(hwnd, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
hdc2 = GetDCEx(hwnd, NULL, DCX_WINDOW);
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC\n");
|
|
|
|
ok(ReleaseDC(hwnd, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Try after resetting CS_OWNDC in the class */
|
|
|
|
ok(SetClassLongPtrA(hwnd, GCL_STYLE, 0) == CS_OWNDC, "class style wrong\n");
|
|
|
|
hdc2 = GetDCEx(hwnd, NULL, 0);
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC, got %p\n", hdc2);
|
|
|
|
ok(ReleaseDC(hwnd, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Try after setting CS_CLASSDC in the class */
|
|
|
|
ok(SetClassLongPtrA(hwnd, GCL_STYLE, CS_CLASSDC) == 0, "class style not set\n");
|
|
|
|
hdc2 = GetDCEx(hwnd, NULL, 0);
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC, got %p\n", hdc2);
|
|
|
|
ok(ReleaseDC(hwnd, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* CS_OWNDC and CS_CLASSDC? Is that even legal? */
|
|
|
|
ok(SetClassLongPtrA(hwnd, GCL_STYLE, (CS_OWNDC | CS_CLASSDC)) == CS_CLASSDC, "class style not set\n");
|
|
|
|
hdc2 = GetDCEx(hwnd, NULL, 0);
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC, got %p\n", hdc2);
|
|
|
|
ok(ReleaseDC(hwnd, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
SetClassLongPtrA(hwnd, GCL_STYLE, CS_OWNDC);
|
|
|
|
|
|
|
|
DestroyWindow(hwnd);
|
|
|
|
ok(UnregisterClass(pszClassName, GetModuleHandleA(0)) == TRUE,
|
|
|
|
"UnregisterClass failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void
|
|
|
|
Test_GetDCEx_CS_CLASSDC()
|
|
|
|
{
|
|
|
|
static const PSTR pszClassName = "TestClass_CS_CLASSDC";
|
|
|
|
ATOM atomClass;
|
|
|
|
HWND hwnd1, hwnd2;
|
|
|
|
HDC hdc1, hdc2;
|
|
|
|
//HRGN hrgn;
|
|
|
|
|
|
|
|
atomClass = RegisterClassHelper(pszClassName, CS_CLASSDC, WndProc);
|
|
|
|
ok(atomClass != 0, "Failed to register class\n");
|
|
|
|
|
|
|
|
hwnd1 = CreateWindowHelper(pszClassName, "Test Window1");
|
|
|
|
ok(hwnd1 != NULL, "Failed to create hwnd1\n");
|
|
|
|
|
|
|
|
/* Looks legit, but this is not the DC you are looking for!
|
|
|
|
In fact this is NOT the class dc, but an own DC, doh!
|
|
|
|
When the first Window is created, the DC for that Window is both it's own
|
|
|
|
AND the class DC. But we only get the class DC, when using DCX_USESTYLE */
|
|
|
|
hdc1 = GetDCEx(hwnd1, NULL, 0);
|
|
|
|
ok(hdc1 != NULL, "GetDCEx failed\n");
|
|
|
|
hdc2 = GetDCEx(hwnd1, NULL, 0);
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC, got %p\n", hdc2);
|
|
|
|
ok(ReleaseDC(hwnd1, hdc1) == TRUE, "ReleaseDC failed\n");
|
|
|
|
ok(ReleaseDC(hwnd1, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Now with DCX_USESTYLE */
|
|
|
|
hdc2 = GetDCEx(hwnd1, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC, got %p\n", hdc2);
|
|
|
|
ok(ReleaseDC(hwnd1, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
hwnd2 = CreateWindowHelper(pszClassName, "Test Window2");
|
|
|
|
ok(hwnd2 != NULL, "Failed to create hwnd2\n");
|
|
|
|
|
|
|
|
/* Yeah, this doesn't work anymore. Once the */
|
|
|
|
hdc2 = GetDCEx(hwnd2, NULL, 0);
|
|
|
|
ok(hdc2 == NULL, "Expected failure\n");
|
|
|
|
|
|
|
|
/* Now with DCX_USESTYLE ... */
|
|
|
|
hdc2 = GetDCEx(hwnd2, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc2 == hdc1, "Expected the same DC, got %p\n", hdc2);
|
|
|
|
ok(ReleaseDC(hwnd2, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
SendMessage(hwnd2, WM_USER, 0, 0);
|
|
|
|
|
|
|
|
DestroyWindow(hwnd1);
|
|
|
|
DestroyWindow(hwnd2);
|
|
|
|
ok(UnregisterClass(pszClassName, GetModuleHandleA(0)) == TRUE,
|
|
|
|
"UnregisterClass failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void
|
|
|
|
Test_GetDCEx_CS_Mixed()
|
|
|
|
{
|
|
|
|
static const PSTR pszClassName = "TestClass_CS_Mixed";
|
|
|
|
ATOM atomClass;
|
|
|
|
HWND hwnd1,hwnd2, hwnd3;
|
|
|
|
HDC hdc1, hdc2, hdc3;
|
|
|
|
|
|
|
|
/* Register a class with CS_OWNDC *and* CS_CLASSDC */
|
|
|
|
atomClass = RegisterClassHelper(pszClassName, CS_OWNDC | CS_CLASSDC, WndProc);
|
|
|
|
ok(atomClass != 0, "Failed to register class\n");
|
|
|
|
|
|
|
|
/* Create the first window, this should create a single own and class DC */
|
|
|
|
hwnd1 = CreateWindowHelper(pszClassName, "Test Window1");
|
|
|
|
ok(hwnd1 != NULL, "Failed to create hwnd1\n");
|
|
|
|
|
|
|
|
/* Verify that we have the right style */
|
|
|
|
ok(GetClassLongPtrA(hwnd1, GCL_STYLE) == (CS_OWNDC | CS_CLASSDC),
|
|
|
|
"class style not set\n");
|
|
|
|
|
|
|
|
/* This is now the class DC and the first windows own DC */
|
|
|
|
hdc1 = GetDCEx(hwnd1, NULL, 0);
|
|
|
|
ok(hdc1 != NULL, "GetDCEx failed\n");
|
|
|
|
ok(ReleaseDC(hwnd1, hdc1) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* This should get us the own/class DC again */
|
|
|
|
hdc2 = GetDCEx(hwnd1, NULL, 0);
|
|
|
|
ok(hdc2 == hdc1, "Expected the own/class DC, got %p\n", hdc2);
|
|
|
|
ok(ReleaseDC(hwnd1, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* This should get us the class DC, but it's the same */
|
|
|
|
hdc2 = GetDCEx(hwnd1, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc2 == hdc1, "Expected the own/class DC, got %p\n", hdc2);
|
|
|
|
ok(ReleaseDC(hwnd1, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Create a second window */
|
|
|
|
hwnd2 = CreateWindowHelper(pszClassName, "Test Window1");
|
|
|
|
ok(hwnd1 != NULL, "Failed to create hwnd1\n");
|
|
|
|
|
|
|
|
/* This should get us the own DC of the new window */
|
|
|
|
hdc2 = GetDCEx(hwnd2, NULL, 0);
|
|
|
|
ok(hdc2 != NULL, "GetDCEx failed\n");
|
|
|
|
ok(hdc2 != hdc1, "Expected different DC\n");
|
|
|
|
ok(ReleaseDC(hwnd2, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* This gets us the own DC again, CS_OWNDC has priority! */
|
|
|
|
hdc3 = GetDCEx(hwnd2, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc3 == hdc2, "Expected the own DC, got %p\n", hdc3);
|
|
|
|
ok(ReleaseDC(hwnd2, hdc3) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Disable CS_OWNDC */
|
|
|
|
ok(SetClassLongPtrA(hwnd1, GCL_STYLE, CS_CLASSDC) == (CS_OWNDC | CS_CLASSDC), "unexpected style\n");
|
|
|
|
ok(GetClassLongPtrA(hwnd1, GCL_STYLE) == CS_CLASSDC, "class style not set\n");
|
|
|
|
|
|
|
|
/* Since the window already has an own DC, we get it again! */
|
|
|
|
hdc3 = GetDCEx(hwnd2, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc3 == hdc2, "Expected the own DC, got %p\n", hdc3);
|
|
|
|
ok(ReleaseDC(hwnd2, hdc3) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Disable CS_CLASSDC, too */
|
|
|
|
ok(SetClassLongPtrA(hwnd1, GCL_STYLE, 0) == CS_CLASSDC, "unexpected style\n");
|
|
|
|
ok(GetClassLongPtrA(hwnd1, GCL_STYLE) == 0, "class style not set\n");
|
|
|
|
|
|
|
|
/* With DCX_USESTYLE we only get a cached DC */
|
|
|
|
hdc3 = GetDCEx(hwnd2, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc3 != NULL, "GetDCEx failed\n");
|
|
|
|
ok(hdc3 != hdc1, "Expected different DC, got class DC\n");
|
|
|
|
ok(hdc3 != hdc2, "Expected different DC, got own DC\n");
|
|
|
|
ok(ReleaseDC(hwnd2, hdc3) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Without DCX_USESTYLE we get the own DC */
|
|
|
|
hdc3 = GetDCEx(hwnd2, NULL, 0);
|
|
|
|
ok(hdc3 != NULL, "GetDCEx failed\n");
|
|
|
|
ok(hdc3 != hdc1, "Expected different DC, got class DC\n");
|
|
|
|
ok(hdc3 == hdc2, "Expected the own DC, got %p\n", hdc3);
|
|
|
|
ok(ReleaseDC(hwnd2, hdc3) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Set only CS_OWNDC */
|
|
|
|
ok(SetClassLongPtrA(hwnd1, GCL_STYLE, CS_OWNDC) == 0, "unexpected style\n");
|
|
|
|
ok(GetClassLongPtrA(hwnd1, GCL_STYLE) == CS_OWNDC, "class style not set\n");
|
|
|
|
|
|
|
|
hwnd3 = CreateWindowHelper(pszClassName, "Test Window1");
|
|
|
|
ok(hwnd3 != NULL, "Failed to create hwnd1\n");
|
|
|
|
|
|
|
|
/* This should get a new own DC */
|
|
|
|
hdc2 = GetDCEx(hwnd3, NULL, 0);
|
|
|
|
ok(hdc2 != hdc1, "Expected different DC\n");
|
|
|
|
ok(ReleaseDC(hwnd3, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Re-enable CS_CLASSDC */
|
|
|
|
ok(SetClassLongPtrA(hwnd1, GCL_STYLE, (CS_OWNDC | CS_CLASSDC)) == CS_OWNDC, "unexpected style\n");
|
|
|
|
ok(GetClassLongPtrA(hwnd1, GCL_STYLE) == (CS_OWNDC | CS_CLASSDC), "class style not set\n");
|
|
|
|
|
|
|
|
/* This should get us the own DC */
|
|
|
|
hdc3 = GetDCEx(hwnd3, NULL, 0);
|
|
|
|
ok(hdc3 == hdc2, "Expected the same DC, got %p\n", hdc3);
|
|
|
|
ok(ReleaseDC(hwnd3, hdc3) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* This should still get us the new own DC */
|
|
|
|
hdc3 = GetDCEx(hwnd3, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc3 == hdc2, "Expected the same DC, got %p\n", hdc3);
|
|
|
|
ok(ReleaseDC(hwnd3, hdc3) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Disable CS_OWNDC */
|
|
|
|
ok(SetClassLongPtrA(hwnd1, GCL_STYLE, CS_CLASSDC) == (CS_OWNDC | CS_CLASSDC), "unexpected style\n");
|
|
|
|
ok(GetClassLongPtrA(hwnd1, GCL_STYLE) == CS_CLASSDC, "class style not set\n");
|
|
|
|
|
|
|
|
/* This should get us the own DC */
|
|
|
|
hdc3 = GetDCEx(hwnd3, NULL, 0);
|
|
|
|
ok(hdc3 == hdc2, "Expected the same DC, got %p\n", hdc3);
|
|
|
|
ok(ReleaseDC(hwnd3, hdc3) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* This should still get us the new own DC */
|
|
|
|
hdc3 = GetDCEx(hwnd3, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc3 == hdc2, "Expected the same DC, got %p\n", hdc3);
|
|
|
|
ok(ReleaseDC(hwnd3, hdc3) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* cleanup for a second run */
|
|
|
|
DestroyWindow(hwnd1);
|
|
|
|
DestroyWindow(hwnd2);
|
|
|
|
DestroyWindow(hwnd3);
|
|
|
|
ok(UnregisterClass(pszClassName, GetModuleHandleA(0)) == TRUE,
|
|
|
|
"UnregisterClass failed\n");
|
|
|
|
|
|
|
|
/* Create class again with CS_OWNDC */
|
|
|
|
atomClass = RegisterClassHelper(pszClassName, CS_OWNDC, WndProc);
|
|
|
|
ok(atomClass != 0, "Failed to register class\n");
|
|
|
|
|
|
|
|
hwnd1 = CreateWindowHelper(pszClassName, "Test Window1");
|
|
|
|
ok(hwnd1 != NULL, "Failed to create hwnd1\n");
|
|
|
|
|
|
|
|
/* This is the windows own DC, the class does not have a class DC yet */
|
|
|
|
hdc1 = GetDCEx(hwnd1, NULL, 0);
|
|
|
|
ok(hdc1 != NULL, "GetDCEx failed\n");
|
|
|
|
ok(ReleaseDC(hwnd1, hdc1) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Enable only CS_CLASSDC */
|
|
|
|
ok(SetClassLongPtrA(hwnd1, GCL_STYLE, CS_CLASSDC) == CS_OWNDC, "unexpected style\n");
|
|
|
|
ok(GetClassLongPtrA(hwnd1, GCL_STYLE) == CS_CLASSDC, "class style not set\n");
|
|
|
|
|
|
|
|
/* Create a second window. Now we should create a class DC! */
|
|
|
|
hwnd2 = CreateWindowHelper(pszClassName, "Test Window2");
|
|
|
|
ok(hwnd2 != NULL, "Failed to create hwnd1\n");
|
|
|
|
|
|
|
|
/* We expect a new DCE (the class DCE) */
|
|
|
|
hdc2 = GetDCEx(hwnd2, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc2 != NULL, "GetDCEx failed\n");
|
|
|
|
ok(hdc2 != hdc1, "Expected different DCs\n");
|
|
|
|
ok(ReleaseDC(hwnd2, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
DestroyWindow(hwnd1);
|
|
|
|
DestroyWindow(hwnd2);
|
|
|
|
ok(UnregisterClass(pszClassName, GetModuleHandleA(0)) == TRUE,
|
|
|
|
"UnregisterClass failed\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void
|
|
|
|
Test_GetDCEx_CS_SwitchedStyle()
|
|
|
|
{
|
|
|
|
static const PSTR pszClassName = "TestClass_CS_SwitchedStyle";
|
|
|
|
ATOM atomClass;
|
|
|
|
HWND hwnd1, hwnd2;
|
2019-12-09 16:16:02 +00:00
|
|
|
HDC hdc1, hdc2, hdcClass;
|
2015-02-24 23:15:08 +00:00
|
|
|
|
2019-12-09 16:16:02 +00:00
|
|
|
/* Create a class with CS_CLASSDC */
|
|
|
|
atomClass = RegisterClassHelper(pszClassName, CS_CLASSDC, WndProc);
|
2015-02-24 23:15:08 +00:00
|
|
|
ok(atomClass != 0, "Failed to register class\n");
|
|
|
|
|
2019-12-09 16:16:02 +00:00
|
|
|
/* Create the 2 windows */
|
2015-02-24 23:15:08 +00:00
|
|
|
hwnd1 = CreateWindowHelper(pszClassName, "Test Window1");
|
|
|
|
ok(hwnd1 != NULL, "Failed to create hwnd1\n");
|
|
|
|
hwnd2 = CreateWindowHelper(pszClassName, "Test Window2");
|
|
|
|
ok(hwnd2 != NULL, "Failed to create hwnd2\n");
|
|
|
|
|
2019-12-09 16:16:02 +00:00
|
|
|
/* Get the class DC from the Windows */
|
|
|
|
hdc1 = GetDCEx(hwnd1, NULL, DCX_USESTYLE);
|
|
|
|
hdc2 = GetDCEx(hwnd2, NULL, DCX_USESTYLE);
|
|
|
|
hdcClass = hdc1;
|
|
|
|
ok(hdc1 == hdc2, "Expected same DC\n");
|
|
|
|
ok(ReleaseDC(hwnd2, hdc2) == TRUE, "ReleaseDC failed\n");
|
|
|
|
|
|
|
|
/* Switch the class to CS_OWNDC */
|
|
|
|
ok(SetClassLongPtrA(hwnd1, GCL_STYLE, CS_OWNDC) == CS_CLASSDC, "unexpected style\n");
|
|
|
|
ok(GetClassLongPtrA(hwnd1, GCL_STYLE) == CS_OWNDC, "class style not set\n");
|
|
|
|
|
|
|
|
/* Release the DC and try to get another one, this should fail now */
|
|
|
|
ok(ReleaseDC(hwnd1, hdc1) == TRUE, "ReleaseDC failed\n");
|
|
|
|
hdc1 = GetDCEx(hwnd1, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc1 == NULL, "GetDCEx should fail\n");
|
|
|
|
|
|
|
|
/* Destroy the 1st window, this should move it's own DC to the cache,
|
|
|
|
but not the class DC, but they are the same, so... */
|
|
|
|
DestroyWindow(hwnd1);
|
|
|
|
|
|
|
|
/* Create another window, this time it should have it's own DC */
|
|
|
|
hwnd1 = CreateWindowHelper(pszClassName, "Test Window1");
|
|
|
|
ok(hwnd1 != NULL, "Failed to create hwnd1\n");
|
|
|
|
hdc1 = GetDCEx(hwnd1, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc1 != NULL, "GetDXEx failed\n");
|
|
|
|
ok(hdc1 != hdc2, "Should get different DC\n");
|
|
|
|
|
|
|
|
/* Switch the class back to CS_CLASSDC */
|
|
|
|
ok(SetClassLongPtrA(hwnd2, GCL_STYLE, CS_CLASSDC) == CS_OWNDC, "unexpected style\n");
|
|
|
|
ok(GetClassLongPtrA(hwnd2, GCL_STYLE) == CS_CLASSDC, "class style not set\n");
|
|
|
|
|
|
|
|
/* Get the 2nd window's DC, this should still be the class DC */
|
|
|
|
hdc2 = GetDCEx(hwnd2, NULL, DCX_USESTYLE);
|
|
|
|
ok(hdc2 != hdc1, "Expected different DC\n");
|
|
|
|
ok(hdc2 == hdcClass, "Expected class DC\n");
|
|
|
|
|
2015-02-24 23:15:08 +00:00
|
|
|
DestroyWindow(hwnd1);
|
|
|
|
DestroyWindow(hwnd2);
|
|
|
|
ok(UnregisterClass(pszClassName, GetModuleHandleA(0)) == TRUE,
|
|
|
|
"UnregisterClass failed\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
START_TEST(GetDCEx)
|
|
|
|
{
|
|
|
|
Test_GetDCEx_Params();
|
|
|
|
Test_GetDCEx_Cached();
|
|
|
|
Test_GetDCEx_CS_OWNDC();
|
|
|
|
Test_GetDCEx_CS_CLASSDC();
|
|
|
|
Test_GetDCEx_CS_Mixed();
|
|
|
|
Test_GetDCEx_CS_SwitchedStyle();
|
|
|
|
}
|