【问题标题】:How do I get IDropTarget to work with my Drop Handler in Delphi?如何让 IDropTarget 与 Delphi 中的 Drop Handler 一起工作?
【发布时间】:2010-08-31 21:22:42
【问题描述】:

我已将文件扩展名与我的 Delphi 2009 程序相关联。我一直在使用命令行调用方法将文件名传递给我的 Delphi 程序,以便可以打开它。

但是,我发现在选择多个文件时,并立即单击它们时,它将在我程序的单独实例中打开每个文件。 I asked about this,显然解决方案是使用one of the other two Windows methods: DDE or IDropTarget

但 DDE 已被弃用,MSDN 推荐使用 IDropTarget 方法。 Lars Truijens in his answer to me 还表示,如果我已经在运行拖放功能,IDropTarget 可能更适合我。

目前,这是我的放置处理程序:

private
  procedure WMDropFiles(var WinMsg: TMessage);
            message wm_DropFiles;

procedure TLogoAppForm.FormShow(Sender: TObject);
begin
  DragAcceptFiles(Handle, true);
end;

procedure TLogoAppForm.WMDropFiles(var WinMsg: TMessage);
// From Delphi 3 - User Interface Design, pg 170
const
  BufSize = 255;
var
  TempStr : array[0..BufSize] of Char;
  NumDroppedFiles, I: integer;
  Filenames: TStringList;
begin
  NumDroppedFiles := DragQueryFile(TWMDropFiles(WinMsg).Drop, $ffffffff, nil, 0);
  if NumDroppedFiles >= 1 then begin
    Filenames := TStringList.Create;
    for I := 0 to NumDroppedFiles - 1 do begin
      DragQueryFile(TWMDropFiles(WinMsg).Drop, I, TempStr, BufSize);
      Filenames.Add(TempStr);
    end;
    OpenFiles(Filenames, '');
    Filenames.Free;
  end;
  DragFinish(TWMDropFiles(WinMsg).Drop);
  WinMsg.Result := 0;
end;

它现在接受一个或多个文件,并会根据我的需要打开它们。这是非常古老的代码,来自 Delphi 3 书籍,但它似乎仍然有效。

我在任何地方都找不到任何关于如何在 Delphi 中实现 IDropHandler 的文档,特别是让它与我正在使用的 Drop Handler(上图)一起工作。

谁能告诉我如何使用 IDropHandler,以便单击带有我的文件扩展名的选定文件会将它们传递给我的 Drop Handler,并且我的程序可以打开所有单击的文件?

【问题讨论】:

    标签: delphi drag-and-drop registry associations


    【解决方案1】:

    This page 有一个在 Delphi 中实现 IDropTarget 的示例。 Here 是 Jedi Code Formatter 的另一个成员。但是this library 可能会更好。除了其他功能外,它还支持从 Windows 资源管理器拖放,因此已经支持 TDropHandler 类中的 IDropTarget。

    【讨论】:

    【解决方案2】:

    使用 Delphi 的向导将标准 COM 进程外服务器对象添加到您的项目中,拥有它implement the IDropHandler interface(本文的代码是 C++,但许多概念也可以应用于 Delphi 代码,其中一些已由 VCL 为您实现),然后覆盖其虚拟 UpdateRegistry() 方法以添加一些额外的注册表项(请参阅上述文章的底部),以便您的 IDropHandler 对象使用Windows资源管理器双击和弹出菜单操作。

    然后,将您的应用代码更改为使用 RegisterDragDrop() 而不是 DragAcceptFiles(),这样用户仍然可以通过基于 IDropTarget 的类的实例将文件拖放到应用的窗口中。

    在 IDropHandler 方法的实现中,您可以查询传入的 IDataObject 接口,以查看它是否可以提供 HDROP 格式的数据,如果可以,则可以将其传递给现有的 WM_DROPFILES 消息处理程序(即旧的也被弃用了,顺便说一句,所以你应该考虑删除它)。

    这听起来像是很多工作,但一旦你真正进入它,它根本就不是很多。我最近在我的一个 C++Builder VCL 应用程序中实现了对 IDropTarget 的支持,并且完全不需要很长时间就能让它工作。

    IDropTarget 工作后,如果需要,您还可以支持许多其他 Shell 格式,例如从非文件系统源删除数据时。

    【讨论】:

    • 谢谢@Remy。你给了我很好的信息+1,但让我为代码工作。 @Lars 能够提示我代码示例。
    猜你喜欢
    • 2021-11-14
    • 1970-01-01
    • 2012-11-30
    • 2023-02-02
    • 2017-06-25
    • 2020-12-13
    • 2012-02-02
    • 2011-02-22
    • 2013-03-24
    相关资源
    最近更新 更多