3

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

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

end.

delphi 做的第一件事就是显示消息“Hi”。然后它会完成其余的工作(表单出现、隐藏按钮、加载图像等)。即使 showmessage 是最后一个,它也会首先执行。如何在表单出现后显示消息,隐藏按钮是否加载图像?

谢谢

4

1 回答 1

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.

解决方案 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.

在实践中,这两种方法都可以完美运行。第一个解决方案的缺点是它可能在某种程度上依赖于“实现细节”,而后一个解决方案的缺点非常明显:每次表单重新获得键盘焦点时,您都​​会检查一个标志,即使在表单最初创建几周后也是如此,并且该消息已显示。

解决方案 3

一个没有缺点但假设您不需要该OnActivate事件用于其他目的的解决方案只是在第一次(因此,仅)执行后“取消分配”事件:

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.

(但是,如果您将事件替换为,则这种方法可以扩展到您确实需要事件用于其他目的的情况。)OnActivate := nilOnActivate := MySecondEventHandler

于 2013-04-21T13:40:57.883 回答