C# 如何从位图对象创建光标对象?
假设我有一个现有的C# 如何从位图对象创建光标对象?,c#,.net,winforms,bitmap,cursor,C#,.net,Winforms,Bitmap,Cursor,假设我有一个现有的System.Drawing.Bitmap对象,我如何创建一个System.Windows.Forms.Cursor对象,该对象的像素数据与我的Bitmap对象相同?这个答案取自。它允许您从位图对象创建光标并设置其热点 public struct IconInfo { public bool fIcon; public int xHotspot; public int yHotspot; public IntPtr hbmMask; pu
System.Drawing.Bitmap
对象,我如何创建一个System.Windows.Forms.Cursor
对象,该对象的像素数据与我的Bitmap
对象相同?这个答案取自。它允许您从位图对象创建光标并设置其热点
public struct IconInfo
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
[DllImport("user32.dll")]
public static extern IntPtr CreateIconIndirect(ref IconInfo icon);
/// <summary>
/// Create a cursor from a bitmap without resizing and with the specified
/// hot spot
/// </summary>
public static Cursor CreateCursorNoResize(Bitmap bmp, int xHotSpot, int yHotSpot)
{
IntPtr ptr = bmp.GetHicon();
IconInfo tmp = new IconInfo();
GetIconInfo(ptr, ref tmp);
tmp.xHotspot = xHotSpot;
tmp.yHotspot = yHotSpot;
tmp.fIcon = false;
ptr = CreateIconIndirect(ref tmp);
return new Cursor(ptr);
}
/// <summary>
/// Create a 32x32 cursor from a bitmap, with the hot spot in the middle
/// </summary>
public static Cursor CreateCursor(Bitmap bmp)
{
int xHotSpot = 16;
int yHotSpot = 16;
IntPtr ptr = ((Bitmap)ResizeImage(bmp, 32, 32)).GetHicon();
IconInfo tmp = new IconInfo();
GetIconInfo(ptr, ref tmp);
tmp.xHotspot = xHotSpot;
tmp.yHotspot = yHotSpot;
tmp.fIcon = false;
ptr = CreateIconIndirect(ref tmp);
return new Cursor(ptr);
}
然后你可以像这样调用函数:
DestroyIcon(myCursor.Handle);
这个答案来自于。它允许您从位图对象创建光标并设置其热点
public struct IconInfo
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
[DllImport("user32.dll")]
public static extern IntPtr CreateIconIndirect(ref IconInfo icon);
/// <summary>
/// Create a cursor from a bitmap without resizing and with the specified
/// hot spot
/// </summary>
public static Cursor CreateCursorNoResize(Bitmap bmp, int xHotSpot, int yHotSpot)
{
IntPtr ptr = bmp.GetHicon();
IconInfo tmp = new IconInfo();
GetIconInfo(ptr, ref tmp);
tmp.xHotspot = xHotSpot;
tmp.yHotspot = yHotSpot;
tmp.fIcon = false;
ptr = CreateIconIndirect(ref tmp);
return new Cursor(ptr);
}
/// <summary>
/// Create a 32x32 cursor from a bitmap, with the hot spot in the middle
/// </summary>
public static Cursor CreateCursor(Bitmap bmp)
{
int xHotSpot = 16;
int yHotSpot = 16;
IntPtr ptr = ((Bitmap)ResizeImage(bmp, 32, 32)).GetHicon();
IconInfo tmp = new IconInfo();
GetIconInfo(ptr, ref tmp);
tmp.xHotspot = xHotSpot;
tmp.yHotspot = yHotSpot;
tmp.fIcon = false;
ptr = CreateIconIndirect(ref tmp);
return new Cursor(ptr);
}
然后你可以像这样调用函数:
DestroyIcon(myCursor.Handle);
*您还需要手动使用DesroyIcon()API来释放使用GetHicon()检索的IntPtr。感谢链接,我将尝试一下该解决方案。这不是一个重复的问题,即使答案是相关的;这个问题是特定于具体情况的,而这个问题一般适用于您可能希望从位图创建光标的任何情况。光标不仅仅是位图。热点和遮罩不会从天而降。正如Hans指出的,Romoku链接的“可能重复”解决方案是不完整的,因为它没有显示如何设置热点。我在下面贴了一个更好的答案。这是什么问题的“复制品”?仅仅因为一个问题的答案与另一个问题的答案相同,这并不意味着它是同一个问题。*您还需要手动使用DesroyIcon()API来释放使用GetHicon()检索的IntPtr。感谢链接,我将尝试一下该解决方案。这不是一个重复的问题,即使答案是相关的;这个问题是特定于具体情况的,而这个问题一般适用于您可能希望从位图创建光标的任何情况。光标不仅仅是位图。热点和遮罩不会从天而降。正如Hans指出的,Romoku链接的“可能重复”解决方案是不完整的,因为它没有显示如何设置热点。我在下面贴了一个更好的答案。这是什么问题的“复制品”?仅仅因为一个问题与另一个问题的答案相同,这并不意味着它是同一个问题。从IntPtr句柄创建的游标在释放句柄时不会释放句柄。它会导致内存泄漏,除非使用手动释放Cursor.Handle.Good point,谢谢您的提醒!这不是一个好的观点,这是一个关键点。你能举例说明你是如何成功解决这个内存泄漏问题的吗?@Jazimov我已经用一个例子编辑了我的答案。谢谢。我一直在处理这个问题,现在的问题是在何处执行DestroyIcon操作--如果执行得太快,光标将无法正确显示…从IntPtr句柄创建的光标在释放句柄时不会释放句柄。它会导致内存泄漏,除非使用手动释放Cursor.Handle.Good point,谢谢您的提醒!这不是一个好的观点,这是一个关键点。你能举例说明你是如何成功解决这个内存泄漏问题的吗?@Jazimov我已经用一个例子编辑了我的答案。谢谢。我一直在处理这个问题,现在的问题是到底在哪里执行DestroyIcon操作——如果执行得太快,光标将无法正确显示。。。