3

アプリケーションフォームが表示される前にコマンド「showmessage」が実行されるのはなぜだろうと思っていました。つまり、プログラムを実行すると、最初にメッセージが表示され、次にアプリケーションフォームが表示されます。

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

end.

Delphi が最初に行うことは、「こんにちは」というメッセージを表示することです。その後、残りの処理を行います (フォームの表示、ボタンの非表示、画像の読み込みなど)。showmessage は最後ですが、最初に実行されます。フォームが表示された後にメッセージを表示するにはどうすればよいですか? ボタンが非表示になり、画像が読み込まれますか?

ありがとう

4

1 に答える 1

6

その理由は、フォームが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 := nilOnActivate := MySecondEventHandler

于 2013-04-21T13:40:57.883 に答える