내 응용 프로그램 로그 파일에 로깅 TLogger 클래스에서 일하고 있어요 ...델파이 XE5는 이상한 행동 도움말
내가 잇는 TMemo에 파일에서 로그를 얻는 방식이 필요 그런 다음 TLogger 클래스에 DisplayInMemo 속성에 True를 할당 한 다음 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.
만 차이는 볼 수 있듯이 LDesplayInMemo : True이면 TMemo가 로그로 채 웁니다 ... False 일 때 TMemo에서 결과를 얻으려면 버튼 4를 2 번 클릭해야합니다 ...
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를 시도했습니다.