gdi32: Remove call to CreateCompatibleDC() from GetDIBits() implementation (try 1)

Alex Villací­s Lasso a_villacis at
Mon Oct 23 17:45:33 CDT 2006

Huw Davies escribió:
> On Fri, Oct 20, 2006 at 05:49:09PM -0500, Alex Villací­s Lasso wrote:
>> This is the first attempt at a patch that will fix the debug assertion 
>> when icons are rendered into metafiles (triggered by Enterprise 
>> Architect 6.5, and possibly others). This patch simply removes mentions 
>> of memdc, created by a call to CreateCompatibleDC(), and redirects calls 
>> to GetDIBColorTable() to use the original DC instead of memdc. Intends 
>> to fix bug #6439. Now with patch.
> This can't work, since the bitmap needs to be selected into the dc for
> GetDIBColorTable to succeed and you're not allow to call GetDIBits
> with the bitmap selected into the dc...
> Huw.
Please correct me if the details of my understanding are wrong in any way.

The problem is that in the wine implementation, the palette is *not* 
stored anywhere inside the returned HBITMAP from CreateDIBSection(). 
Instead, the HDC used by CreateDIBSection must implement the 
pCreateDIBSection (this already leads to loss of palette information if 
it doesn't, for example in enhmfdrv), and then pCreateDIBSection is 
called, and somehow associates the HBITMAP with the actual 
implementation (in winex11drv, an XContext is used to save the pointer 
to a X_PHYSBITMAP, indexed by the HBITMAP). The method of getting to the 
palette information given an arbitrary DIB HBITMAP is private to the 
driver, and the functions contained in the BITMAPOBJ structure are not 
enough - a PHYSDEV is also required, usually provided by the DC. Million 
dollar question: what happens in the current implementation if a DIB 
created with a reference DC that saves the palette with method A is used 
with GetDIBits() and a reference HDC that expects a PHYSDEV with a 
different method B of saving the palette? Also, how do we get the 
palette information from GetDIBits() if the reference HDC does not 
support pGetDIBColorTable()?

Given that, I thought of a few solutions to get the palette information 
from a DIB without CreateCompatibleDC():
- Select the HBITMAP into the reference DC inside the implementation of 
GetDIBits(), then call GetDIBColorTable() on the reference DC. Although 
the HBITMAP should not be selected into the reference DC before calling 
GetDIBits(), MSDN says nothing about GetDIBits() itself selecting the 
bitmap into the reference DC.
- Add a new field to BITMAPOBJ with the PHYSDEV from the reference DC. 
Then, the corresponding function pGetDIBColorTable could be called with 
the proper parameters without the need of a new DC. Palette information 
is still lost if reference DC of CreateDIBSection does not support 
- Add a new field to BITMAPOBJ for the sole purpose of storing a copy of 
the DIB palette when calling CreateDIBSection(), and use it for 
GetDIBits(). Requires synchronization when calling SetDIBColorTable(), 
and possibly in other places, and also a rewrite of GetDIBColorTable(). 
However, this has the advantage that no palette information will be lost 
when creating a DIB section with a reference DC that does not implement 
pCreateDIBsection. The best method IMHO.

What do you think of these suggestions? Any comments are welcome.

Alex Villacís Lasso

The following cryptic message was allegedly found in the inner edge of a Windows
XP installation CD:


It is rumored that only a true Unix Wizard can decypher this mysterious message,
which supposedly encodes the true nature and purpose of the software.

More information about the wine-devel mailing list