請問關於memo1.lines.add的問題 |
答題得分者是:jow
|
mypigbaby
高階會員 發表:11 回覆:168 積分:155 註冊:2006-07-20 發送簡訊給我 |
不好意思
想請問大家一個問題 我在form上面放了一個memo1的元件 主要的用途是用來當log用的 現在問題來了 這個form裡面有一堆user define function 當每個function 如果有需要就會去執行Memo1.Lines.Add( 可是 這種function不會把訊息記錄到檔案去 我想過最笨的方法是 如果有Memo1.Lines.Add( 在下面就加一段指令把這些訊息寫到文字檔去 但是這個方法個人覺得太笨了 而Memo1.Lines.SaveToFile( 這個方法會把之前檔案的內容覆蓋掉 目前動到的腦筋是想把寫到檔案那段的code 加到Memo1.Lines.Add 這裡面 可是又不能去改到Classes及StdCtrls這二個原始碼(其他的project不需要這個功能) 請問有辦法用繼承,覆載或者是其他的方式來解決嗎? 謝謝 編輯記錄
mypigbaby 重新編輯於 2007-11-05 23:07:15, 註解 無‧
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
寫一個小元件來負責Log.
以下程式碼謹供參考...^_^ [code delphi] unit fMain; interface uses Classes, Forms, ExtCtrls, Controls, StdCtrls; type { TLog } TLog = class(TPersistent) private function GetText: string; protected FFileName: string; L0: TStringList; L1: TStringList; procedure FlushToFile(L: TStringList); public constructor Create(const FileName: string); destructor Destroy; override; procedure Add(S: string); property Text: string read GetText; end; { TForm1 } TForm1 = class(TForm) Timer1: TTimer; Timer2: TTimer; Timer3: TTimer; Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private Log: TLog; procedure DO_ON_TIMER(Sender: TObject); end; var Form1: TForm1; implementation uses SysUtils; {$R *.dfm} { TLog } constructor TLog.Create(const FileName: string); begin inherited Create; FFileName := FileName; L0 := TStringList.Create; L1 := TStringList.Create; end; destructor TLog.Destroy; begin FlushToFile(L1); FlushToFile(L0); FreeAndNil(L1); FreeAndNil(L0); inherited; end; function TLog.GetText: string; begin Result := L0.Text; end; procedure TLog.Add(S: string); begin L0.Add(S); while L0.Count > 20 do begin L1.Add(L0[0]); L0.Delete(0); end; //儲存到檔案 if L1.Count > 100 then FlushToFile(L1); end; //若為求效率可以用TFileStream開啟舊檔, //並將新增資料寫到檔尾... procedure TLog.FlushToFile(L: TStringList); var List: TStringList; begin List := TStringList.Create; try if FileExists(FFileName) then List.LoadFromFile(FFileName); List.Text := List.Text L.Text; L.Clear; List.SaveToFile(FFileName); finally FreeAndNil(List); end; end; { TForm1 } procedure TForm1.FormCreate(Sender: TObject); begin Randomize; Log := TLog.Create('D:\LOG.TXT'); Timer1.OnTimer := DO_ON_TIMER; Timer2.OnTimer := DO_ON_TIMER; Timer3.OnTimer := DO_ON_TIMER; end; procedure TForm1.FormDestroy(Sender: TObject); begin FreeAndNil(Log); end; procedure TForm1.DO_ON_TIMER(Sender: TObject); var S: string; begin S := TComponent(Sender).Name ': '; S := S FormatDateTime('YYYY-MM-DD hh:nn:ss.zzz > ', Now); S := S Format('.12d, .12d', [Random(MaxInt),Random(MaxInt)]); Log.Add(S); Memo1.Lines.Text := Log.Text; end; end. [/code] |
mypigbaby
高階會員 發表:11 回覆:168 積分:155 註冊:2006-07-20 發送簡訊給我 |
首先感謝jow兄
這麼晚還幫豬寶寶解答^^" ===================引 用 jow 文 章=================== 寫一個小元件來負責Log. 以下程式碼謹供參考...^_^ 也謝謝JOW兄的範例 但是豬寶寶是希望 這二行能併成一段 且其他FUNCTION都不用修改的情形下能達成存到LOG的目的(所以才會想去用繼承或覆載的方式去改MEMO 元件) 還是謝謝您^^" [code delphi] Log.Add(S); Memo1.Lines.Text := Log.Text; end; end. [/code] |
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
想想Document / View的觀念, 你Log的動作應該盡量與畫面的更新分開,
而且要考慮寫檔的動作 不能够太頻繁. 所以我的程式想法是以TStringList(L0) 來Log所要的資料, 並且只保留最新的20筆以供顯示, 多的部分則放在另一個 TStringList(L1)之中, 在達到100筆時, 則寫入檔案, 並清除L1. 至於顯示的部分: Memo1.Lines.Text := Log.Text; 可以另置他處, 以固定時間 顯示一次, 如此可節省更新畫面所產生的效能上的負擔. 個人建議, 謹供參考 ^_^' ===================引 用 mypigbaby 文 章=================== 首先感謝jow兄 這麼晚還幫豬寶寶解答^^" ===================引 用 jow 文 章=================== 寫一個小元件來負責Log. 以下程式碼謹供參考...^_^ 也謝謝JOW兄的範例 但是豬寶寶是希望 這二行能併成一段 且其他FUNCTION都不用修改的情形下能達成存到LOG的目的(所以才會想去用繼承或覆載的方式去改MEMO 元件) 還是謝謝您^^" [code delphi] Log.Add(S); Memo1.Lines.Text := Log.Text; end; end. [/code] |
mypigbaby
高階會員 發表:11 回覆:168 積分:155 註冊:2006-07-20 發送簡訊給我 |
JOW兄的想法是蠻正確的
但是這支程式遇到的問題就是 這支程式是在SERVER常駐的(聆聽TCP的訊息進來做記錄) 可能不到100行就被外力關掉程式 而這100行的LOG就沒了 所以才會想說當ADD時 馬上寫進LOG 就算程式被外力關掉,也能從LOG中發現問題 後來是有想到另一個比較笨的方法 寫一個FORM1用的函數 裡面就是寫入LOG跟在MEMO1.LINES.ADD 所有的子函數都去呼叫那個TFORM1的方法來寫入 ANYWAY 還是謝謝JOW兄 的幫忙^^ ===================引 用 jow 文 章=================== 想想Document / View的觀念, 你Log的動作應該盡量與畫面的更新分開, 而且要考慮寫檔的動作 不能够太頻繁. 所以我的程式想法是以TStringList(L0) 來Log所要的資料, 並且只保留最新的20筆以供顯示, 多的部分則放在另一個 TStringList(L1)之中, 在達到100筆時, 則寫入檔案, 並清除L1. 至於顯示的部分: Memo1.Lines.Text := Log.Text; 可以另置他處, 以固定時間 顯示一次, 如此可節省更新畫面所產生的效能上的負擔. 個人建議, 謹供參考 ^_^' ===================引 用 mypigbaby 文 章=================== 首先感謝jow兄 這麼晚還幫豬寶寶解答^^" ===================引 用 jow 文 章=================== 寫一個小元件來負責Log. 以下程式碼謹供參考...^_^ 也謝謝JOW兄的範例 但是豬寶寶是希望 這二行能併成一段 且其他FUNCTION都不用修改的情形下能達成存到LOG的目的(所以才會想去用繼承或覆載的方式去改MEMO 元件) 還是謝謝您^^" [code delphi] Log.Add(S); Memo1.Lines.Text := Log.Text; end; end. [/code] |
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
可是如果依照你的需求, 你的程式根本就不需要有顯示的功能(VIEW),
應該在每筆訊息加入的時候, 立即作以下的動作: 開啟LOG檔->Seek到檔尾->寫入訊息->關閉檔案 如此才能夠盡可能不會Lose掉任何訊息 這是最後的建議了, 僅供參考... ^_^'' ===================引 用 mypigbaby 文 章=================== JOW兄的想法是蠻正確的 但是這支程式遇到的問題就是 這支程式是在SERVER常駐的(聆聽TCP的訊息進來做記錄) 可能不到100行就被外力關掉程式 而這100行的LOG就沒了 所以才會想說當ADD時 馬上寫進LOG 就算程式被外力關掉,也能從LOG中發現問題 後來是有想到另一個比較笨的方法 寫一個FORM1用的函數 裡面就是寫入LOG跟在MEMO1.LINES.ADD 所有的子函數都去呼叫那個TFORM1的方法來寫入 ANYWAY 還是謝謝JOW兄 的幫忙^ |
mypigbaby
高階會員 發表:11 回覆:168 積分:155 註冊:2006-07-20 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |