1

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

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);
}
4

1 回答 1

1

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

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

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

使位图与DC断开

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

看起来您正在使用使用参数 的CopyImage()调用创建与设备无关的 bimapLR_CREATEDIBSECTION

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

在我看来没问题!

于 2013-06-14T16:56:54.217 回答