nam*_*los 30 c# mouse icons screenshot cursor
这是来自原始文章.
static Bitmap CaptureCursor(ref int x, ref int y)
{
Bitmap bmp;
IntPtr hicon;
Win32Stuff.CURSORINFO ci = new Win32Stuff.CURSORINFO();
Win32Stuff.ICONINFO icInfo;
ci.cbSize = Marshal.SizeOf(ci);
if (Win32Stuff.GetCursorInfo(out ci))
{
if (ci.flags == Win32Stuff.CURSOR_SHOWING)
{
hicon = Win32Stuff.CopyIcon(ci.hCursor);
if (Win32Stuff.GetIconInfo(hicon, out icInfo))
{
x = ci.ptScreenPos.x - ((int)icInfo.xHotspot);
y = ci.ptScreenPos.y - ((int)icInfo.yHotspot);
Icon ic = Icon.FromHandle(hicon);
bmp = ic.ToBitmap();
return bmp;
}
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
Tar*_*ier 29
虽然我无法解释为什么会发生这种情况,但我想我可以展示如何解决这个问题.
ICONINFO结构包含两个成员hbmMask和hbmColor,它们分别包含光标的掩码和颜色位图(有关官方文档,请参阅ICONINFO的MSDN页面).
当您为默认光标调用GetIconInfo()时,ICONINFO结构包含有效的掩码和颜色位图,如下所示(注意:已添加红色边框以清楚地显示图像边界):
默认光标掩码位图 默认光标掩码位图图像http://img4.imageshack.us/img4/1108/arrowmask.png
默认光标颜色位图 默认光标颜色位图图像http://img191.imageshack.us/img191/7680/arrowcolor.png
当Windows绘制默认光标时,首先使用AND光栅操作应用蒙版位图,然后使用XOR光栅操作应用颜色位图.这导致不透明的光标和透明背景.
但是,当你为I-Beam光标调用GetIconInfo()时,ICONINFO结构只包含一个有效的掩码位图,而没有颜色位图,如下所示(注意:再次添加红色边框以清楚地显示图像边界) ):
I-Beam光标掩码位图 ibeam光标掩码位图图像http://img14.imageshack.us/img14/6025/ibeammask.png
根据ICONINFO文档,I-Beam光标是单色光标.掩码位图的上半部分是AND掩码,掩码位图的下半部分是XOR位图.当Windows绘制I-Beam光标时,首先使用AND光栅操作在桌面上绘制此位图的上半部分.然后使用XOR光栅操作在顶部绘制位图的下半部分.屏幕,光标将显示为其背后内容的反转.
您链接的原始文章的评论之一提到了这一点.在桌面上,由于光栅操作应用于桌面内容,因此光标将显示正确.但是,如果图像是在没有背景的情况下绘制的,就像在发布的代码中一样,Windows执行的光栅操作会导致图像褪色.
话虽这么说,这个更新的CaptureCursor()方法将处理彩色和单色光标,当光标是单色时提供纯黑色光标图像.
static Bitmap CaptureCursor(ref int x, ref int y)
{
Win32Stuff.CURSORINFO cursorInfo = new Win32Stuff.CURSORINFO();
cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);
if (!Win32Stuff.GetCursorInfo(out cursorInfo))
return null;
if (cursorInfo.flags != Win32Stuff.CURSOR_SHOWING)
return null;
IntPtr hicon = Win32Stuff.CopyIcon(cursorInfo.hCursor);
if (hicon == IntPtr.Zero)
return null;
Win32Stuff.ICONINFO iconInfo;
if (!Win32Stuff.GetIconInfo(hicon, out iconInfo))
return null;
x = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot);
y = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot);
using (Bitmap maskBitmap = Bitmap.FromHbitmap(iconInfo.hbmMask))
{
// Is this a monochrome cursor?
if (maskBitmap.Height == maskBitmap.Width * 2)
{
Bitmap resultBitmap = new Bitmap(maskBitmap.Width, maskBitmap.Width);
Graphics desktopGraphics = Graphics.FromHwnd(Win32Stuff.GetDesktopWindow());
IntPtr desktopHdc = desktopGraphics.GetHdc();
IntPtr maskHdc = Win32Stuff.CreateCompatibleDC(desktopHdc);
IntPtr oldPtr = Win32Stuff.SelectObject(maskHdc, maskBitmap.GetHbitmap());
using (Graphics resultGraphics = Graphics.FromImage(resultBitmap))
{
IntPtr resultHdc = resultGraphics.GetHdc();
// These two operation will result in a black cursor over a white background.
// Later in the code, a call to MakeTransparent() will get rid of the white background.
Win32Stuff.BitBlt(resultHdc, 0, 0, 32, 32, maskHdc, 0, 32, Win32Stuff.TernaryRasterOperations.SRCCOPY);
Win32Stuff.BitBlt(resultHdc, 0, 0, 32, 32, maskHdc, 0, 0, Win32Stuff.TernaryRasterOperations.SRCINVERT);
resultGraphics.ReleaseHdc(resultHdc);
}
IntPtr newPtr = Win32Stuff.SelectObject(maskHdc, oldPtr);
Win32Stuff.DeleteObject(newPtr);
Win32Stuff.DeleteDC(maskHdc);
desktopGraphics.ReleaseHdc(desktopHdc);
// Remove the white background from the BitBlt calls,
// resulting in a black cursor over a transparent background.
resultBitmap.MakeTransparent(Color.White);
return resultBitmap;
}
}
Icon icon = Icon.FromHandle(hicon);
return icon.ToBitmap();
}
Run Code Online (Sandbox Code Playgroud)
代码存在一些问题,可能是也可能不是问题.
小智 10
[StructLayout(LayoutKind.Sequential)]
struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINTAPI ptScreenPos;
}
[StructLayout(LayoutKind.Sequential)]
struct POINTAPI
{
public int x;
public int y;
}
[DllImport("user32.dll")]
static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll")]
static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon);
const Int32 CURSOR_SHOWING = 0x00000001;
public static Bitmap CaptureScreen(bool CaptureMouse)
{
Bitmap result = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format24bppRgb);
try
{
using (Graphics g = Graphics.FromImage(result))
{
g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
if (CaptureMouse)
{
CURSORINFO pci;
pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(CURSORINFO));
if (GetCursorInfo(out pci))
{
if (pci.flags == CURSOR_SHOWING)
{
DrawIcon(g.GetHdc(), pci.ptScreenPos.x, pci.ptScreenPos.y, pci.hCursor);
g.ReleaseHdc();
}
}
}
}
}
catch
{
result = null;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22327 次 |
| 最近记录: |