Reputation: 38776
I'm loading an ICON of another application via
HICON ico = ExtractIcon(NULL, L"path\\to\\OtherApp.exe", 0);
How can I create a CBitmap
object from this icon?
Specifically (not really answered in the dup question for me):
CBitmap
object that outlives the function that converts the icon:DC
, ...?)Here's the code I have so far:
void ConvertIconToBitmap(CBitmap& bmpObj, HICON hIcon, int cx, int cy) {
CClientDC clientDC(NULL);
CDC dc;
dc.CreateCompatibleDC(NULL);
CBitmap bmpTmp;
VERIFY( bmpTmp.CreateCompatibleBitmap(&clientDC, cx, cy) );
CBitmap* pOldBmp = (CBitmap*)dc.SelectObject(&bmpTmp);
VERIFY( ::DrawIconEx( dc.GetSafeHdc(), 0, 0, hIcon, cx, cy, 0, NULL, DI_NORMAL) );
dc.SelectObject( pOldBmp );
// For some reason I need to copy the bitmap here: (maybe it's the DIB flag)
HBITMAP hDibBmp = (HBITMAP)::CopyImage((HANDLE)(HBITMAP)bmpTmp, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
VERIFY( hDibBmp );
VERIFY( bmpObj.Attach(hDibBmp) );
// VERIFY( bmpObj.Attach(bmpTmp.Detach()) );
}
Now, this code works, but I don't understand it:
CClientDC
? (If I use only CDC the bitmap is not shown or Black&White, depending on where I put it.)dc.SelectObject( pOldBmp )
line needed?CopyImage
? (If I don't, the bitmap is sometimes drawn with inverted colors.)Here's another version that also seems to work:
void ConvertIconToBitmap2(CBitmap& bmpObj, HICON hIcon, int cx, int cy) {
CClientDC clientDC(NULL);
CDC memDC;
memDC.CreateCompatibleDC(&clientDC);
ASSERT(hIcon);
ICONINFO info;
VERIFY(GetIconInfo(hIcon, &info));
BITMAP bmp;
GetObject(info.hbmColor, sizeof(bmp), &bmp);
HBITMAP hBitmap = (HBITMAP)CopyImage(info.hbmColor, IMAGE_BITMAP, 0, 0, 0);
ASSERT(hBitmap);
ASSERT(memDC.GetSafeHdc());
HBITMAP hOldBmp = (HBITMAP)memDC.SelectObject(hBitmap);
clientDC.BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &memDC, 0, 0, SRCCOPY);
memDC.SelectObject(hOldBmp);
VERIFY( bmpObj.Attach(hBitmap) );
DeleteObject(info.hbmColor);
DeleteObject(info.hbmMask);
}
Upvotes: 2
Views: 3594
Reputation: 5132
•Why do I need a CClientDC? (If I use only CDC the bitmap is not shown or Black&White, depending on where I put it.)
You would need a DC that is based on your window or the screen, just declaring a CDC
is not enough, you will also need to call dc.Attach()
or one of the CDC::Create*
functions.
•(Why) is the dc.SelectObject( pOldBmp ) line needed?
So that the bitmap is disconnected from the DC
•Why do I have to do CopyImage? (If I don't, the bitmap is sometimes drawn with inverted colors.)
It looks like you are creating a device independent bimap using the CopyImage()
call using the LR_CREATEDIBSECTION
parameter
•Does this code leak anything or is everything properly cleaned up?
Looks ok to me!
Upvotes: 2