Winapi 如何使用MFC将图标正确转换为位图?

Winapi 如何使用MFC将图标正确转换为位图?,winapi,visual-c++,mfc,icons,cbitmap,Winapi,Visual C++,Mfc,Icons,Cbitmap,我正在通过加载另一个应用程序的图标 HICON ico = ExtractIcon(NULL, L"path\\to\\OtherApp.exe", 0); 如何从此图标创建CBitmap对象 具体地说(在dup问题中我没有真正回答): 哪个设备上下文 最后,我需要一个CBitmap对象,该对象超出了转换图标的函数: 我需要立即清理什么?我需要保留什么?(DC,…?) 以下是我目前掌握的代码: void ConvertIconToBitmap(CBitmap& bmpObj, HI

我正在通过加载另一个应用程序的图标

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);
}
•为什么我需要CClientDC?(如果我只使用CDC,则位图不会显示或显示为黑白,具体取决于我放置的位置。)

您需要一个基于窗口或屏幕的DC,仅声明
CDC
是不够的,您还需要调用
DC.Attach()
CDC::Create*
函数之一。

•(为什么)是否需要dc.SelectObject(pOldBmp)行

使位图与DC断开连接

•我为什么要做CopyImage?(如果不这样做,位图有时会使用反转颜色绘制。)

看起来您正在使用
LR\u CREATEDIBSECTION
参数使用
CopyImage()
调用创建一个与设备无关的bimap

•此代码是否泄漏任何内容,或是否已正确清理所有内容

我看还可以

•为什么我需要CClientDC?(如果我只使用CDC,则位图不会显示或显示为黑白,具体取决于我放置的位置。)

您需要一个基于窗口或屏幕的DC,仅声明
CDC
是不够的,您还需要调用
DC.Attach()
CDC::Create*
函数之一。

•(为什么)是否需要dc.SelectObject(pOldBmp)行

使位图与DC断开连接

•我为什么要做CopyImage?(如果不这样做,位图有时会使用反转颜色绘制。)

看起来您正在使用
LR\u CREATEDIBSECTION
参数使用
CopyImage()
调用创建一个与设备无关的bimap

•此代码是否泄漏任何内容,或是否已正确清理所有内容


我看还可以

创建位图,在其上绘制图标,然后保存位图。在Win32中,需要调用
DrawIcon
传递设备上下文,将位图加载到其中。创建位图的可能副本,在其上绘制图标,保存位图。在Win32中,需要调用
DrawIcon
传递加载位图的设备上下文。可能重复