Delphi7,Showmessage命令在应用程序窗体出现之前执行
我想知道为什么“showmessage”命令在应用程序窗体出现之前执行,我的意思是,每当我运行程序时,首先出现消息,然后出现应用程序窗体:Delphi7,Showmessage命令在应用程序窗体出现之前执行,delphi,action,message,Delphi,Action,Message,我想知道为什么“showmessage”命令在应用程序窗体出现之前执行,我的意思是,每当我运行程序时,首先出现消息,然后出现应用程序窗体: procedure TForm1.FormCreate(Sender: TObject); begin button1.hide; button2.hide; image3.picture.loadfromfile('c:\EAS\std.bmp'); showmessage ('Hi'); end; end. delphi做的第一件事就是显示消息“Hi
procedure TForm1.FormCreate(Sender: TObject);
begin
button1.hide;
button2.hide;
image3.picture.loadfromfile('c:\EAS\std.bmp');
showmessage ('Hi');
end;
end.
delphi做的第一件事就是显示消息“Hi”。然后它完成其余的工作(表单显示、隐藏按钮、加载图像等)。即使showmessage是最后一个,它也是首先执行的。在窗体显示、按钮隐藏和图像加载后,如何使消息显示
感谢原因是表单在显示之前已创建(因此,
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
。然后,在激活的中,如果标志为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.
实际上,这两种方法都非常有效。第一种解决方案的缺点是,它可能在某种程度上依赖于“实现细节”,而后一种解决方案的缺点是非常明显的:每次表单regets键盘焦点时都会检查一个标志,甚至在表单最初创建和消息显示数周后也是如此
解决方案3
一个既没有缺点,又假定您不需要为其他目的而激活事件的解决方案,就是在事件第一次(因此仅)执行后“取消分配”事件:
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:=nil
替换为OnActivate:=MySecondEventHandler
),这种方法可以扩展到您确实需要用于其他目的的事件的情况下)我宁愿将OnShow
事件的消息发布到自身。@TLama:但是如果表单被隐藏,然后再次显示,消息将再次出现。但您可能可以在OnCreate
中发布消息。回答!请随意将其包含在您的答案中。您的想法是从OnCreate
事件发布该消息。关键是您不需要依赖异步消息分派。目标是在窗口出现在屏幕上时执行某些操作。因为系统会通知你,在我看来,最好对此做出回应。所以伙计们,在你们进行了很长时间的讨论之后:P,哪一个是最好的方法?