如何使用 MFC 正确地将 ICON 转换为 BITMAP?
Posted
技术标签:
【中文标题】如何使用 MFC 正确地将 ICON 转换为 BITMAP?【英文标题】:How do I correctly convert an ICON to a BITMAP using MFC? 【发布时间】:2013-06-13 08:55:58 【问题描述】:我正在通过
加载另一个应用程序的图标HICON ico = ExtractIcon(NULL, L"path\\to\\OtherApp.exe", 0);
如何从该图标创建CBitmap
对象?
具体来说(在我的 dup 问题中没有真正回答):
哪个设备上下文? 最后,我想要一个CBitmap
对象,它比转换图标的函数的寿命更长:
我需要立即清理什么以及需要保留什么? (DC
, ...?)
这是我目前的代码:
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()) );
现在,这段代码有效,但我不明白:
为什么我需要CClientDC
? (如果我只使用 CDC,则不显示位图或黑白,这取决于我放置它的位置。)
(为什么)需要dc.SelectObject( pOldBmp )
行吗?
为什么我必须做CopyImage
? (如果我不这样做,位图有时会用反色绘制。)
此代码是否泄漏任何内容或是否已正确清理所有内容?
这是另一个似乎也可以工作的版本:
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);
【问题讨论】:
创建位图,在其上绘制图标,保存位图。 在 Win32 中,涉及对DrawIcon
的调用,传递您加载位图的设备上下文。
How to convert HICON to HBITMAP in VC++? 的可能重复项
【参考方案1】:
•为什么需要 CClientDC? (如果我只使用 CDC,则不显示位图或黑白,这取决于我放置它的位置。)
您需要一个基于您的窗口或屏幕的 DC,仅声明 CDC
是不够的,您还需要调用 dc.Attach()
或 CDC::Create*
函数之一。
•(为什么)需要 dc.SelectObject( pOldBmp ) 行吗?
使位图与DC断开
•为什么我必须进行 CopyImage? (如果我不这样做,位图有时会用反色绘制。)
看起来您正在使用CopyImage()
调用使用LR_CREATEDIBSECTION
参数创建一个设备独立的bimap
•此代码是否泄漏任何内容或是否已正确清理所有内容?
我觉得不错!
【讨论】:
以上是关于如何使用 MFC 正确地将 ICON 转换为 BITMAP?的主要内容,如果未能解决你的问题,请参考以下文章