MEMO文字行數控制問題 |
尚未結案
|
isthatu
初階會員 發表:80 回覆:47 積分:25 註冊:2002-06-26 發送簡訊給我 |
我有一個問題想請教各位 客戶要在memo鍵入文數字 條件是 每行只能80字 (以ENTER鍵來判定換行) 最多3行 最後存成文字檔 目前遇到問題 1.如果MEMO不用自動折行 當字超過MEMO寬度 會破壞畫面完整性 (比較難看客戶不會接受) 2.可是MEMO用了自動折行後 在行數判斷時 又無法以MEMO1.Lines.Strings[i]來判定 因為折行部分MEMO會算到第二列(其實它還試算第一行) 又,存成文字檔時 它又變成不折行的方式存檔 仍以ENTER來換行 所以 很難達成上述客戶要求.... ??難道說MEMO要先成文字檔暫存 在去解析文字檔內容的行數字數 沒通過的再螢幕SHOW出訊息??? 要這麼麻煩嗎 不曉得看得懂得人 有沒更好建議!
------
BCDEFHIJKLMNOPQRSTUVWXZ |
shinjie
資深會員 發表:12 回覆:275 積分:287 註冊:2003-03-19 發送簡訊給我 |
可以參考下面文章的作法
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=21030 行數限制
procedure TForm1.Memo1Change(Sender: TObject);
const MaxLineCount=5;
begin
if Memo1.Lines.Count>MaxLineCount then
Memo1.Perform(EM_UNDO,0,0);
Memo1.Perform(EM_EMPTYUNDOBUFFER,0,0);
end; 取得字數與行數
SendMessage(Memo1.Handle,EM_LINEFROMCHAR,-1,0);
Memo1.SelStart-SendMessage(Memo1.Handle,EM_LINEINDEX,-1,0); 只要控制得好應該可以達到你的需求,要考慮到從ClipBoard貼上也要控制。
發表人 - shinjie 於 2005/02/03 16:16:44 發表人 - shinjie 於 2005/02/03 16:41:33
------
我將在茫茫人海中尋訪我唯一之靈魂伴侶。 得之;我幸。不得;我命。 |
chris_shieh
高階會員 發表:46 回覆:308 積分:240 註冊:2004-04-26 發送簡訊給我 |
可參考http://delphi.ktop.com.tw/topic.php?topic_id=45834
加上載入檔案處理
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Memo1Change(Sender: TObject); private OldMemoWndProc:TWndMethod ; procedure NewWindowProc(var Message: TMessage); { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin AutoSize:=True; OldMemoWndProc:=Memo1.WindowProc; Memo1.Lines.Clear; Memo1.WindowProc:=NewWindowProc; Memo1.Width:=Canvas.TextWidth('測')*81; //中文長度 //Memo1.Width:=Canvas.TextWidth('a')*81; //英文長度 end; procedure TForm1.NewWindowProc(var Message: TMessage); var slTmp:TStringlist; begin OldMemoWndProc(Message); if (Message.Msg=WM_CHAR) then //處理字元動作 begin if Memo1.Lines.Count>=4 then Memo1.Lines.Delete(3); end else if (Message.Msg=WM_PASTE) then //處理大量Paste 動作 begin slTmp:=TStringList.Create; slTmp.Text:=Memo1.Lines.Text; Memo1.Lines.Clear; While slTmp.Count>=4 do slTmp.Delete(3); Memo1.Lines:=slTmp; slTmp.Free end; end; procedure TForm1.Button1Click(Sender: TObject); var slTmp:TStringList; i,j:integer; begin //Memo1.Lines.LoadFromFile('C:\test.txt'); //會直接載入所有內容 不行 slTmp:=TStringList.Create; slTmp.LoadFromFile('C:\test.txt'); for i := 0 to slTmp.Count-1 do begin if i>4 then break else begin for j := 1 to Length(slTmp[i]) do SendMessage(Memo1.Handle, WM_CHAR , Ord(slTmp[i][j]) ,1); //送出內容 SendMessage(Memo1.Handle, WM_CHAR , 13 ,1); //送出換行 end; end; slTmp.Free; end; end.發表人 - chris_shieh 於 2005/02/03 17:00:24 發表人 - chris_shieh 於 2005/02/03 17:04:05 |
isthatu
初階會員 發表:80 回覆:47 積分:25 註冊:2002-06-26 發送簡訊給我 |
謝謝 不過我試了一下您提供的方法 他在判斷行數部分
仍以 Memo1.Lines.Count來判斷 在memo寬度不足80字的情況下 自動折行部分它就會算到第二行 然後出現誤判的現象 ex: USER在MEMO輸入以下3行
aaaaaaaaaaaaaa (ENTER)
bbbbbbbbbbbbbbbbbbbbb (ENTER)
cccccccccccc (ENTER) 因受限MEMO寬度大小自動折行後呈現
aaaaaaaaaaaaaa (ENTER)
bbbbbbbbbbbbbbb
bbbbbb (ENTER)
cccccccccccc (ENTER) 變得說Memo1.Lines.Count 現在有4行了 所以在行數判定上會有問題 如果不用自動折行 aaaaaaaaaaaaaa (ENTER)
bbbbbbbbbbbbbbbbbbbbb (ENTER) <畫面上這一行後半段必超出MEMO範圍 這也不是客戶想要的結果>
cccccccccccc (ENTER) 我現在想到的方法 先將MEMO內容存成文字檔 就算有自動折行 它還是會以 USER原始方式存成TEXT 如下
aaaaaaaaaaaaaa (ENTER)
bbbbbbbbbbbbbbbbbbbbb (ENTER)
cccccccccccc (ENTER) 然後再去解析這些文字 判定有沒有符合條件 ...繞了一圈 >
------
BCDEFHIJKLMNOPQRSTUVWXZ |
chunglin
一般會員 發表:8 回覆:8 積分:3 註冊:2005-02-03 發送簡訊給我 |
|
chris_shieh
高階會員 發表:46 回覆:308 積分:240 註冊:2004-04-26 發送簡訊給我 |
原理一樣
我們乾脆全部利用TStringList 來判斷
以下試驗過 Memo1 可為任何寬度
對於較長的同一行自動折行情形 可以正確判斷
適用於使用 CopyPaste/ Keyin/ LoadFile 的動作
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Memo1Change(Sender: TObject); procedure FormDestroy(Sender: TObject); private slTmp:TStringlist; OldMemoWndProc:TWndMethod ; procedure NewWindowProc(var Message: TMessage); { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin slTmp:=TStringList.Create; AutoSize:=True; Memo1.Lines.Clear; OldMemoWndProc:=Memo1.WindowProc; Memo1.WindowProc:=NewWindowProc; end; procedure TForm1.NewWindowProc(var Message: TMessage); var bClear:Boolean; begin bClear:=False; OldMemoWndProc(Message); if (Message.Msg=WM_CHAR) or (Message.Msg=WM_PASTE) then begin slTmp.Text:=Memo1.Lines.Text; While slTmp.Count>=4 do begin bClear:=True; slTmp.Delete(3); end; if bClear then Memo1.Lines:=slTmp; end; end; procedure TForm1.Button1Click(Sender: TObject); var slTmp:TStringList; i,j:integer; begin //Memo1.Lines.LoadFromFile('C:\test.txt'); //會直接載入所有內容 不行 slTmp:=TStringList.Create; slTmp.LoadFromFile('C:\test.txt'); for i := 0 to slTmp.Count-1 do begin if i>4 then break else begin for j := 1 to Length(slTmp[i]) do SendMessage(Memo1.Handle, WM_CHAR , Ord(slTmp[i][j]) ,1); //送出內容 SendMessage(Memo1.Handle, WM_CHAR , 13 ,1); //送出換行 end; end; slTmp.Free; end; procedure TForm1.FormDestroy(Sender: TObject); begin slTmp.Free end; end.@瞭解越多.懂得越少@ |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |