我的工作是记录我的应用程序日志保存至文件TLogger类...
我必须让从文件记录到TMemo的方式:1分配TMemo到TLogger类,那么,分配给真实财产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:如果是真TMemo原木罢了......是假,当我需要点击两下就按钮4得到TMemo结果...
procedure TLogger.GetLogsFromFileThreadTerminateHandler(sender: TObject);
begin
LStringResult := (Sender as TLoggerThread).StringResult;
if LDisplayInMemo then
LLoggerMemo.Text := (Sender as TLoggerThread).StringResult;
end;
有任何想法吗? 说实话,我不知道什么是diffenerce在这两种解决方案的工作的原因:(我也Self.Memo1.Text后试图ProcessMessages:= logger.LogsResult;