2012-01-02 14 views
1

コントロールが完全に初期化されているかどうかを確認するにはどうすればよいですか?
次のコード(私はそれがこれを行うには非常に悪い習慣を知っている、例としてそれを取るしてください)コントロールが完全に初期化されたときをチェックする方法?

type 
    TForm1 = class(TForm) 
    Memo1: TMemo; 
    private 
    procedure WndProc(var Message: TMessage); override; 
    public 
    { Public declarations } 
    end; 

procedure TForm1.WndProc(var Message: TMessage); 
begin 
{ 
    I'd like to log the messages to the memo as soon 
    as it's possible so I need to find out how to 
    check if the memo box is ready to use; the following 
    code stuck the application, so that the form is not 
    even displayed. How would you fix this code except 
    "avoid using of component access in window proc" ? 
} 

    if Assigned(Memo1) then 
    if Memo1.HandleAllocated then 
     Memo1.Lines.Add('Message: ' + IntToStr(Message.Msg)); 

    inherited WndProc(Message); 
end; 

P.S.を考えてみましょう私はOutputDebugStringを知っています:-)
ありがとう!

+1

私は混乱しています。あなたは何を正確にしたいですか? 1)メッセージループ中で発生したすべての 'Message.Msg'をMemo1に記録するか、' Form1やMemo1'の初期化の完了を記録するか?それを明確にすることはできますか? – menjaraz

+0

@menjaraz "メッセージループ"と言うときは注意してください。それは単にキューに入れられたメッセージです。待ち行列に入れられていないメッセージも 'WndProc'を通過します。 –

+1

@David Heffernan:それを指摘していただきありがとうございます。 SOは実際には学ぶのに最適な場所です。 – menjaraz

答えて

4

あなたの質問はむしろ私を混乱させました。あなたが言った場合:

ログメッセージをメモ

にあなたが何を意味するか、あなたがメモにテキストを書き込むことで、フォームにメッセージを記録したいということです。

メモに書き込むときにフォームにメッセージが送信されるため、メモに書き込む結果となり、スタックのオーバーフローが避けられない結果になるため、このアプローチは危険に満ちています。

私は、あなたの考えを再入門保護を入れて管理することができました。また、コントロールを表示する準備が整う前に配信されるメッセージをキャプチャするために、一時的な非ビジュアル文字列リストを導入しました。これを紹介すると、メモに追加するのが安全な、最も早い瞬間を見つけることを心配する必要はなくなりました。

unit LoggingHack; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; 

type 
    TLoggingForm = class(TForm) 
    Memo1: TMemo; 
    private 
    FLog: TStringList; 
    FLogging: Boolean; 
    protected 
    procedure WndProc(var Message: TMessage); override; 
    public 
    destructor Destroy; override; 
    end; 

var 
    LoggingForm: TLoggingForm; 

implementation 

{$R *.dfm} 

{ TLoggingForm } 

destructor TLoggingForm.Destroy; 
begin 
    FreeAndNil(FLog); 
    inherited; 
end; 

procedure TLoggingForm.WndProc(var Message: TMessage); 
var 
    Msg: string; 
begin 
    if not FLogging then begin 
    FLogging := True; 
    Try 
     Msg := IntToStr(Message.Msg); 
     if Assigned(Memo1) and Memo1.HandleAllocated then begin 
     if Assigned(FLog) then begin 
      Memo1.Lines.Assign(FLog); 
      FreeAndNil(FLog); 
     end; 
     Memo1.Lines.Add(Msg); 
     end else if not (csDestroying in ComponentState) then begin 
     if not Assigned(FLog) then begin 
      FLog := TStringList.Create; 
     end; 
     FLog.Add(Msg); 
     end; 
    Finally 
     FLogging := False; 
    End; 
    end; 
    inherited; 
end; 

end. 

end; 

話の教訓は、あなたがはあなたがログインしようとしているものと相互作用しない、より適切なロギングフレームワークを使用する必要があるということです。

+0

Davidさん、サブクラス化について聞いたことがありますが、私の質問は「フォームのウィンドウプロシージャからそのメモにアクセスする方法」です。メモの使用準備が整ったことを確認する方法(フォームとそのすべてのコントロールにアクセスする準備ができています)を意味します。 –

+0

@ Martin私は今質問を理解しています。言葉は私を混乱させた。ごめんなさい。 –

+0

ええ、それは良い考えです。ありがとうございました。 –

関連する問題