Delphi7,Showmessage命令在应用程序表单出现之前执行

use*_*565 3 delphi message action

我想知道为什么命令"showmessage"在申请表出现之前执行,我的意思是,每当我运行程序时,首先出现消息,然后是申请表:

procedure TForm1.FormCreate(Sender: TObject);
begin
button1.hide;
button2.hide;
image3.picture.loadfromfile('c:\EAS\std.bmp');
showmessage ('Hi');
end;

end.
Run Code Online (Sandbox Code Playgroud)

delphi做的第一件事就是显示消息"Hi".然后它完成剩下的工作(表单出现,隐藏按钮,加载图像等).尽管showmessage是最后一个,但它首先被执行.如何在表单出现后显示消息,按钮是否隐藏图像是否已加载?

谢谢

And*_*and 6

原因是表单在OnCreate显示之前已创建(因此被触发).

解决方案1

一种解决方案是在创建表单时向窗体发布窗口消息.试试这个:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

const
  WM_GREETING = WM_USER + 1;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
  protected
    procedure WMGreeting(var Message: TMessage); message WM_GREETING;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  PostMessage(Self.Handle, WM_GREETING, 0, 0);
end;

procedure TForm1.WMGreeting(var Message: TMessage);
begin
  ShowMessage('Created and shown!');
end;

end.
Run Code Online (Sandbox Code Playgroud)

解决方案2

另一种解决方案是使用OnActivate事件,每次表单获得键盘焦点时调用该事件:FMessageShown: boolean向表单类添加私有字段.然后,OnActivate如果标志为false(因为它是默认情况下,是一个类的字段),则显示您的消息并将标志设置为true:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
    FMessageShown: boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormActivate(Sender: TObject);
begin
  if not FMessageShown then
  begin
    ShowMessage('Created and shown.');
    FMessageShown := true;
  end;
end;

end.
Run Code Online (Sandbox Code Playgroud)

在实践中,这两种方法都很完美.第一个解决方案的缺点是它可能在某种程度上依赖于"实现细节",而后者的缺点非常明显:每次表单重新设置键盘焦点时都会检查一个标记,即使表单最初创建后几周也是如此消息已显示.

解决方案3

一个既没有缺点但又假设你不需要OnActivate其他一些purpouse 的事件的解决方案,只是在第一次(因此,只执行)执行后"取消分配"事件:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormActivate(Sender: TObject);
begin
  ShowMessage('Created and shown.');
  OnActivate := nil;
end;

end.
Run Code Online (Sandbox Code Playgroud)

(但是,这种方法可以扩展到你确实需要其他purp事件的情况,如果你替换OnActivate := nilOnActivate := MySecondEventHandler.)