http://bugs.winehq.com/show_bug.cgi?id=1534
Summary: CreateBitmap is supposed to return the stock object Product: Wine Version: unspecified Platform: Other OS/Version: other Status: UNCONFIRMED Severity: minor Priority: P2 Component: wine-gdi AssignedTo: wine-bugs@winehq.com ReportedBy: pete_a90@hotmail.com
Note, I don't have wine but I use the source code as a reference because msdn is terrible at times. I noticed that the author of CreateCompatibleBitmap and CreateBitmap (and CreateBitmapIndirect too but that calls CreateBitmap directly) misinterpreted the gdi documentation. It returns *the* (as in GetStockObject(DEFALT_BITMAP) in wine) handle to a 1x1 monochrome bitmap if the width or height is 0. Here is some test code that I wrote in windows that verifies this is true:
#define WIN32_LEAN_AND_MEAN #include <windows.h>
int main() { HDC screenDC = GetDC(0); HDC hdc = CreateCompatibleDC(screenDC);
// all of these are the stock (in wine) monochrome bitmap HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0); HBITMAP bm1 = CreateCompatibleBitmap(hdc, 0, 0); HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0); HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0); HBITMAP curObj = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1); HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
HBITMAP old = (HBITMAP)SelectObject(hdc, (HGDIOBJ)bm2); SelectObject(hdc, (HGDIOBJ)old);
// old == the stock monochrome bitmaps above
{ HBITMAP screenBM = (HBITMAP)GetCurrentObject(screenDC, OBJ_BITMAP); // weird: screenBM != bm BITMAP bitmap1;
int ret = GetObject(screenBM, 0, 0); // returns sizeof(BITMAP)
BITMAP bitmap2;
memset(&bitmap1, 0xDA, sizeof(bitmap1)); ret = GetObject(screenBM, ret, &bitmap1); // ret = 0, doesn't touch bitmap1 at all.
ret = GetObject(bm, sizeof(bitmap2), &bitmap2); // ret = 18, bitmap2 is filled in with the monochrome bitmap info }
DeleteObject(bm); DeleteObject(bm1); DeleteObject(bm2); DeleteObject(bm3); DeleteObject(bm4); DeleteObject(bm5);
DeleteDC(hdc); ReleaseDC(0, screenDC);
return 0; }
Looks like an easy fix though (don't quote me on that since I don't use linux and I don't have a local copy of the code [sorry for no path either]):
In CreateCompatibleBitmap replace the following:
/* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */ if (!width || !height) hbmpRet = CreateBitmap( 1, 1, 1, 1, NULL ); else hbmpRet = CreateBitmap( width, height, 1, dc->bitsPerPixel, NULL );
with just:
hbmpRet = CreateBitmap( width, height, 1, dc->bitsPerPixel, NULL );
and in CreateBitmap replace:
if (!height || !width) { height = 1; width = 1; planes = 1; bpp = 1; }
with:
if (!height || !width) return GetStockObject(DEFAULT_BITMAP);