Как правильно преобразовать ICON в BITMAP с помощью MFC?

Я загружаю иконку другого приложения через

HICON ico = ExtractIcon(NULL, L"path\\to\\OtherApp.exe", 0);

Как я могу создать CBitmap объект из этой иконы?

В частности (на самом деле не ответил в двойном вопросе для меня):

  • Какой контекст устройства?
  • В конце я хочу 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);
}

1 ответ

Решение

• Зачем мне нужен CClientDC? (Если я использую только CDC, растровое изображение не отображается или черно-белое, в зависимости от того, где я его разместил.)

Вам нужен DC, который основан на вашем окне или экране, просто объявив CDC не достаточно, вам также нужно будет позвонить dc.Attach() или один из CDC::Create* функции.

• (Почему) нужна строка dc.SelectObject( pOldBmp)?

Так что растровое изображение отключено от DC

• Почему я должен делать CopyImage? (Если я этого не сделаю, растровое изображение иногда рисуется с перевернутыми цветами.)

Похоже, вы создаете независимую от устройства BIMAP с помощью CopyImage() позвонить с помощью LR_CREATEDIBSECTION параметр

• Этот код что-то пропускает или все правильно очищено?

Выглядит нормально для меня!

Другие вопросы по тегам