Sep*_*hrM 1 .net c# wpf cursor imagesource
我有一个 .cur 文件路径 ( "%SystemRoot%\cursors\aero_arrow.cur"),我想在图像控件中显示。所以我需要将 Cursor 转换为 ImageSource。我尝试了 CursorConverter 和 ImageSourceConverter 但没有运气。我还尝试从光标创建图形,然后将其转换为位图,但这也不起作用。
该线程说:
直接将 Cursor 转换为 Icon 很复杂,因为 Cursor 不公开它使用的图像源。
和
如果您确实想将图像绑定到光标,您可能想尝试一种方法。
由于WindowForm能够绘制光标,因此我们可以使用WindowForm在位图上绘制光标。之后我们可以找到一种方法将该位图复制到 WPF 支持的位置。
现在有趣的是,我无法创建System.Windows.Forms.Cursor既没有文件路径也没有流的新实例,因为它抛出以下异常:
System.Runtime.InteropServices.COMException (0x800A01E1):
Exception from HRESULT: 0x800A01E1 (CTL_E_INVALIDPICTURE)
at System.Windows.Forms.UnsafeNativeMethods.IPersistStream.Load(IStream pstm)
at System.Windows.Forms.Cursor.LoadPicture(IStream stream)
Run Code Online (Sandbox Code Playgroud)
System.Windows.Input.Cursor那么有人可以告诉我转换为的最佳方法吗ImageSource?
.ani 光标又如何呢?如果我没记错的话System.Windows.Input.Cursor不支持动画光标,那么我该如何向用户显示它们呢?将它们转换为 gif 然后使用 3d party gif 库?
我在这个线程中找到了解决方案:How to Render a Transparent Cursor to Bitmap saving alpha channel?
所以这是代码:
[StructLayout(LayoutKind.Sequential)]
private struct ICONINFO
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
[DllImport("user32")]
private static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO pIconInfo);
[DllImport("user32.dll")]
private static extern IntPtr LoadCursorFromFile(string lpFileName);
[DllImport("gdi32.dll", SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);
private Bitmap BitmapFromCursor(Cursor cur)
{
ICONINFO ii;
GetIconInfo(cur.Handle, out ii);
Bitmap bmp = Bitmap.FromHbitmap(ii.hbmColor);
DeleteObject(ii.hbmColor);
DeleteObject(ii.hbmMask);
BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
Bitmap dstBitmap = new Bitmap(bmData.Width, bmData.Height, bmData.Stride, PixelFormat.Format32bppArgb, bmData.Scan0);
bmp.UnlockBits(bmData);
return new Bitmap(dstBitmap);
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
//Using LoadCursorFromFile from user32.dll, get a handle to the icon
IntPtr hCursor = LoadCursorFromFile("C:\\Windows\\Cursors\\Windows Aero\\aero_busy.ani");
//Create a Cursor object from that handle
Cursor cursor = new Cursor(hCursor);
//Convert that cursor into a bitmap
using (Bitmap cursorBitmap = BitmapFromCursor(cursor))
{
//Draw that cursor bitmap directly to the form canvas
e.Graphics.DrawImage(cursorBitmap, 50, 50);
}
}
Run Code Online (Sandbox Code Playgroud)
它是为 Win Forms 编写的并绘制图像。但也可以在 wpf 中使用,并引用 System.Windows.Forms。然后您可以将该位图转换为位图源并将其显示在图像控件中...
我使用 System.Windows.Forms.Cursor 而不是 System.Windows.Input.Cursor 的原因是我无法使用 IntPtr 句柄创建新的光标实例...
编辑:上述方法不适用于具有低颜色位的光标。另一种方法是使用Icon.ExtractAssociatedIcon:
System.Drawing.Icon i = System.Drawing.Icon.ExtractAssociatedIcon(@"C:\Windows\Cursors\arrow_rl.cur");
System.Drawing.Bitmap b = i.ToBitmap();
Run Code Online (Sandbox Code Playgroud)
希望能帮助某人...