代码之家  ›  专栏  ›  技术社区  ›  rossmcm

Delphi-何时调用DragAcceptFiles

  •  5
  • rossmcm  · 技术社区  · 14 年前

    我有

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

    但是表单不接受拖动的文件-没有放置光标,没有触发wm_drop files消息。

    我在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的第一场火灾。我确信我在其他地方的代码有问题,但这可能是什么原因造成的?

    3 回复  |  直到 14 年前
        1
  •  8
  •   Remy Lebeau    14 年前

    任何TwinControl的Hwnd都可以在其生存期内多次创建和重新创建。调用dragaAcceptFiles()的最佳位置是overriden createwnd()和destroywnd()方法,以便您可以(重新)在所有(重新)创建期间注册,并在所有销毁期间注销,例如:

    procedure TMainForm.CreateWnd;
    begin 
      inherited;
      DragAcceptFiles(Handle, True);  
    end;
    
    procedure TMainForm.DestroyWnd;
    begin 
      DragAcceptFiles(Handle, False);
      inherited;
    end;
    
        2
  •  1
  •   mghie    14 年前

    这个 FormShow 在应用程序中多次激发的事件表示窗体句柄至少被销毁并重新创建一次,很可能是因为更改了要求重新创建窗口句柄的属性之一。改变“保持顶端”就是一个例子。

    如果重新创建了句柄,那么新的句柄当然不会接收以前注册的句柄要接收的任何消息。

    你需要做的是打电话 DragAcceptFiles() 在最后一个句柄被创建之后,或者(这可能很难做到)确实多次。

        3
  •  1
  •   skamradt    14 年前

    我发现这样的问题很容易通过一条自定义消息来处理,您可以在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以外的东西。