HBITMAP GraphicsMisc::IconToPARGB32Bitmap(HICON hIcon) { HBITMAP hBmp = NULL; if (hIcon) { HDC hdcDest = CreateCompatibleDC(NULL); BOOL bSuccess = FALSE; if (hdcDest) { CSize sIcon = GetIconSize(hIcon); if (Create32BitHBITMAP(hdcDest, &sIcon, NULL, &hBmp)) { HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcDest, hBmp); if (hbmpOld) { BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; TH_PAINTPARAMS paintParams = { 0 }; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; paintParams.pBlendFunction = &bfAlpha; HDC hdcBuffer = NULL; CRect rIcon(0, 0, sIcon.cx, sIcon.cy); HPAINTBUFFER hPaintBuffer = CThemed::BeginBufferedPaint(hdcDest, rIcon, THBPBF_DIB, &paintParams, &hdcBuffer); if (hPaintBuffer) { ASSERT(hdcBuffer); if (DrawIconEx(hdcBuffer, 0, 0, hIcon, sIcon.cx, sIcon.cy, 0, NULL, DI_NORMAL)) { // If icon did not have an alpha channel, we need to convert buffer to PARGB. bSuccess = ConvertBufferToPARGB32(hPaintBuffer, hdcDest, hIcon, sIcon); } // This will write the buffer contents to the destination bitmap. CThemed::EndBufferedPaint(hPaintBuffer, TRUE); } SelectObject(hdcDest, hbmpOld); } } VERIFY(DeleteDC(hdcDest)); } if (!bSuccess && hBmp) { VERIFY(DeleteObject(hBmp)); hBmp = NULL; } } return hBmp; }
HBITMAP IconToBitmapPARGB32(HICON hIcon, DWORD cx, DWORD cy) { HRESULT hr = E_OUTOFMEMORY; HBITMAP hBmp = NULL; if(!hIcon) return NULL; SIZE sizIcon; sizIcon.cx = cx; sizIcon.cy = cy; RECT rcIcon; SetRect(&rcIcon, 0, 0, sizIcon.cx, sizIcon.cy); HDC hdcDest = CreateCompatibleDC(NULL); if(hdcDest) { hr = Create32BitHBITMAP(hdcDest, &sizIcon, NULL, &hBmp); if(SUCCEEDED(hr)) { hr = E_FAIL; HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcDest, hBmp); if(hbmpOld) { BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; BP_PAINTPARAMS paintParams = {0, 0, 0, 0}; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; paintParams.pBlendFunction = &bfAlpha; HDC hdcBuffer; HPAINTBUFFER hPaintBuffer = pfnBeginBufferedPaint(hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer); if(hPaintBuffer) { if(DrawIconEx(hdcBuffer, 0, 0, hIcon, sizIcon.cx, sizIcon.cy, 0, NULL, DI_NORMAL)) { // If icon did not have an alpha channel, we need to convert buffer to PARGB. hr = ConvertBufferToPARGB32(hPaintBuffer, hdcDest, hIcon, sizIcon); } // This will write the buffer contents to the destination bitmap. pfnEndBufferedPaint(hPaintBuffer, TRUE); } SelectObject(hdcDest, hbmpOld); } } DeleteDC(hdcDest); } DestroyIcon(hIcon); if(SUCCEEDED(hr)) { return hBmp; } DeleteObject(hBmp); return NULL; }
HBITMAP IconBitmapUtils::IconToBitmapPARGB32(HICON hIcon) { if (!hIcon) return NULL; SIZE sizIcon; sizIcon.cx = GetSystemMetrics(SM_CXSMICON); sizIcon.cy = GetSystemMetrics(SM_CYSMICON); RECT rcIcon; SetRect(&rcIcon, 0, 0, sizIcon.cx, sizIcon.cy); HDC hdcDest = CreateCompatibleDC(NULL); if (!hdcDest) return nullptr; SCOPE_EXIT { DeleteDC(hdcDest); }; HBITMAP hBmp = nullptr; if (FAILED(Create32BitHBITMAP(hdcDest, &sizIcon, NULL, &hBmp))) return nullptr; HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcDest, hBmp); if (!hbmpOld) return hBmp; BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; BP_PAINTPARAMS paintParams = { 0 }; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; paintParams.pBlendFunction = &bfAlpha; HDC hdcBuffer; HPAINTBUFFER hPaintBuffer = BeginBufferedPaint(hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer); if (hPaintBuffer) { if (DrawIconEx(hdcBuffer, 0, 0, hIcon, sizIcon.cx, sizIcon.cy, 0, NULL, DI_NORMAL)) { // If icon did not have an alpha channel we need to convert buffer to PARGB ConvertBufferToPARGB32(hPaintBuffer, hdcDest, hIcon, sizIcon); } // This will write the buffer contents to the destination bitmap EndBufferedPaint(hPaintBuffer, TRUE); } SelectObject(hdcDest, hbmpOld); return hBmp; }
HBITMAP CIconMenu::IconToBitmapPARGB32(UINT uIcon) { std::map<UINT, HBITMAP>::iterator bitmap_it = bitmaps.lower_bound(uIcon); if (bitmap_it != bitmaps.end() && bitmap_it->first == uIcon) return bitmap_it->second; HICON hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(uIcon), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); if (!hIcon) return NULL; if (pfnBeginBufferedPaint == NULL || pfnEndBufferedPaint == NULL || pfnGetBufferedPaintBits == NULL) return NULL; SIZE sizIcon; sizIcon.cx = GetSystemMetrics(SM_CXSMICON); sizIcon.cy = GetSystemMetrics(SM_CYSMICON); RECT rcIcon; SetRect(&rcIcon, 0, 0, sizIcon.cx, sizIcon.cy); HBITMAP hBmp = NULL; HDC hdcDest = CreateCompatibleDC(NULL); if (hdcDest) { if (SUCCEEDED(Create32BitHBITMAP(hdcDest, &sizIcon, NULL, &hBmp))) { HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcDest, hBmp); if (hbmpOld) { BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; BP_PAINTPARAMS paintParams = {0}; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; paintParams.pBlendFunction = &bfAlpha; HDC hdcBuffer; HPAINTBUFFER hPaintBuffer = pfnBeginBufferedPaint(hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer); if (hPaintBuffer) { if (DrawIconEx(hdcBuffer, 0, 0, hIcon, sizIcon.cx, sizIcon.cy, 0, NULL, DI_NORMAL)) { // If icon did not have an alpha channel we need to convert buffer to PARGB ConvertBufferToPARGB32(hPaintBuffer, hdcDest, hIcon, sizIcon); } // This will write the buffer contents to the destination bitmap pfnEndBufferedPaint(hPaintBuffer, TRUE); } SelectObject(hdcDest, hbmpOld); } } DeleteDC(hdcDest); } DestroyIcon(hIcon); if(hBmp) bitmaps.insert(bitmap_it, std::make_pair(uIcon, hBmp)); return hBmp; }
HBITMAP IconToBitmapPARGB32(HICON hIcon) { if (!hIcon) return NULL; pfnGetBufferedPaintBits = NULL; pfnBeginBufferedPaint = NULL; pfnEndBufferedPaint = NULL; HMODULE hUxTheme = LoadLibrary(_T("UXTHEME.DLL")); if (hUxTheme) { pfnGetBufferedPaintBits = (FN_GetBufferedPaintBits)::GetProcAddress(hUxTheme, "GetBufferedPaintBits"); pfnBeginBufferedPaint = (FN_BeginBufferedPaint)::GetProcAddress(hUxTheme, "BeginBufferedPaint"); pfnEndBufferedPaint = (FN_EndBufferedPaint)::GetProcAddress(hUxTheme, "EndBufferedPaint"); } if (pfnBeginBufferedPaint == NULL || pfnEndBufferedPaint == NULL || pfnGetBufferedPaintBits == NULL) { FreeLibrary(hUxTheme); return NULL; } SIZE sizIcon; sizIcon.cx = GetSystemMetrics(SM_CXSMICON); sizIcon.cy = GetSystemMetrics(SM_CYSMICON); RECT rcIcon; SetRect(&rcIcon, 0, 0, sizIcon.cx, sizIcon.cy); HBITMAP hBmp = NULL; HDC hdcDest = CreateCompatibleDC(NULL); if (hdcDest) { if (SUCCEEDED(Create32BitHBITMAP(hdcDest, &sizIcon, NULL, &hBmp))) { HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcDest, hBmp); if (hbmpOld) { BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; BP_PAINTPARAMS paintParams = {0}; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; paintParams.pBlendFunction = &bfAlpha; HDC hdcBuffer; HPAINTBUFFER hPaintBuffer = pfnBeginBufferedPaint(hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer); if (hPaintBuffer) { if (DrawIconEx(hdcBuffer, 0, 0, hIcon, sizIcon.cx, sizIcon.cy, 0, NULL, DI_NORMAL)) { // If icon did not have an alpha channel we need to convert buffer to PARGB ConvertBufferToPARGB32(hPaintBuffer, hdcDest, hIcon, sizIcon); } // This will write the buffer contents to the destination bitmap pfnEndBufferedPaint(hPaintBuffer, TRUE); } SelectObject(hdcDest, hbmpOld); } } DeleteDC(hdcDest); } FreeLibrary(hUxTheme); return hBmp; }