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@codeweavers.com
From: Zhiyi Zhang zzhang@codeweavers.com
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@codeweavers.com --- dlls/gdi32/tests/bitmap.c | 1 - dlls/user32/tests/monitor.c | 1 - dlls/win32u/dc.c | 13 +++++++++++-- 3 files changed, 11 insertions(+), 4 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/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index 94cb7e60382..4b774037508 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -2164,7 +2164,6 @@ static void _check_display_dc(INT line, HDC hdc, const DEVMODEA *dm, BOOL allow_ ok_(__FILE__, line)(!!hbmp, "GetCurrentObject failed, error %#lx.\n", GetLastError()); ret = GetObjectA(hbmp, sizeof(bitmap), &bitmap); /* GetObjectA fails on Win7 and older */ - ok_(__FILE__, line)(ret || broken(!ret), "GetObjectA failed, error %ld.\n", GetLastError()); if (ret) { ok_(__FILE__, line)(bitmap.bmType == 0, "Expected bmType %d, got %d.\n", 0, bitmap.bmType); 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 );
This merge request was approved by Huw Davies.