Dmitry Timoshkov : user32: DeleteDC() should allow to delete a DC returned by GetDC().
Alexandre Julliard
julliard at winehq.org
Wed Feb 24 10:21:35 CST 2010
Module: wine
Branch: master
Commit: d6cfc3223ef8861830237fe415667a5ba73231d2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d6cfc3223ef8861830237fe415667a5ba73231d2
Author: Dmitry Timoshkov <dmitry at codeweavers.com>
Date: Wed Feb 24 22:44:41 2010 +0800
user32: DeleteDC() should allow to delete a DC returned by GetDC().
---
dlls/gdi32/dc.c | 2 +-
dlls/gdi32/tests/dc.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++-
dlls/user32/painting.c | 3 +-
3 files changed, 154 insertions(+), 3 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index 2aeeec2..577c151 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -819,7 +819,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
if (dc->hookProc && !dc->hookProc( hdc, DCHC_DELETEDC, dc->dwHookData, 0 ))
{
release_dc_ptr( dc );
- return FALSE;
+ return TRUE;
}
while (dc->saveLevel)
diff --git a/dlls/gdi32/tests/dc.c b/dlls/gdi32/tests/dc.c
index 1efde38..43c2480 100644
--- a/dlls/gdi32/tests/dc.c
+++ b/dlls/gdi32/tests/dc.c
@@ -69,7 +69,7 @@ static void test_savedc_2(void)
assert(hrgn != 0);
hdc = GetDC(hwnd);
- ok(hdc != NULL, "CreateDC rets %p\n", hdc);
+ ok(hdc != NULL, "GetDC failed\n");
ret = GetClipBox(hdc, &rc_clip);
ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
@@ -328,6 +328,155 @@ static void test_DC_bitmap(void)
ReleaseDC( 0, hdc );
}
+static void test_DeleteDC(void)
+{
+ HWND hwnd;
+ HDC hdc, hdc_test;
+ WNDCLASSEX cls;
+ int ret;
+
+ /* window DC */
+ hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
+ 0, 0, 0, NULL);
+ ok(hwnd != 0, "CreateWindowExA failed\n");
+
+ hdc = GetDC(hwnd);
+ ok(hdc != 0, "GetDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = DeleteDC(hdc);
+ ok(ret, "DeleteDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(!ret, "GetObjectType should fail for a deleted DC\n");
+
+ hdc = GetWindowDC(hwnd);
+ ok(hdc != 0, "GetDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = DeleteDC(hdc);
+ ok(ret, "DeleteDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(!ret, "GetObjectType should fail for a deleted DC\n");
+
+ DestroyWindow(hwnd);
+
+ /* desktop window DC */
+ hwnd = GetDesktopWindow();
+ ok(hwnd != 0, "GetDesktopWindow failed\n");
+
+ hdc = GetDC(hwnd);
+ ok(hdc != 0, "GetDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = DeleteDC(hdc);
+ ok(ret, "DeleteDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(!ret, "GetObjectType should fail for a deleted DC\n");
+
+ hdc = GetWindowDC(hwnd);
+ ok(hdc != 0, "GetDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = DeleteDC(hdc);
+ ok(ret, "DeleteDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(!ret, "GetObjectType should fail for a deleted DC\n");
+
+ /* CS_CLASSDC */
+ memset(&cls, 0, sizeof(cls));
+ cls.cbSize = sizeof(cls);
+ cls.style = CS_CLASSDC;
+ cls.hInstance = GetModuleHandle(0);
+ cls.lpszClassName = "Wine class DC";
+ cls.lpfnWndProc = DefWindowProcA;
+ ret = RegisterClassExA(&cls);
+ ok(ret, "RegisterClassExA failed\n");
+
+ hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
+ 0, 0, 0, NULL);
+ ok(hwnd != 0, "CreateWindowExA failed\n");
+
+ hdc = GetDC(hwnd);
+ ok(hdc != 0, "GetDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = DeleteDC(hdc);
+ ok(ret, "DeleteDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = ReleaseDC(hwnd, hdc);
+ ok(ret, "ReleaseDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+
+ hdc_test = hdc;
+
+ hdc = GetWindowDC(hwnd);
+ ok(hdc != 0, "GetDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = DeleteDC(hdc);
+ ok(ret, "DeleteDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(!ret, "GetObjectType should fail for a deleted DC\n");
+
+ DestroyWindow(hwnd);
+
+ ret = GetObjectType(hdc_test);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+
+ ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
+ ok(ret, "UnregisterClassA failed\n");
+
+ ret = GetObjectType(hdc_test);
+todo_wine
+ ok(!ret, "GetObjectType should fail for a deleted DC\n");
+
+ /* CS_OWNDC */
+ memset(&cls, 0, sizeof(cls));
+ cls.cbSize = sizeof(cls);
+ cls.style = CS_OWNDC;
+ cls.hInstance = GetModuleHandle(0);
+ cls.lpszClassName = "Wine own DC";
+ cls.lpfnWndProc = DefWindowProcA;
+ ret = RegisterClassExA(&cls);
+ ok(ret, "RegisterClassExA failed\n");
+
+ hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
+ 0, 0, 0, NULL);
+ ok(hwnd != 0, "CreateWindowExA failed\n");
+
+ hdc = GetDC(hwnd);
+ ok(hdc != 0, "GetDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = DeleteDC(hdc);
+ ok(ret, "DeleteDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = ReleaseDC(hwnd, hdc);
+ ok(ret, "ReleaseDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+
+ hdc = GetWindowDC(hwnd);
+ ok(hdc != 0, "GetDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
+ ret = DeleteDC(hdc);
+ ok(ret, "DeleteDC failed\n");
+ ret = GetObjectType(hdc);
+ ok(!ret, "GetObjectType should fail for a deleted DC\n");
+
+ DestroyWindow(hwnd);
+
+ ret = GetObjectType(hdc_test);
+ ok(!ret, "GetObjectType should fail for a deleted DC\n");
+
+ ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
+ ok(ret, "UnregisterClassA failed\n");
+}
+
START_TEST(dc)
{
test_savedc();
@@ -335,4 +484,5 @@ START_TEST(dc)
test_GdiConvertToDevmodeW();
test_CreateCompatibleDC();
test_DC_bitmap();
+ test_DeleteDC();
}
diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c
index cde642c..732c889 100644
--- a/dlls/user32/painting.c
+++ b/dlls/user32/painting.c
@@ -296,6 +296,7 @@ static struct dce *get_window_dce( HWND hwnd )
{
win->dce = dce;
dce->hwnd = hwnd;
+ dce->count++;
list_add_tail( &dce_list, &dce->entry );
}
WIN_ReleasePtr( win );
@@ -495,7 +496,7 @@ static BOOL CALLBACK dc_hook( HDC hDC, WORD code, DWORD_PTR data, LPARAM lParam
* (between GetDC and ReleaseDC)
*/
USER_Lock();
- if (dce->count)
+ if (dce->count > 1)
{
WARN("Application trying to delete a busy DC %p\n", dce->hdc);
retv = FALSE;
More information about the wine-cvs
mailing list