I am using a piece of software that David Heffernan has shared here:
How can I allow a form to accept file dropping without handling Windows messages?
I have changed the component from a Form to a Panel, and that works fine in the MainForm.
However, when using in a ShowModal()
environment, I do not have access to the values of components in the modal Form.
I made a small demo to show the problem.
Unit1:
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.
Unit2:
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.
The DragAndDrop
unit has the unchanged code as made by David.
I have demonstrated the problem here with Label1
.
When I am in the Drop()
procedure and ask for the Form2.Label1.Caption
, it shows the Label1
value from design-time, or the value as assigned in FormCreate()
, but not the value from FormActivate()
or assigned later in the program.
It looks like there are 2 forms.
PS1: Works fine when in the MainForm.
PS2: Changing Form2
to nil
in TmyPanel.Create(Form2)
does not change the behaviour.
PS3: Moving the Create()
function to OnActivate
does not change the behaviour.
PS4. I'm using Delphi XE4.
Does anyone have an idea what is wrong in this ShowModal()
example?