如何让IDropTarget在Delphi中使用我的Drop Handler?

时间:2010-08-31 21:22:43

标签: delphi drag-and-drop registry associations

我已将文件扩展名与我的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可能更适合我。

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

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,我的程序可以打开所有点击的文件吗?

2 个答案:

答案 0 :(得分:1)

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

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

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

这听起来像是很多工作,但是一旦你真正进入它,它就不是很多了。我最近在我的一个C ++ Builder VCL应用程序中实现了IDropTarget支持,并且没有花很长时间才能使它工作。

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

答案 1 :(得分:1)

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