2012-01-02 3 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

그래, 좋은 생각이야. 고맙습니다. –

관련 문제