Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi - when to call DragAcceptFiles

I have

procedure TMainForm.FormCreate(Sender: TObject);
begin
DragAcceptFiles (Handle, True ) ; 
end ;

but the form does not accept dragged files - no drop cursor, no firing of WM_DROPFILES message.

I had the following construct in my FormShow event (for a different reason - there was code I wanted to execute only once after the form was created, and FormShow was firing more than once during initialisation) :

procedure TMainForm.FormShow(Sender: TObject);

begin
if (not FRunOnce) then  // as FormShow can be called twice - if Form.Position assigned to
    begin
    DragAcceptFiles (Handle, True ) ; 
    FRunOnce := True ;
    end ;
end ;

DragAcceptFiles (Handle, True ) in the position shown still doesn't work. If I move it to the top of the routine (so it executes twice), it does work:

procedure TMainForm.FormShow(Sender: TObject);

begin
DragAcceptFiles (Handle, True ) ; 
if (not FRunOnce) then  // as FormShow can be called twice - if Form.Position assigned to
    begin
    FRunOnce := True ;
    end ;
end ;

All the example code I have found seems to call DragAccept during OnCreate. My experiments suggest this is too early, as is the first fire of OnShow. I'm sure something is wrong with my code elsewhere but what might be causing this?

like image 458
rossmcm Avatar asked Oct 13 '10 21:10

rossmcm


2 Answers

Any TWinControl's HWND can be created and recreated multiple times during its lifetime. The best place to call DragAcceptFiles() is in overriden CreateWnd() and DestroyWnd() methods so that you can (re)register during all (re)creations and unregister during all destructions, eg:

procedure TMainForm.CreateWnd;
begin 
  inherited;
  DragAcceptFiles(Handle, True);  
end;

procedure TMainForm.DestroyWnd;
begin 
  DragAcceptFiles(Handle, False);
  inherited;
end;
like image 129
Remy Lebeau Avatar answered Oct 03 '22 00:10

Remy Lebeau


The FormShow event firing more than once in your application is a sign that the handle of the form is destroyed and recreated at least once, most probably because you change one of the properties that requires the window handle to be recreated. Changing the stay-on-topness is one example.

If the handle is recreated then the new one will of course not receive any messages the previous handle was registered to receive.

What you need to do is to call DragAcceptFiles() after the final handle has been created, or (as that may be hard to do) indeed multiple times.

like image 34
mghie Avatar answered Oct 02 '22 23:10

mghie