如何将System.Windows.Input.Cursor转换为ImageSource

本文关键字:Cursor 转换 ImageSource Input Windows System | 更新日期: 2023-09-27 18:28:29

我有一个.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)

有人能告诉我把System.Windows.Input.Cursor转换成ImageSource的最佳方法吗?

那.ani游标呢?如果我没记错的话,System.Windows.Input.Cursor不支持动画光标,那么我该如何向用户显示它们呢?将它们转换为gif,然后使用3d派对gif库?

如何将System.Windows.Input.Cursor转换为ImageSource

我在这个线程中找到了解决方案:如何将透明光标渲染到保留位图的alpha通道?

这是代码:

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

它是为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();

希望能帮助到别人。。。