【发布时间】:2021-09-08 12:06:37
【问题描述】:
我正在使用 David Heffernan 在此处分享的软件:
How can I allow a form to accept file dropping without handling Windows messages?
我已将组件从表单更改为面板,并且在 MainForm 中运行良好。
但是,当在ShowModal() 环境中使用时,我无法访问模态表单中组件的值。
我做了一个小演示来展示这个问题。
单元1:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
protected
Public
End;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
Var aForm: TForm2;
Begin
aForm := TForm2.Create(Nil);
Try
aForm.ShowModal;
Finally
aForm.Free;
End;
End;
End.
单元2:
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, DragAndDrop;
type
TmyPanel = class(TPanel, IDragDrop)
private
FDropTarget: TDropTarget;
// implement IDragDrop
function DropAllowed(const FileNames: array of string): Boolean;
procedure Drop(const FileNames: array of string);
protected
// procedure WMDropFiles(var Message: TWMDropFiles); message WM_DROPFILES;
procedure CreateWindowHandle(Const Params: TCreateParams); override;
procedure DestroyWindowHandle; override;
end;
TForm2 = class(TForm)
DropRefPanel: TPanel;
Label1: TLabel;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormActivate(Sender: TObject);
procedure Button1Click(Sender: TObject);
{ Private declarations }
public
{ Public declarations }
DropPanel: TmyPanel;
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TmyPanel.CreateWindowHandle(Const Params: TCreateParams);
begin
inherited;
FDropTarget := TDropTarget.Create(WindowHandle, Self);
end;
procedure TmyPanel.DestroyWindowHandle;
begin
FreeAndNil(FDropTarget);
inherited;
end;
function TmyPanel.DropAllowed(const FileNames: array of string): Boolean;
begin
Result := True;
end;
procedure TmyPanel.Drop(const FileNames: array of string);
Var i: Integer;
begin
// Form2.Label1.Caption := 'Drop';
begin
for i := 0 to Length(FileNames)-1 do
ShowMessage(Form2.Label1.Caption + ': ' + FileNames[i]);
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
showMessage(Label1.Caption);
Label1.Caption := 'Button';
end;
procedure TForm2.FormActivate(Sender: TObject);
begin
Label1.Caption := 'Activation';
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
Label1.Caption := 'FormCreate';
DropRefPanel.Color := $00BBF7B3 -50;
DropPanel := TmyPanel.Create(Form2);
with DropPanel do
begin
Parent := DropRefPanel;
Left := 3;
Top := 3;
Width := DropRefPanel.Width - 6;
Height := DropRefPanel.Height - 6;
Visible := True;
ParentBackground := False;
Color := $00BBF7B3;
BevelOuter := bvLowered;
Caption := 'DropBox';
end;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(DropPanel);
end;
end.
DragAndDrop 单元的代码与 David 相同。
我在这里用Label1 演示了这个问题。
当我在Drop() 过程中并请求Form2.Label1.Caption 时,它会显示设计时的Label1 值,或FormCreate() 中分配的值,而不是FormActivate() 中的值或稍后分配的值在程序中。
好像有两种形式。
PS1:在 MainForm 中工作正常。
PS2:将TmyPanel.Create(Form2) 中的Form2 更改为nil 不会改变行为。
PS3:将 Create() 函数移动到 OnActivate 不会改变行为。
PS4。我正在使用 Delphi XE4。
有人知道这个ShowModal() 示例中有什么问题吗?
【问题讨论】:
-
Unit2.dfm 文件中是否存在 FormActivate?或者:在 FormCreate 中设置此值:
OnActivate := FormActivate。我怀疑赋值已经丢失。 -
@Usauter 感谢您的反应。 .dfm 文件中确实存在 Formactivate。
标签: delphi modalpopup