views:

153

answers:

2

Maybe this is a foolish question, I can't see why I can not get a DC created in the following code :

HBITMAP COcrDlg::LoadClippedBitmap(LPCTSTR pathName,UINT maxWidth,UINT maxHeight)
{
    HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, pathName, IMAGE_BITMAP, 0, 0,
                                  LR_LOADFROMFILE | LR_CREATEDIBSECTION);       
    if (!hBmp)
        return NULL;

    HDC hdc = (HDC)GetDC();
    HDC hdcMem = CreateCompatibleDC(hdc);
    if (!hdcMem)
    {
        DWORD err = GetLastError();
    }  
    ...
    ...
    ...

The bitmap hBmp is loaded fine and hdc has a valid value. But the call to CreateCompatibleDC() returns a NULL pointer. Then, GetLastError() returns 0 ! Anybody can guess what's going on here , please ?

PS : There are no memory allocations or GDI routines called before this one...so I think memory leaks should be ruled out.

+2  A: 

Certain device contexts won't work with CreateCompatibleDC(). The DC has to support raster operations. You can feed the hdc to GetDeviceCaps() and check RASTERCAPS.

But it turns out the GetDC you're calling is a method on a class and not the C binding I thought you meant. SoapBox has the right answer.

JustJeff
GetDeviceCaps(hdc, RASTERCAPS) returned 0....does this mean no support for raster operations?
sevaxx
@sevaxx: well, the documentation says that GetDeviceCaps(hdc,RASTERCAPS) should return one of those famous bitfield values, so zero would seem to imply no raster capabilities. When I just ran it with a plain window DC, it returned 0x7E99
JustJeff
+4  A: 

You are improperly casting the result of GetDC() to an HDC. GetDC() returns a pointer to a CDC object.

To do what you want you can do either of the following. The first choice fits more into how MFC likes to do things, but both work just fine:

CDC *pDC = GetDC();

// Option 1
CDC memDC;
memDC.CreateCompatibleDC(pDC);

// Option 2
HDC hMemDC = CreateCompatibleDC((HDC)(*pDC));

It is important to note that option 2 does not do the same thing that you're currently doing wrong. The CDC class has an operator HDC() member that allows it to be converted to an HDC, but this does NOT apply to the pointer. You must dereference it first.

SoapBox
You are perfectly right. This was the error . Grateful to all for the help !
sevaxx