4

使用“标准”VCL 拖放事件 OnDragOver 和 OnDragDrop,如何区分“复制”和“移动”操作?

我似乎没有可用的 TDragType,并且键盘 Shift 状态没有传递给这些事件。

4

4 回答 4

9

这不是您可以从事件中确定的,因为事件不会对您的应用程序需求或功能做出任何假设。

将特定的拖放解释为具有任何特定的语义是应用程序本身的责任 - 操作系统无法知道应用程序将如何对文件的放置做出反应,因此无法假设拖动操作可能对用户意味着什么。

对于许多应用程序来说,复制/移动之间没有区别,只有拖放。

复制/移动的区别是Windows 资源管理器应用于文件操作的东西。对于“vanilla”拖放,它应用基于原始和目标驱动器卷的规则 - 默认情况下,在卷上拖放文件是一种移动操作。默认情况下,跨卷拖放是一个副本

但这些只是由应用程序(Windows 资源管理器)确定的默认规则。用户可以在拖动过程中和(最重要的是)放下时使用键盘快捷键覆盖这些默认值。但这些是由特定应用程序定义和解释的——即Windows 资源管理器——而不是操作系统。

因此,如果您的应用程序是可能从Windows Explorer拖动的文件的放置目标,并且如果您的应用程序区分复制和移动是有意义的,那么您可能需要支持Windows Explorer支持的相同键盘修饰符. 我不相信这些是可修改的(尽管我建议确认这一点),因此您可以简单地测试拖动事件中 Ctrl 或 Shift 键的状态:

Ctrl         = COPY
Shift        = MOVE
Ctrl + Shift = MAKE SHORTCUT  (if this is applicable to your application)

GetKeyState()可用于在任何给定时刻直接询问特定键的状态。

如果需要不同的“默认”行为,那么您必须将自己的测试应用于源信息以确定哪个默认最有意义(即模仿Windows 资源管理器“卷边界”默认规则),或者只是选择最合适的或为您的应用程序提供直观的默认操作。

于 2009-08-18T21:51:40.760 回答
4

简短的回答是——你没有。VCL 的内置拖放系统不区分两者。但是,您可以派生自己的 TDragObject/Ex 类来控制实际拖动的数据类型。

于 2009-08-18T20:57:00.853 回答
4

如果您想在您的应用程序和其他 Windows 应用程序之间使用 Drag'n'Drop,那么值得一看 Anders Melander 的Drag and Drop Component Suite for Delphi
最新的代码在这里

于 2009-08-18T22:44:20.310 回答
0

具体不确定 Delphi,但在 C# 中,您检查事件参数的 AllowedEffect 属性。由于它们都链接回 Win32,我无法想象有太大的区别。

http://msdn.microsoft.com/en-us/library/system.windows.forms.drageventargs.aspx有一个很好的例子。希望这可以帮助!

于 2009-08-18T20:56:01.590 回答