Index: subsystems/win32/win32k/ntuser/cursoricon.c =================================================================== --- subsystems/win32/win32k/ntuser/cursoricon.c (revision 40359) +++ subsystems/win32/win32k/ntuser/cursoricon.c (working copy) @@ -1405,7 +1405,6 @@ BOOL Ret = FALSE; HBITMAP hbmMask, hbmColor; BITMAP bmpMask, bmpColor; - COLORREF oldFg, oldBg; BOOL DoFlickerFree; SIZE IconSize; @@ -1413,8 +1412,10 @@ HGDIOBJ hOldOffBrush = 0; HGDIOBJ hOldOffBmp = 0; HBITMAP hbmOff = 0; - HDC hdcMem = 0; - HGDIOBJ hOldMem; + HDC hdcMemMASK = 0; + HGDIOBJ hOldMemMASK = NULL; + HDC hdcMemIMAGE = 0; + HGDIOBJ hOldMemIMAGE = NULL; BOOL bAlpha = FALSE; hbmMask = pIcon->IconInfo.hbmMask; @@ -1452,7 +1453,8 @@ PFN_DIB_GetPixel fnSource_GetPixel = NULL; INT x, y; - //Find alpha into icon + //In order to correctly display 32 bit icons Windows first scans the image, + //because information about transparency is not stored in any image's headers. psurfOff = SURFACE_LockSurface(hbmColor ? hbmColor : hbmMask); if (psurfOff) { @@ -1549,61 +1551,62 @@ else hdcOff = hDc; - hdcMem = NtGdiCreateCompatibleDC(hDc); - if (!hdcMem) + if (diFlags & DI_IMAGE) { - DPRINT1("NtGdiCreateCompatibleDC() failed!\n"); - goto cleanup; + hdcMemIMAGE = NtGdiCreateCompatibleDC(hDc); + if (!hdcMemIMAGE) + { + DPRINT1("NtGdiCreateCompatibleDC() failed!\n"); + goto cleanup; + } + hOldMemIMAGE = NtGdiSelectBitmap(hdcMemIMAGE, (hbmColor ? hbmColor : hbmMask)); + if (!hOldMemIMAGE) + { + DPRINT("NtGdiSelectBitmap() failed!\n"); + goto cleanup; + } } - oldFg = IntGdiSetTextColor(hdcOff, RGB(0, 0, 0)); - oldBg = IntGdiSetBkColor(hdcOff, RGB(255, 255, 255)); - - if (diFlags & DI_MASK) + //If diFlags DI_IMAGE and exists hbmMask, then always using mask for draw. + if (diFlags & DI_MASK || (diFlags & DI_IMAGE && hbmMask)) { - hOldMem = NtGdiSelectBitmap(hdcMem, hbmMask); - if (!hOldMem) + hdcMemMASK = NtGdiCreateCompatibleDC(hDc); + if (!hdcMemMASK) { - DPRINT("NtGdiSelectBitmap() failed!\n"); + DPRINT1("NtGdiCreateCompatibleDC() failed!\n"); goto cleanup; } - NtGdiStretchBlt(hdcOff, - (DoFlickerFree || bAlpha ? 0 : xLeft), - (DoFlickerFree || bAlpha ? 0 : yTop), - cxWidth, - cyHeight, - hdcMem, - 0, - 0, - IconSize.cx, - IconSize.cy, - ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), - 0); - - NtGdiSelectBitmap(hdcMem, hOldMem); + hOldMemMASK = NtGdiSelectBitmap(hdcMemMASK, hbmMask); + if (!hOldMemMASK) + { + DPRINT("NtGdiSelectBitmap() failed!\n"); + goto cleanup; + } } - if(diFlags & DI_IMAGE) + if (hdcMemMASK || hdcMemIMAGE) { - hOldMem = NtGdiSelectBitmap(hdcMem, (hbmColor ? hbmColor : hbmMask)); - - NtGdiStretchBlt(hdcOff, + GreStretchBltMask(hdcOff, (DoFlickerFree || bAlpha ? 0 : xLeft), - (DoFlickerFree || bAlpha ? 0 : yTop), + (DoFlickerFree || bAlpha ? 0 : yTop), cxWidth, cyHeight, - hdcMem, + hdcMemIMAGE ? hdcMemIMAGE : hdcMemMASK, 0, - (hbmColor ? 0 : IconSize.cy), + (diFlags & DI_IMAGE && hbmColor ? 0 : IconSize.cy), IconSize.cx, IconSize.cy, - ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY), - 0); - - NtGdiSelectBitmap(hdcMem, hOldMem); + SRCCOPY, + 0, + hdcMemIMAGE ? hdcMemMASK : NULL); } + if (hOldMemMASK) NtGdiSelectBitmap(hdcMemMASK, hOldMemMASK); + if (hOldMemIMAGE) NtGdiSelectBitmap(hdcMemIMAGE, hOldMemIMAGE); + if (hdcMemIMAGE) NtGdiDeleteObjectApp(hdcMemIMAGE); + if (hdcMemMASK) NtGdiDeleteObjectApp(hdcMemMASK); + if (bAlpha) { BITMAP bm; @@ -1673,9 +1676,6 @@ cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0); } - IntGdiSetTextColor(hdcOff, oldFg); - IntGdiSetBkColor(hdcOff, oldBg); - Ret = TRUE; cleanup: @@ -1687,7 +1687,6 @@ if(hdcOff) NtGdiDeleteObjectApp(hdcOff); } - if(hdcMem) NtGdiDeleteObjectApp(hdcMem); return Ret; }