我正在研究 TLogger 类,它将我的应用程序日志记录到文件中......
我必须将日志从文件获取到 TMemo: 1. 将 TMemo 分配给 TLogger 类,然后将 True 分配给 DisplayInMemo 属性,然后调用 GetLogFromFile(); 2.调用GetLogsFromFile();然后 Self.Memo1.Text := TLogger.LogsResult;
下面...注释的解决方案工作正常...未注释的解决方案仅每 2 次单击按钮 4 有效
procedure TForm1.Button4Click(Sender: TObject); // get log.file to memo
begin
// automatic forwarding logs from File to TMemo - it works!
//logger.DisplayMemo := Self.Memo1;
//logger.DisplayInMemo := True;
//logger.GetLogsFromFile();
// tested - half-automatic method of formwarding logs to TMemo - works every 2 clicks :(
logger.DisplayInMemo := False;
logger.GetLogsFromFile();
Self.Memo1.Text := logger.LogsResult;
end;
整个 TLogger 实现:
unit Logger;
interface
uses
System.IOUtils, System.TypInfo, System.SysUtils, FMX.Forms, FMX.Dialogs, System.Classes, FMX.Graphics, FMX.ExtCtrls, LoggerThread, FMX.Memo;
type
TLogger = class
private
FileName : String; // name of file to log
FilePath : String; // path to app / log-file
LStringResult : String; // result of thread log.file reading
LLoggerMemo : TMemo; // copy of memo - place where GetLogsFromFile put results
LDisplayInMemo : Boolean; // bool - if True GetLogsFromFile puts results to DisplayMemo, otherwise waiting in LogsResult
NewLoggerThread : TLoggerThread; // thread object - created in Create()
procedure GetLogsFromFileThreadTerminateHandler(sender: TObject);
public
constructor Create(); overload; // open or create 'development.log'
constructor Create(LogFileName : String); overload; // open or create LogFileName for logging
destructor Destroy(); overload; // cleaner of TLogger object
// main procedures
procedure Log(LogString : String); // add line to log file
procedure GetLogsFromFile(); // get all logs from log file to string
// settings, reading results,
property DisplayInMemo : Boolean read LDisplayInMemo write LDisplayInMemo; //bool - if True GetLogsFromFile puts results to DisplayMemo, otherwise waiting in LogsResult
property LogsResult : String read LStringResult write LStringResult; //string results after Getters from TLogger usage
property DisplayMemo : TMemo read LLoggerMemo write LLoggerMemo; // sets TMemo where results will be put if DisplayInMemo set to True
end;
implementation
constructor TLogger.Create();
begin
{$IFDEF Android}
FilePath := TPath.GetDownloadsPath + System.SysUtils.PathDelim;
{$ELSE}
FilePath := ExtractFilePath(ParamStr(0));
{$ENDIF}
FileName := 'development.log';
LDisplayInMemo := False;
// inherited
inherited Create;
end;
constructor TLogger.Create(LogFileName : String);
begin
{$IFDEF Android}
FilePath := TPath.GetDownloadsPath + System.SysUtils.PathDelim;
//TPath.Combine(TPath.GetDocumentsPath,'test.txt'); // to have / \ auto-change
{$ELSE}
FilePath := ExtractFilePath(ParamStr(0));
{$ENDIF}
FileName := LogFileName;
LDisplayInMemo := False;
// inherited
inherited Create;
end;
destructor TLogger.Destroy();
begin
inherited Destroy;
end;
// adds a sigle line to log file with date time
procedure TLogger.Log(LogString : String);
begin
NewLoggerThread := TLoggerThread.Create(True);
NewLoggerThread.FreeOnTerminate := True;
NewLoggerThread.Log := LogString; //log to write - date time then added in execute
NewLoggerThread.LoggerInstruction := TLoggerInstruction.liLogToFile; //set instuction for thread - LogToFile
NewLoggerThread.FileName := FileName; //file to write
NewLoggerThread.FilePath := FilePath; //path to file
try
NewLoggerThread.Start;
except
NewLoggerThread.Free();
end;
end;
// results String with LogFile content
procedure TLogger.GetLogsFromFile();
begin
NewLoggerThread := TLoggerThread.Create(True);
NewLoggerThread.FreeOnTerminate := True;
NewLoggerThread.OnTerminate := GetLogsFromFileThreadTerminateHandler;
NewLoggerThread.FileName := FileName; //file to write
NewLoggerThread.FilePath := FilePath; //path to file
NewLoggerThread.LoggerInstruction := TLoggerInstruction.liGetLogsFromFile; //set instuction for thread - GetLogFromFile
try
NewLoggerThread.Start;
except
NewLoggerThread.Free();
end;
end;
procedure TLogger.GetLogsFromFileThreadTerminateHandler(sender: TObject);
begin
LStringResult := (Sender as TLoggerThread).StringResult;
if LDisplayInMemo then
LLoggerMemo.Text := (Sender as TLoggerThread).StringResult;
end;
end.
正如您所看到的,唯一的区别在于 LDisplayInMemo:如果是 True TMemo 会填充日志......什么时候是 False 我需要在按钮 4 上单击 2 次才能在 TMemo 中获得结果......
procedure TLogger.GetLogsFromFileThreadTerminateHandler(sender: TObject);
begin
LStringResult := (Sender as TLoggerThread).StringResult;
if LDisplayInMemo then
LLoggerMemo.Text := (Sender as TLoggerThread).StringResult;
end;
有任何想法吗?老实说,我不知道这两种解决方案工作不同的原因是什么:(我也在 Self.Memo1.Text := logger.LogsResult; 之后尝试了 ProcessMessages