その理由は、フォームがOnCreate
表示される前に作成される (したがって、起動される) ためです。
解決策 1
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 := nil
OnActivate := MySecondEventHandler