首页 > 解决方案 > Delphi 将文件从 Windows 资源管理器拖放到 TListView 不起作用

问题描述

我正在使用 Delphi 10.3 社区版。我正在尝试将文件从 Windows 文件夹拖放到我的应用程序中,但是当我将文件拖放到表单上时,不会调用 Windows 消息处理程序。

这就是我目前所拥有的:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  protected
    procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
    ShellApi;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin

    // Disable drag accept files
    DragAcceptFiles(Self.Handle, true);

end;

procedure TForm1.FormCreate(Sender: TObject);
begin

    // Enable drag accept files
    DragAcceptFiles(Self.Handle, true);

end;

procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);
begin

    // Show a message
    ShowMessage('File dropped');

    // Set the message result
    Msg.Result := 0;

    inherited;

end;

end.

就像我说的,当我将文件拖放到表单上时,我可以看到将文件拖放到表单上时会被接受,但是当我放下文件时,WMDropFiles不会调用该过程。

我也尝试DragAcceptFilesCreateWnd程序中启用。但它仍然不起作用。

...
public
    procedure CreateWnd; override;
    procedure DestroyWnd; override;

...

procedure TForm1.CreateWnd;
begin

  inherited;
  DragAcceptFiles(Handle, True);

end;

procedure TForm1.DestroyWnd;
begin

  DragAcceptFiles(Handle, False);
  inherited;

end;

我什至尝试以管理员身份运行 Delpi IDE。这可能是社区版的限制还是我遗漏了什么?

附录

我现在添加了一个按钮来发送消息WM_DROPFILES

procedure TForm1.Button1Click(Sender: TObject);
begin
    SendMessage(Self.Handle, WM_DROPFILES, Integer(self), 0);
end;

当我单击按钮时,将WMDropFiles调用该过程。那么它就起作用了。

标签: delphiwinapi

解决方案


好的,很有趣。我找到了这篇文章:

如何在 Vista/Windows 7 上为提升的 MFC 应用程序启用拖放功能

所以我在我的表单创建过程中添加了以下内容:

procedure TForm1.FormCreate(Sender: TObject);
begin


    // Enable drag accept files
    DragAcceptFiles(Form1.Handle, true);

    ChangeWindowMessageFilter (WM_DROPFILES, MSGFLT_ADD);
    ChangeWindowMessageFilter (WM_COPYDATA, MSGFLT_ADD);
    ChangeWindowMessageFilter ($0049, MSGFLT_ADD);

end;

现在它正在工作!


推荐阅读