[PATCH] win32u: Create a dummy bitmap for display device contexts.

Zhiyi Zhang zzhang at codeweavers.com
Mon May 23 02:22:47 CDT 2022


On Windows 7 and older versions of Windows, calling GetCurrentObject(hdc, OBJ_BITMAP) for a display
device context will return a valid handle. However, this handle will fail for GetObject(). On newer
versions of Windows, GetCurrentObject(hdc, OBJ_BITMAP) for display device contexts returns a bitmap
of virtual screen size and its size changes after display mode changes. This behavior is tested in
the _check_display_dc() function in user32/tests/monitor.c.

The screen shot function of WeChat depends on GetObject() to either return failure or a valid size
for the bitmap from display device contexts. Since Wine currently report Windows 7 as default and to
save memory, the Windows 7 behavior is implemented.

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/gdi32/tests/bitmap.c |  1 -
 dlls/win32u/dc.c          | 13 +++++++++++--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index 18d1e8f6c28..d3074286ee6 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -2789,7 +2789,6 @@ static void test_CreateBitmap(void)
        "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
        bm, bm1, bm4, bm5, curObj1, old1);
     ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
-    todo_wine
     ok(bm != curObj2, "0: %p, curObj2 %p\n", bm, curObj2);
     ok(old2 == 0, "old2 %p\n", old2);
 
diff --git a/dlls/win32u/dc.c b/dlls/win32u/dc.c
index b684e198c05..95dd2651929 100644
--- a/dlls/win32u/dc.c
+++ b/dlls/win32u/dc.c
@@ -274,7 +274,13 @@ void free_dc_ptr( DC *dc )
     GDI_dec_ref_count( dc->hPen );
     GDI_dec_ref_count( dc->hBrush );
     GDI_dec_ref_count( dc->hFont );
-    if (dc->hBitmap) GDI_dec_ref_count( dc->hBitmap );
+    if (dc->hBitmap)
+    {
+        if (dc->is_display)
+            NtGdiDeleteClientObj( dc->hBitmap );
+        else
+            GDI_dec_ref_count( dc->hBitmap );
+    }
     free_gdi_handle( dc->hSelf );
     free_dc_state( dc );
 }
@@ -724,7 +730,10 @@ HDC WINAPI NtGdiOpenDCW( UNICODE_STRING *device, const DEVMODEW *devmode, UNICOD
     if (!(dc = alloc_dc_ptr( NTGDI_OBJ_DC ))) return 0;
     hdc = dc->hSelf;
 
-    dc->hBitmap = GDI_inc_ref_count( GetStockObject( DEFAULT_BITMAP ));
+    if (is_display)
+        dc->hBitmap = NtGdiCreateClientObj( NTGDI_OBJ_SURF );
+    else
+        dc->hBitmap = GDI_inc_ref_count( GetStockObject( DEFAULT_BITMAP ));
 
     TRACE("(device=%s, output=%s): returning %p\n",
           debugstr_us(device), debugstr_us(output), dc->hSelf );
-- 
2.34.1



More information about the wine-devel mailing list