8     _In_ 
const RECT *prcTarget,
 
    9     _In_ BP_BUFFERFORMAT dwFormat,
 
   10     _In_ BP_PAINTPARAMS *pPaintParams,
 
   15     _In_ HPAINTBUFFER hBufferedPaint,
 
   16     _In_ 
BOOL fUpdateTarget
 
   20     _In_ HPAINTBUFFER hBufferedPaint,
 
   21     _Out_ RGBQUAD **ppbBuffer,
 
   25 static BOOLEAN ImportsInitialized = 
FALSE;
 
   30 static HBITMAP PhpCreateBitmap32(
 
   34     _Outptr_opt_ PVOID *Bits
 
   37     BITMAPINFO bitmapInfo;
 
   39     memset(&bitmapInfo, 0, 
sizeof(BITMAPINFO));
 
   40     bitmapInfo.bmiHeader.biSize = 
sizeof(BITMAPINFOHEADER);
 
   41     bitmapInfo.bmiHeader.biPlanes = 1;
 
   42     bitmapInfo.bmiHeader.biCompression = BI_RGB;
 
   44     bitmapInfo.bmiHeader.biWidth = Width;
 
   45     bitmapInfo.bmiHeader.biHeight = Height;
 
   46     bitmapInfo.bmiHeader.biBitCount = 32;
 
   48     return CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, Bits, NULL, 0);
 
   51 static BOOLEAN PhpHasAlpha(
 
   62     delta = RowWidth - Width;
 
   64     for (y = Width; y; y--)
 
   66         for (x = Height; x; x--)
 
   68             if (*Argb++ & 0xff000000)
 
   78 static VOID PhpConvertToPArgb32(
 
   87     BITMAPINFO bitmapInfo;
 
   90     memset(&bitmapInfo, 0, 
sizeof(BITMAPINFO));
 
   91     bitmapInfo.bmiHeader.biSize = 
sizeof(BITMAPINFOHEADER);
 
   92     bitmapInfo.bmiHeader.biPlanes = 1;
 
   93     bitmapInfo.bmiHeader.biCompression = BI_RGB;
 
   95     bitmapInfo.bmiHeader.biWidth = Width;
 
   96     bitmapInfo.bmiHeader.biHeight = Height;
 
   97     bitmapInfo.bmiHeader.biBitCount = 32;
 
   99     bits = PhAllocate(Width * 
sizeof(ULONG) * Height);
 
  101     if (GetDIBits(hdc, Bitmap, 0, Height, bits, &bitmapInfo, DIB_RGB_COLORS) == Height)
 
  108         argbMask = (PULONG)bits;
 
  109         delta = RowWidth - Width;
 
  111         for (y = Height; y; y--)
 
  113             for (x = Width; x; x--)
 
  121                     *Argb++ |= 0xff000000; 
 
  132 static VOID PhpConvertToPArgb32IfNeeded(
 
  133     _In_ HPAINTBUFFER PaintBuffer,
 
  143     if (SUCCEEDED(GetBufferedPaintBits_I(PaintBuffer, &quad, &rowWidth)))
 
  145         PULONG argb = (PULONG)quad;
 
  147         if (!PhpHasAlpha(argb, Width, Height, rowWidth))
 
  151             if (GetIconInfo(Icon, &iconInfo))
 
  153                 if (iconInfo.hbmMask)
 
  155                     PhpConvertToPArgb32(hdc, argb, iconInfo.hbmMask, Width, Height, rowWidth);
 
  158                 DeleteObject(iconInfo.hbmColor);
 
  159                 DeleteObject(iconInfo.hbmMask);
 
  176     BLENDFUNCTION blendFunction = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
 
  177     BP_PAINTPARAMS paintParams = { 
sizeof(paintParams) };
 
  179     HPAINTBUFFER paintBuffer;
 
  181     iconRectangle.left = 0;
 
  182     iconRectangle.top = 0;
 
  183     iconRectangle.right = Width;
 
  184     iconRectangle.bottom = Height;
 
  186     if (!ImportsInitialized)
 
  190         uxtheme = GetModuleHandle(L
"uxtheme.dll");
 
  191         BeginBufferedPaint_I = (PVOID)GetProcAddress(uxtheme, 
"BeginBufferedPaint");
 
  192         EndBufferedPaint_I = (PVOID)GetProcAddress(uxtheme, 
"EndBufferedPaint");
 
  193         GetBufferedPaintBits_I = (PVOID)GetProcAddress(uxtheme, 
"GetBufferedPaintBits");
 
  194         ImportsInitialized = 
TRUE;
 
  197     if (!BeginBufferedPaint_I || !EndBufferedPaint_I || !GetBufferedPaintBits_I)
 
  201         screenHdc = GetDC(NULL);
 
  202         hdc = CreateCompatibleDC(screenHdc);
 
  203         bitmap = CreateCompatibleBitmap(screenHdc, Width, Height);
 
  204         ReleaseDC(NULL, screenHdc);
 
  206         oldBitmap = SelectObject(hdc, bitmap);
 
  207         FillRect(hdc, &iconRectangle, (HBRUSH)(COLOR_WINDOW + 1));
 
  208         DrawIconEx(hdc, 0, 0, Icon, Width, Height, 0, NULL, DI_NORMAL);
 
  209         SelectObject(hdc, oldBitmap);
 
  216     screenHdc = GetDC(NULL);
 
  217     hdc = CreateCompatibleDC(screenHdc);
 
  218     bitmap = PhpCreateBitmap32(screenHdc, Width, Height, NULL);
 
  219     ReleaseDC(NULL, screenHdc);
 
  220     oldBitmap = SelectObject(hdc, bitmap);
 
  222     paintParams.dwFlags = BPPF_ERASE;
 
  223     paintParams.pBlendFunction = &blendFunction;
 
  225     paintBuffer = BeginBufferedPaint_I(hdc, &iconRectangle, BPBF_DIB, &paintParams, &bufferHdc);
 
  226     DrawIconEx(bufferHdc, 0, 0, Icon, Width, Height, 0, NULL, DI_NORMAL);
 
  228     PhpConvertToPArgb32IfNeeded(paintBuffer, hdc, Icon, Width, Height);
 
  230     EndBufferedPaint_I(paintBuffer, 
TRUE);
 
  232     SelectObject(hdc, oldBitmap);