⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cursoricon.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
   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 */

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;
   }

   /* A hack to get alpha-blending support for icons.
      Disabled now because of a bug in alpha blending function
      (which blends with white background instead of the background).
    */
   /*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 && 
      (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_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)
        {
            BLENDFUNCTION  BlendFunc;
            BlendFunc.BlendOp = AC_SRC_OVER; /* right ? */
            BlendFunc.BlendFlags = 0;
            BlendFunc.SourceConstantAlpha = 255;
            BlendFunc.AlphaFormat = AC_SRC_ALPHA;
            NtGdiAlphaBlend(hDc, xLeft, yTop, cxWidth, cyHeight, 
                            hdcOff, 0, 0, cxWidth, cyHeight, BlendFunc);
        }
        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 + -