OLE 拖放如何工作

当执行 OLE 拖放操作时,在源端和目标端会产生某些事件。无论拖放操作是自动操作还是手工操作,都总要生成与源对象关联的事件。但是,只在手工拖放操作时才生成目标端事件。下图说明在拖动源会有什么事件发生并可得到响应,以及在放目标会有什么事件发生并可得到响应。

图 11.6 源端事件和目标端事件

需要响应哪个事件取决于如何实现拖放功能。例如,可能已创建了一个具有文本框的应用程序并希望该文本框能够自动接受从其它应用程序拖动来的数据。这种情况下直接将控件的 OLEDropMode 属性设置为“自动化”。如果还希望能从文本框控件中自动拖动数据,则应将其 OLEDragMode 属性设置为“自动化”。

但是,如果希望改变缺省鼠标光标或增强按钮状态和 shift 键的功能,则需手工响应源端和目标端事件。同样,如果希望在将数据放到控件之前就对其进行分析(例如检查数据是否兼容),或者在将数据加载到 DataObject 对象时延迟若干时间(这样,在开始时就不必加载多个格式),则必须使用手工 OLE 拖放操作。

因为可将数据拖动到众多具有不同限制和要求的 Visual Basic 控件或 Windows 应用程序中,所以实现 OLE 拖放的难度,从简单到复杂,极为不同。当然,最简单的实现方式是在两个自动对象之间拖放,无论对象是 Word 文档、Excel 电子数据表,还是应用程序中设置为“自动化”的控件。对拖放目标指定多个可接受的数据格式,这将更加复杂。

启动拖动

在 Visual Basic 应用程序的基本手工 OLE 拖放操作过程中究竟发生了什么?当用户选定数据并按下鼠标左按钮,因而从 OLE 拖动源(例如,一个文本框控件)拖动数据时将触发 OLEStartDrag 事件,然后就可存贮数据,也可直接指定源所支持的格式。还需指明,源允许复制数据还是允许移动数据,还是两种方法都允许。

详细信息 关于 OLEDrag 方法、OLEstartDrag 事件、如何使用 SetData 方法指定可支持的数据格式和如何将数据放到 DataObject 中的详细信息,请参阅“启动 OLE 拖动操作”。

在目标上拖动数据

在拖动数据经过目标时会触发目标的 OLEDragOver 事件,这表明源位于目标的边界内。而后,如果在这里放下数据,则应指定目标要执行的操作─ 或者是复制、移动,拒绝数据。按照约定,缺省操作通常是移动,但也可以是复制。

如果在这里放下源,则目标指定所产生的拖放效果,此时将触发一个 OLEGiveFeedback 事件。用这个事件向用户提供视觉反馈,当放下选定数据时,按照该反馈执行操作─ 也就是说,鼠标指针将发生变化,以指示操作的类型是复制、移动,还是“不放”。

当源在目标边界内移动时─ 或者若用户按住鼠标按钮的同时按下了 SHIFT、CTRL 或 ALT 键─ 拖放效果可能会改变。例如,数据可能被拒绝,而不是被复制或移动。

例如,如果移动时超出目标的边界或按 ESC 键,则可能会取消或修改拖动操作(鼠标指针可能发生变化,指出当前所经过的对象不接受数据)。

详细信息 关于 OLEDragOver 和 OLEGiveFeedback 事件详细信息,请参阅“将 OLE 拖动源拖到 OLE 拖放目标的上方”。

完成拖动

当把源放到目标时将触发目标的 OLEDragDrop 事件。目标就源所包含的数据的格式(若拖动开始时未将数据放在源中,则就源所支持的格式)查询源,然后获取数据或拒绝数据。

如果在拖动开始时就已存储数据,则目标将使用 GetData 方法获取数据。如果在拖动开始时未存储数据,则通过触发 OLESetData 事件并使用 SetData 方法获取数据。

在接受数据或拒绝数据时将触发 OLECompleteDrag 事件,而后,源将执行相应操作:例如,如果接受数据并指定一个移动,则源将删除数据。

详细信息 关于 OLEDragDrop 事件、OLECompleteDrag 事件及如何使用 GetFormat 和 GetData 方法从 DataObject 对象中获取数据的详细信息,请参阅“将 OLE 拖动源放到 OLE 拖放目标上”。