![]() |
Logging in Form aus anderer Unit steuern
Hallo,
ich habe eine Prozedur, welche bei der Auslösung eines Events ausgeführt wird.
Delphi-Quellcode:
Das Event
procedure TfrmMain.ConsoleLineOut(const Line: String);
begin Log.Lines.Add(Line); end;
Delphi-Quellcode:
ConsoleLineOut.OnLineOut := ConsoleLineOutLineOut; wird aber in einer anderen Unit ausgelöst. Ich will keine Referenz auf die Form Klasse, da sonst eine zirkuäre Abhängigkeit entsteht und Logik nichts in der Form zu suchen hat. Wenn also das Event in meiner anderen Unit ausgelöst wird, dann soll in den Log vom Typ TMemo in der Form ein Lines.Add ausgeführt werden. Kann man das überhaupt irgendwie machen, ohne das die beiden Klassen sich kennen? Gibt es Trace Klassen etc.? Danke Vielmals PS: Oder gibts eine Quick and Dirty Variante? Gleiches Problem, leider ungelöst: ![]() |
AW: Logging in Form aus anderer Unit steuern
Ich mache das ganze über Messages.
In der Form, in der auch das Logging geschieht, gibt es die Methode WMWriteLog.
Delphi-Quellcode:
procedure WMWriteLog(var AMessage : TMessage); message WM_WRITELOG;
Delphi-Quellcode:
An den Stellen, wo ich etwas an das Log übergeben will nutze ich dann "SendMessage" um meinen Text zu an die Form zu schicken.
procedure TfrmMain.WMWriteLog(var AMessage: TMessage);
var lMessage : PChar; begin lMessage := PChar(AMessage.WParam); if (Length(lMessage) > 0) then FLog.Add(lMessage); StrDispose(lMessage); end;
Delphi-Quellcode:
Ob das nun die sauberste Lösung ist, kann ich nicht versprechen - sie funktioniert aber.
procedure WriteLog(AMessage: string);
var lMessage : PChar; begin lMessage := StrAlloc(Succ(Length(AMessage))); StrPCopy(lMessage, AMessage); SendMessage(FParentHandle, WM_WRITELOG, integer(lMessage), 0); Application.ProcessMessages; end; |
AW: Logging in Form aus anderer Unit steuern
OK ich hänge an der Stelle, wo ich dem SendMessage ein Objekt vom Typ HWND übergeben muss. Dieses erzeuge ich durch beispielsweise self.handle. Mein Objekt vom Typ meiner Klasse hat aber kein Handle. Wie kann ich das hinzufügen oder muss ich einen eigenen Handler schreiben.
Was ist HWND überhaupt für ein typ? Danke vielmals aber für die Idee |
AW: Logging in Form aus anderer Unit steuern
HWND ist ein Fensterhandle.
|
AW: Logging in Form aus anderer Unit steuern
Wenn man das Logging elegant und flexibel machen möchte, dann braucht man zunächst eine abstrakte Basisklasse oder ein Interface.
Delphi-Quellcode:
Davon werden nun eine oder mehrere konkrete Logging-Klassen abgeleitet:
unit MyLogger; // eigene Unit
interface type TCustomLogger=class(TPersistent) public procedure LogMsg(level:integer; const msg:string);virtual;abstract; end;
Delphi-Quellcode:
Im Hauptformular oder dort wo man die Log-Ausgabe sehen möchte erzeugt man ein Objekt der Klasse TStringsLogger:
TStringsLogger = class(TCustomLogger)
private FList : TStrings; public constructor Create(list:TStrings); // "level" dient dazu, verschieden Logmeldung (Fehler, Warnung, Info) // voneinander zu trennen procedure LogMsg(level:integer; const msg:string);override; end; implementation constructor TStringsLogger.Create(list:TStrings); begin inherited Create; FList := list; end; procedure TStringsLogger.LogMsg(level:integer; const msg:string);override; begin FList.Add(TimeToStr(Now)+' ('+IntToStr(level)+') '+msg; end;
Delphi-Quellcode:
Der "Trick" ist nun, dass das Hauptformular das Logger-Objekt in das Unterformular einspeist.
procedure TFrmMain.FormCreate(Sender:TObject);
begin // Logger-Objekt erzeugen und gleich an ein Memo-Feld anbinden FLogger := TStringsLogger.Create(MemoLog.Lines); end; procedure TfrmMain.ConsoleLineOut(const Line: String); begin Flogger.LogMsg(0, Line); end; Man nennt das Dependency Injection.
Delphi-Quellcode:
Das Unterformular sieht so aus:
procedure TFrmMain.ZeigeUnterformular;
begin if not Assigned(FrmIrgendwas) then FrmIrgendwas := TFrmIrgendwas.Create(Application); FrmIrgendwas.Logger := FLogger; // Logger-Objekt weitergeben/einspeisen FrmIrgendwas.Show; end;
Delphi-Quellcode:
Sourcecode ohne Delphi-IDE eingehackt-kleine Schreibfehler bitte selber korrigieren
uses MyLogger;
TFrmIrgendwas = Class(TForm) ... public // wird von aussen zugewiesen Logger : TCustomLogger; Procedure Test; end; Procedure TFrmIrgendwas.Test; begin Logger.LogMsg(99, 'Das ist eine Log-Meldung aus TFrmIrgendwas.Test'); end; Das Hauptformular und das Unterformular arbeiten jetzt mit dem gleichen Logger-Objekt. Meldungen vom Hauptformular und vom Unterformular laufen über das Logger-Objekt in ein gemeinsames Memo-Feld. Man könnte die Klasse TStringsLogger leicht durch eine andere Klasse z.B. TFileLogger austauschen und die Log-Ausgabe in eine Datei schreiben. Auch ein Kombination aus direkter Anzeige und Schreiben in eine Datei ist möglich. Die Klassenstruktur die ich hier gezeigt habe ist flexibel und ohne zirkuläre Abhängigkeiten. Mit einem Interface anstelle einer abstrakten Basisklasse ist noch mehr möglich, aber das soll erst einmal reichen. |
AW: Logging in Form aus anderer Unit steuern
Danke Vielmals. Das ist eine gute Antwort!
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz