📄 cursoricon.c
字号:
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserSetCursorIconContents\n");
UserEnterExclusive();
WinSta = IntGetWinStaObj();
if(WinSta == NULL)
{
RETURN( FALSE);
}
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
{
ObDereferenceObject(WinSta);
RETURN(FALSE);
}
/* Copy fields */
Status = MmCopyFromCaller(&CurIcon->IconInfo, IconInfo, sizeof(ICONINFO));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
goto done;
}
bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmColor);
if(bmp)
{
CurIcon->Size.cx = bmp->SurfObj.sizlBitmap.cx;
CurIcon->Size.cy = bmp->SurfObj.sizlBitmap.cy;
BITMAPOBJ_UnlockBitmap(bmp);
GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmColor, NULL);
}
else
{
bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmMask);
if(!bmp)
goto done;
CurIcon->Size.cx = bmp->SurfObj.sizlBitmap.cx;
CurIcon->Size.cy = bmp->SurfObj.sizlBitmap.cy / 2;
BITMAPOBJ_UnlockBitmap(bmp);
GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmMask, NULL);
}
Ret = TRUE;
done:
ObDereferenceObject(WinSta);
RETURN( Ret);
CLEANUP:
DPRINT("Leave NtUserSetCursorIconContents, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @implemented
*/
BOOL
STDCALL
NtUserSetCursorIconData(
HANDLE hCurIcon,
PBOOL fIcon,
POINT *Hotspot,
HMODULE hModule,
HRSRC hRsrc,
HRSRC hGroupRsrc)
{
PCURICON_OBJECT CurIcon;
PWINSTATION_OBJECT WinSta;
NTSTATUS Status;
POINT SafeHotspot;
BOOL Ret = FALSE;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserSetCursorIconData\n");
UserEnterExclusive();
WinSta = IntGetWinStaObj();
if(WinSta == NULL)
{
RETURN( FALSE);
}
if(!(CurIcon = UserGetCurIconObject(hCurIcon)))
{
ObDereferenceObject(WinSta);
RETURN(FALSE);
}
CurIcon->hModule = hModule;
CurIcon->hRsrc = hRsrc;
CurIcon->hGroupRsrc = hGroupRsrc;
/* Copy fields */
if(fIcon)
{
Status = MmCopyFromCaller(&CurIcon->IconInfo.fIcon, fIcon, sizeof(BOOL));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
goto done;
}
}
else
{
if(!Hotspot)
Ret = TRUE;
}
if(Hotspot)
{
Status = MmCopyFromCaller(&SafeHotspot, Hotspot, sizeof(POINT));
if(NT_SUCCESS(Status))
{
CurIcon->IconInfo.xHotspot = SafeHotspot.x;
CurIcon->IconInfo.yHotspot = SafeHotspot.y;
Ret = TRUE;
}
else
SetLastNtError(Status);
}
if(!fIcon && !Hotspot)
{
Ret = TRUE;
}
done:
ObDereferenceObject(WinSta);
RETURN( Ret);
CLEANUP:
DPRINT("Leave NtUserSetCursorIconData, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @unimplemented
*/
BOOL
STDCALL
NtUserSetSystemCursor(
HCURSOR hcur,
DWORD id)
{
return FALSE;
}
#define STRETCH_CAN_SRCCOPY_ONLY
#ifdef STRETCH_CAN_SRCCOPY_ONLY
void
FASTCALL
DoStretchBlt(HDC DcDest, int XDest, int YDest, int WidthDest, int HeightDest,
HDC DcSrc, int XSrc, int YSrc, int WidthSrc, int HeightSrc,
DWORD Rop3, BOOL Color)
{
HDC DcStretched;
HBITMAP BitmapStretched;
HBITMAP OldBitmap;
if (WidthDest == WidthSrc && HeightDest == HeightSrc)
{
NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest,
DcSrc, XSrc, YSrc, Rop3, 0, 0);
}
else if (SRCCOPY == Rop3)
{
NtGdiStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest,
DcSrc, XSrc, YSrc, WidthSrc, HeightSrc,
Rop3, 0);
}
else
{
DcStretched = NtGdiCreateCompatibleDC(DcSrc);
if (NULL == DcStretched)
{
DPRINT1("Failed to create compatible DC\n");
return;
}
if (Color)
{
BitmapStretched = NtGdiCreateCompatibleBitmap(DcDest, WidthDest,
HeightDest);
}
else
{
BitmapStretched = IntGdiCreateBitmap(WidthDest, HeightDest, 1, 1, NULL);
}
if (NULL == BitmapStretched)
{
NtGdiDeleteObjectApp(DcStretched);
DPRINT1("Failed to create temporary bitmap\n");
return;
}
OldBitmap = NtGdiSelectObject(DcStretched, BitmapStretched);
if (NULL == OldBitmap)
{
NtGdiDeleteObject(BitmapStretched);
NtGdiDeleteObjectApp(DcStretched);
DPRINT1("Failed to create temporary bitmap\n");
return;
}
if (! NtGdiStretchBlt(DcStretched, 0, 0, WidthDest, HeightDest,
DcSrc, XSrc, YSrc, WidthSrc, HeightSrc,
SRCCOPY, 0) ||
! NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest,
DcStretched, 0, 0, Rop3, 0, 0))
{
DPRINT1("Failed to blt\n");
}
NtGdiSelectObject(DcStretched, OldBitmap);
NtGdiDeleteObject(BitmapStretched);
NtGdiDeleteObjectApp(DcStretched);
}
}
#else
#define DoStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest, \
DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, Rop3, Color) \
NtGdiStretchBlt((DcDest), (XDest), (YDest), (WidthDest), (HeightDest), \
(DcSrc), (XSrc), (YSrc), (WidthSrc), (HeightSrc), \
(Rop3), 0)
#endif /* STRETCH_CAN_SRCCOPY_ONLY */
BOOL
UserDrawIconEx(
HDC hDc,
INT xLeft,
INT yTop,
PCURICON_OBJECT pIcon,
INT cxWidth,
INT cyHeight,
UINT istepIfAniCur,
HBRUSH hbrFlickerFreeDraw,
UINT diFlags)
{
BOOL Ret = FALSE;
HBITMAP hbmMask, hbmColor;
BITMAP bmpMask, bmpColor;
COLORREF oldFg, oldBg;
BOOL DoFlickerFree;
INT nStretchMode;
SIZE IconSize;
HDC hdcOff;
HGDIOBJ hOldOffBrush = 0;
HGDIOBJ hOldOffBmp = 0;
HBITMAP hbmOff = 0;
HDC hdcMem = 0;
HGDIOBJ hOldMem;
BOOL bAlpha = FALSE;
hbmMask = pIcon->IconInfo.hbmMask;
hbmColor = pIcon->IconInfo.hbmColor;
if(istepIfAniCur)
DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
{
return FALSE;
}
if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
{
return FALSE;
}
if(hbmColor)
{
IconSize.cx = bmpColor.bmWidth;
IconSize.cy = bmpColor.bmHeight;
}
else
{
IconSize.cx = bmpMask.bmWidth;
IconSize.cy = bmpMask.bmHeight / 2;
}
if (bmpColor.bmBitsPixel == 32)
{
bAlpha = TRUE;
}
if(!diFlags)
diFlags = DI_NORMAL;
if(!cxWidth)
cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
UserGetSystemMetrics(SM_CXICON) : IconSize.cx);
if(!cyHeight)
cyHeight = ((diFlags & DI_DEFAULTSIZE) ?
UserGetSystemMetrics(SM_CYICON) : IconSize.cy);
DoFlickerFree = (hbrFlickerFreeDraw &&
(GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH));
if(DoFlickerFree)
{
RECT r;
r.right = cxWidth;
r.bottom = cyHeight;
hdcOff = NtGdiCreateCompatibleDC(hDc);
if(!hdcOff)
{
DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
return FALSE;
}
hbmOff = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
if(!hbmOff)
{
DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n");
goto cleanup;
}
hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw);
if(!hOldOffBrush)
{
DPRINT1("NtGdiSelectObject() failed!\n");
goto cleanup;
}
hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff);
if(!hOldOffBmp)
{
DPRINT1("NtGdiSelectObject() failed!\n");
goto cleanup;
}
NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
}
else hdcOff = hDc;
hdcMem = NtGdiCreateCompatibleDC(hDc);
if(!hdcMem)
{
DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
goto cleanup;
}
nStretchMode = NtGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS);
oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0));
oldBg = NtGdiSetBkColor(hdcOff, RGB(255, 255, 255));
if(diFlags & DI_MASK)
{
hOldMem = NtGdiSelectObject(hdcMem, hbmMask);
if(!hOldMem)
{
DPRINT("NtGdiSelectObject() failed!\n");
goto cleanup;
}
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
(DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
0, 0, IconSize.cx, IconSize.cy,
((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), FALSE);
if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth)
&& (diFlags & DI_IMAGE))
{
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
(DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
0, IconSize.cy, IconSize.cx, IconSize.cy, SRCINVERT,
FALSE);
diFlags &= ~DI_IMAGE;
}
NtGdiSelectObject(hdcMem, hOldMem);
}
if(diFlags & DI_IMAGE)
{
hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask));
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
(DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
0, (hbmColor ? 0 : IconSize.cy), IconSize.cx, IconSize.cy,
((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY),
NULL != hbmColor);
NtGdiSelectObject(hdcMem, hOldMem);
}
if(DoFlickerFree)
{
if (bAlpha)
{
BITMAPINFO bi;
BITMAP bm;
BITMAPOBJ *Bitmap = NULL;
PBYTE pBits = NULL;
BLENDFUNCTION BlendFunc;
BYTE Red, Green, Blue, Alpha;
DWORD Count = 0;
INT i, j;
/* Bitmap header */
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = cxWidth;
bi.bmiHeader.biHeight = cyHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = cxWidth * cyHeight * 4;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
Bitmap = GDIOBJ_LockObj(GdiHandleTable, hbmOff, GDI_OBJECT_TYPE_BITMAP);
if (Bitmap == NULL)
{
DPRINT1("GDIOBJ_LockObj() failed!\n");
goto cleanup;
}
BITMAP_GetObject(Bitmap, sizeof(BITMAP), &bm);
/* Buffer */
pBits = ExAllocatePoolWithTag(PagedPool, bm.bmWidthBytes * abs(bm.bmHeight), TAG_BITMAP);
if (pBits == NULL)
{
DPRINT1("ExAllocatePoolWithTag() failed!\n");
GDIOBJ_UnlockObjByPtr(GdiHandleTable, Bitmap);
goto cleanup;
}
/* get icon bits */
IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
/* premultiply with the alpha channel value */
for (i = 0; i < cyHeight; i++)
{
for (j = 0; j < cxWidth; j++)
{
DWORD OrigPixel = 0;
DWORD AlphaPixel = 0;
OrigPixel = *(DWORD *)(pBits + Count);
Red = (BYTE)((OrigPixel >> 0) & 0xff);
Green = (BYTE)((OrigPixel >> 8) & 0xff);
Blue = (BYTE)((OrigPixel >> 16) & 0xff);
Alpha = (BYTE)((OrigPixel >> 24) & 0xff);
Red = (Red * Alpha) / 0xff;
Green = (Green * Alpha) / 0xff;
Blue = (Blue * Alpha) / 0xff;
AlphaPixel = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24));
*(DWORD *)(pBits + Count) = AlphaPixel;
Count += sizeof (DWORD);
}
}
/* set icon bits */
IntSetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
ExFreePool(pBits);
GDIOBJ_UnlockObjByPtr(GdiHandleTable, Bitmap);
BlendFunc.BlendOp = AC_SRC_OVER;
BlendFunc.BlendFlags = 0;
BlendFunc.SourceConstantAlpha = 255;
BlendFunc.AlphaFormat = AC_SRC_ALPHA;
NtGdiAlphaBlend(hDc, xLeft, yTop, cxWidth, cyHeight,
hdcOff, 0, 0, cxWidth, cyHeight, BlendFunc, 0);
}
else
{
NtGdiBitBlt(hDc, xLeft, yTop, cxWidth,
cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
}
}
NtGdiSetTextColor(hdcOff, oldFg);
NtGdiSetBkColor(hdcOff, oldBg);
NtGdiSetStretchBltMode(hdcOff, nStretchMode);
Ret = TRUE;
cleanup:
if(DoFlickerFree)
{
if(hOldOffBmp) NtGdiSelectObject(hdcOff, hOldOffBmp);
if(hOldOffBrush) NtGdiSelectObject(hdcOff, hOldOffBrush);
if(hbmOff) NtGdiDeleteObject(hbmOff);
if(hdcOff) NtGdiDeleteObjectApp(hdcOff);
}
if(hdcMem) NtGdiDeleteObjectApp(hdcMem);
return Ret;
}
/*
* @implemented
*/
BOOL
STDCALL
NtUserDrawIconEx(
HDC hdc,
int xLeft,
int yTop,
HICON hIcon,
int cxWidth,
int cyHeight,
UINT istepIfAniCur,
HBRUSH hbrFlickerFreeDraw,
UINT diFlags,
DWORD Unknown0,
DWORD Unknown1)
{
PCURICON_OBJECT pIcon;
BOOL Ret;
DPRINT("Enter NtUserDrawIconEx\n");
UserEnterExclusive();
if(!(pIcon = UserGetCurIconObject(hIcon)))
{
DPRINT1("UserGetCurIconObject() failed!\n");
UserLeave();
return FALSE;
}
Ret = UserDrawIconEx(hdc,
xLeft,
yTop,
pIcon,
cxWidth,
cyHeight,
istepIfAniCur,
hbrFlickerFreeDraw,
diFlags);
UserLeave();
return Ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -