【问题标题】:Ending or Cancelling a Drag Drop Operation in a Delphi Application在 Delphi 应用程序中结束或取消拖放操作
【发布时间】:2016-09-15 02:48:56
【问题描述】:

我正在从 Outlook 中拖放电子邮件附件。 文件被放入虚拟树视图中。

我在拖拽事件结束时的导入功能需要一段时间来处理文件,它会冻结 Outlook 应用程序,直到功能结束。

我希望能够在函数中途结束拖动操作。

procedure TForm.vstItemsDragDrop(Sender: TBaseVirtualTree;
  Source: TObject; DataObject: IDataObject; Formats: TFormatArray;
  Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);
var
  fileList          : IStringList;
  drop              : IOleDrop;
begin
  fileList:= TIStringList.Create;

  drop := COleDrop.Create.def(DataObject);
  fileList := drop.GetDroppedFileList(fileWarnings);

  //I want to terminate the drag operator here because I already have what I need

  //This imports parts takes a while to run so I want to end the drag and drop operation
  //Outlook freezes still has cursor state on copy and doesn't respond to clicks or ESC
  ImportParts( fileList)    
end;

【问题讨论】:

  • AFAIK,在程序退出之前,您无法取消操作。您可以做的是将列表保存在某处(例如,在表单类声明中声明的变量),将自定义消息发布到您的窗口句柄,然后继续并退出拖放过程。然后,您在处理程序中处理您的列表,以处理您之后发布给自己的自定义消息。

标签: delphi drag-and-drop ole virtualtreeview tvirtualstringtree


【解决方案1】:

我通常只是在 Drop 事件中获取信息(即不处理它),然后向我的表单发送一条消息,告知有新信息需要处理。因此,Drop 事件会很快退出,然后消息处理程序会拾取并处理任何被丢弃的内容。

在你的情况下,你应该做这样的事情:

CONST
  WM_PROCESS_DROPPED_FILES = WM_USER+42;

TYPE
  TMainForm = CLASS(TForm)
                .
                .
              PRIVATE
                fileList : IStringList; // Ie. move the declaration here...
                PROCEDURE ProcessFiles(VAR MSG : TMessage); MESSAGE WM_PROCESS_DROPPED_FILES;
                .
                .
              END;

在你的 drop 事件中,删除 fileList 的声明(你已经将它设为表单的私有成员而不是局部变量)并替换

ImportParts(fileList)

PostMessage(Handle,WM_PROCESS_DROPPED_FILES)

然后实施

PROCEDURE TMainForm.ProcessFiles(VAR MSG : TMessage);
  BEGIN
    ImportParts(fileList)
  END;

可能需要将fileList变量改为TStringList并复制那里的信息,以防在Drop事件退出时结束对IStringList的引用,但一般原则是相同的- 不处理 Drop 事件中的数据,推迟到 Drop 事件退出后处理。

【讨论】:

  • 使用这种技术,您可以推迟处理,直到您的消息到达消息循环。它仍然会在主线程中运行并阻塞 UI,只是稍后。用户仍然无法取消处理。
  • @OndrejKelle:正确 - 但它也不会阻止“发送”应用程序(本例中为 Outlook)。如果阻塞“接收”应用程序也是一个问题,那么应该实现队列和/或后台线程。本质还是一样——尽快退出Drop事件,从“发送”应用中释放“锁”。
猜你喜欢
  • 1970-01-01
  • 2014-07-05
  • 2010-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
相关资源
最近更新 更多