cursoricon.c
来自「一个类似windows」· C语言 代码 · 共 1,531 行 · 第 1/3 页
C
1,531 行
CurInfo = IntGetSysCursorInfo(WinSta);
if(CurInfo->CursorClipInfo.IsClipped)
{
Rect.left = CurInfo->CursorClipInfo.Left;
Rect.top = CurInfo->CursorClipInfo.Top;
Rect.right = CurInfo->CursorClipInfo.Right;
Rect.bottom = CurInfo->CursorClipInfo.Bottom;
}
else
{
Rect.left = 0;
Rect.top = 0;
Rect.right = UserGetSystemMetrics(SM_CXSCREEN);
Rect.bottom = UserGetSystemMetrics(SM_CYSCREEN);
}
Status = MmCopyToCaller((PRECT)lpRect, &Rect, sizeof(RECT));
if(!NT_SUCCESS(Status))
{
ObDereferenceObject(WinSta);
SetLastNtError(Status);
RETURN( FALSE);
}
ObDereferenceObject(WinSta);
RETURN( TRUE);
CLEANUP:
DPRINT("Leave NtUserGetClipCursor, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @implemented
*/
HCURSOR
STDCALL
NtUserSetCursor(
HCURSOR hCursor)
{
PCURICON_OBJECT CurIcon;
HICON OldCursor;
PWINSTATION_OBJECT WinSta;
DECLARE_RETURN(HCURSOR);
DPRINT("Enter NtUserSetCursor\n");
UserEnterExclusive();
WinSta = IntGetWinStaObj();
if(WinSta == NULL)
{
RETURN(NULL);
}
if(!(CurIcon = UserGetCurIconObject(hCursor)))
{
ObDereferenceObject(WinSta);
RETURN(NULL);
}
OldCursor = IntSetCursor(WinSta, CurIcon, FALSE);
ObDereferenceObject(WinSta);
RETURN(OldCursor);
CLEANUP:
DPRINT("Leave NtUserSetCursor, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* @implemented
*/
BOOL
STDCALL
NtUserSetCursorIconContents(
HANDLE hCurIcon,
PICONINFO IconInfo)
{
PCURICON_OBJECT CurIcon;
PBITMAPOBJ bmp;
PWINSTATION_OBJECT WinSta;
NTSTATUS Status;
BOOL Ret = FALSE;
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 = NtGdiCreateBitmap(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 */
/*
* @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 CurIcon;
PWINSTATION_OBJECT WinSta;
HBITMAP hbmMask, hbmColor;
BITMAP bmpMask, bmpColor;
BOOL DoFlickerFree;
SIZE IconSize;
COLORREF oldFg, oldBg;
HDC hdcMem, hdcOff = (HDC)0;
HBITMAP hbmOff = (HBITMAP)0;
HGDIOBJ hOldOffBrush = 0, hOldOffBmp = 0, hOldMem;
BOOL Ret = FALSE;
INT nStretchMode;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserDrawIconEx\n");
UserEnterExclusive();
WinSta = IntGetWinStaObj();
if(WinSta == NULL)
{
RETURN( FALSE);
}
if (!(CurIcon = UserGetCurIconObject(hIcon)))
{
ObDereferenceObject(WinSta);
RETURN(FALSE);
}
hbmMask = CurIcon->IconInfo.hbmMask;
hbmColor = CurIcon->IconInfo.hbmColor;
if(istepIfAniCur)
DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
goto done;
if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
goto done;
if(hbmColor)
{
IconSize.cx = bmpColor.bmWidth;
IconSize.cy = bmpColor.bmHeight;
}
else
{
IconSize.cx = bmpMask.bmWidth;
IconSize.cy = bmpMask.bmHeight / 2;
}
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 && (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_BRUSH));
if(DoFlickerFree)
{
RECT r;
r.right = cxWidth;
r.bottom = cyHeight;
hdcOff = NtGdiCreateCompatibleDC(hdc);
if(!hdcOff)
goto done;
hbmOff = NtGdiCreateCompatibleBitmap(hdc, cxWidth, cyHeight);
if(!hbmOff)
{
NtGdiDeleteObjectApp(hdcOff);
goto done;
}
hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw);
hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff);
NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
NtGdiSelectObject(hdcOff, hbmOff);
}
hdcMem = NtGdiCreateCompatibleDC(hdc);
if(!hdcMem)
goto cleanup;
if(!DoFlickerFree)
hdcOff = hdc;
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);
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)
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)
{
NtGdiSelectObject(hdcOff, hOldOffBmp);
NtGdiSelectObject(hdcOff, hOldOffBrush);
NtGdiDeleteObject(hbmOff);
NtGdiDeleteObjectApp(hdcOff);
}
if(hdcMem)
NtGdiDeleteObjectApp(hdcMem);
done:
ObDereferenceObject(WinSta);
RETURN( Ret);
CLEANUP:
DPRINT("Leave NtUserDrawIconEx, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?