Как правильно преобразовать 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
параметр
• Этот код что-то пропускает или все правильно очищено?
Выглядит нормально для меня!