I was wondering why the command "showmessage" is executed before the application form appears, I mean, whenever I run the program, first appears the message, then the application form:
procedure TForm1.FormCreate(Sender: TObject);
begin
button1.hide;
button2.hide;
image3.picture.loadfromfile('c:\EAS\std.bmp');
showmessage ('Hi');
end;
end.
The first thing delphi does, it to show the message "Hi". Then it does the rest (Form appeared, hide buttons, load images etc). Even though showmessage is last, it is executed first. How do I make the message appear after the form is appeared, the buttons are hiden are the image is loaded?
The reason is that the form is created (hence, OnCreate is fired), before it is shown.
Solution 1
One solution is to post a window message to the form when the form is created. Try this:
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.
Solution 2
A different solution is to make use of the OnActivate event, which is called every time the form obtains keyboard focus: Add a private field FMessageShown: boolean to the form class. Then, in OnActivate, if the flag is false (as it is by default, being a field of a class), then display your message and set the flag to 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.
In practice, both methods work perfectly. The downside of the first solution is that it may rely somewhat on 'implementation details', while the downside of the latter one is quite obvious: you check a flag every time the form regets keyboard focus, even weeks after the form was initially created and the message was shown.
Solution 3
A solution that has neither disadvantage, but assumes that you won't need the OnActivate event for some other purpouse, is simply to 'unassign' the event after its first (hence, only) execution:
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.
(This approach, however, can be extended to cases where you do need the event for other purpouses too, if you replace OnActivate := nil by OnActivate := MySecondEventHandler.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With