2010-10-13 49 views
4

德爾福 - 當調用DragAcceptFiles

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

但形式不接受拖文件 - 沒有下降光標,沒有WM_DROPFILES消息的發射。

我有以下我FormShow事件構建(出於不同的原因 - 有代碼,我想創建表格後,只執行一次,並FormShow在初始化過程中燒製不止一次):

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)在所示位置仍然不起作用。如果我將它移動到程序的頂部(所以它執行兩次),它的工作:

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 ; 

所有我發現的示例代碼似乎在OnCreate中調用DragAccept。我的實驗表明這還爲時過早,OnShow的第一場火災也是如此。我確定其他地方的代碼有問題,但是可能會導致這種情況?

回答

7

任何TWinControl的HWND都可以在其生命週期內多次創建和重新創建。最好的地方調用DragAcceptFiles()是在被覆蓋的CreateWnd方法()和DestroyWnd()方法,這樣就可以(重新)在所有的(再)創造註冊和註銷過程中的所有破壞,如:

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

procedure TMainForm.DestroyWnd; 
begin 
    DragAcceptFiles(Handle, False); 
    inherited; 
end; 
+0

這是最乾淨的方法。非常感謝。 – rossmcm 2010-10-14 00:29:06

1

在您的應用程序中多次觸發的FormShow事件表明窗體的句柄至少被銷燬並重新創建一次,這很可能是因爲您更改了需要重新創建窗口句柄的屬性之一。改變持久性是一個例子。

如果句柄被重新創建,那麼新的句柄當然不會收到前一個句柄被註冊接收的任何消息。

你需要做的是在創建最終句柄或者(可能很難做到)多次後調用DragAcceptFiles()

+0

我覺得這是關鍵。我並沒有意識到,在整個表格的整個生命週期中,句柄可能會有所不同。 – rossmcm 2010-10-13 21:27:08

1

我發現像這樣的問題很容易通過您在FormCreate中發佈給自己的自定義消息來處理。例如:

CONST 
    wm_FirstRun = WM_USER + 101; 


TYPE 
    TForm1 = class(TForm) 
    : 
    Procedure wmFirstRun(var Msg:tMessage); message wm_FirstRun; 
    procedure FormCreate(Sender: TObject); 
    : 
    end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    // other initialization code 
    PostMessage(handle,wm_FirstRun,0,0); 
end; 

Procedure TForm1.wmFirstRun(var Msg:tMessage); 
begin 
    // handle the code here that will run once the form is processing messages 
end; 

的觸發機制是PostMessage,所以每當你調用一個命令,它會調用您的自定義郵件程序。當然,如果是這樣的話,我會稱之爲wmFirstRun以外的東西。

+0

你是說你把dragacceptFiles放在這個消息處理程序中可以確保它在oncreate和onshow事件之後被調用嗎? – rossmcm 2010-10-13 21:34:58

+1

是的,但只有一次,因爲它是在onCreate中請求的。 – skamradt 2010-10-13 21:40:29

+0

我注意到一些答案已經消失。誰這樣做,爲什麼? – rossmcm 2010-10-14 00:33:03