5

私は持っている

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 ) はまだ機能しません。ルーチンの先頭に移動すると (2 回実行されるため)、機能します。

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 の最初の起動と同様に、これは時期尚早であることが示唆されています。他の場所で私のコードに何か問題があると確信していますが、何が原因でしょうか?

4

3 に答える 3

8

TWinControl の HWND は、その有効期間中に何度でも作成および再作成できます。DragAcceptFiles() を呼び出すのに最適な場所は、オーバーライドされた CreateWnd() および DestroyWnd() メソッド内です。これにより、すべての (再) 作成中に (再) 登録し、すべての破棄中に登録を解除できます。次に例を示します。

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

procedure TMainForm.DestroyWnd;
begin 
  DragAcceptFiles(Handle, False);
  inherited;
end;
于 2010-10-13T22:55:28.673 に答える
1

アプリケーションで複数回発生するFormShowイベントは、フォームのハンドルが破棄され、少なくとも1回再作成されたことを示しています。これは、ウィンドウハンドルの再作成が必要なプロパティの1つを変更したことが原因である可能性があります。トップネスの変更は一例です。

ハンドルが再作成された場合、新しいハンドルはもちろん、前のハンドルが受信するように登録されたメッセージを受信しません。

あなたがする必要があるのはDragAcceptFiles()、最終的なハンドルが作成された後、または(それは難しいかもしれないので)実際に複数回呼び出すことです。

于 2010-10-13T21:09:22.927 に答える
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 以外の名前を付けます。

于 2010-10-13T21:14:36.300 に答える