我可以为 C# Windows 应用程序拖放功能选择自定义图像吗?

Posted

技术标签:

【中文标题】我可以为 C# Windows 应用程序拖放功能选择自定义图像吗?【英文标题】:Can I choose a custom image for C# Windows Application Drag Drop functions? 【发布时间】:2011-07-01 23:34:44 【问题描述】:

我正在编写一个小项目,我想利用拖放功能来简化最终用户的一些操作。为了使应用程序更具吸引力,我想显示被拖动的对象。我找到了一些关于 WPF 的资源,但我不知道任何 WPF,所以对于这个单一任务来说,咬住整个主题变得有点困难。我想知道如何使用“常规”C# Windows 窗体来做到这一点。到目前为止,我发现的所有拖放教程都只是谈论拖放效果,这只是几个图标的预设。

WPF 听起来像是我想在这个项目之后学习的东西。

【问题讨论】:

【参考方案1】:

@Jesper 提供的博客链接提供了两到三个关键信息,但我认为值得将其引入 S.O.为后人。

设置自定义光标

下面的代码允许您使用任意图像作为光标

 public struct IconInfo
  
    public bool fIcon;
    public int xHotspot;
    public int yHotspot;
    public IntPtr hbmMask;
    public IntPtr hbmColor;
  

    [DllImport("user32.dll")]
    public static extern IntPtr CreateIconIndirect(ref IconInfo icon);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);

    public static Cursor CreateCursor(Bitmap bmp, int xHotSpot, int yHotSpot)
    
      IconInfo tmp = new IconInfo();
      GetIconInfo(bmp.GetHicon(), ref tmp);
      tmp.xHotspot = xHotSpot;
      tmp.yHotspot = yHotSpot;
      tmp.fIcon = false;
      return new Cursor(CreateIconIndirect(ref tmp));
    

设置拖放事件处理

这在其他教程和答案中有很好的介绍。我们在这里关注的具体事件是 GiveFeedback 和 DragEnter,在您希望自定义光标应用的任何控件上。

 private void DragSource_GiveFeedback(object sender, GiveFeedbackEventArgs e)
    
      e.UseDefaultCursors = 0;
    

   private void DragDest_DragEnter(object sender, DragEventArgs e)
    

      Cursor.Current = CreateCursor(bitmap, 0, 0);
     

【讨论】:

这段代码有一个严重的句柄泄漏,会在一段时间后让你的程序崩溃。请注意在 Bitmap.GetHicon() 方法的 MSDN 示例代码中使用 DestroyIcon()。必需,但必须在光标不再使用后 完成。使用 Reflection hack 可以让 Cursor 类自动为您执行此操作。 出色的观察力。上面的代码实际上确实在“一段时间后”轰炸了,对我来说,这只是在 6 到 10 次调用之后。【参考方案2】:

您需要隐藏默认光标并创建包含自定义图像的自己的窗口,然后使用鼠标位置移动该窗口。

你也可以看看http://web.archive.org/web/20130127145542/http://www.switchonthecode.com/tutorials/winforms-using-custom-cursors-with-drag-drop

2015 年 11 月 26 日更新

更新了指向 archive.org 的最后一个快照的链接

【讨论】:

以上是关于我可以为 C# Windows 应用程序拖放功能选择自定义图像吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 托盘中拖放 NotifyIcon

在 Windows 中拖放的通知

Windows 窗体 C#(拖放 100 个对象)

WPF 拖放 C# 也可以拖动图像

C# 拖放 - 使用基类的 e.Data.GetData

Visual Studio 2010 C# 表单项目 - 拖放 - 最佳方法?