線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4209
推到 Plurk!
推到 Facebook!

MEMO文字行數控制問題

尚未結案
isthatu
初階會員


發表:80
回覆:47
積分:25
註冊:2002-06-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-02-03 15:25:42 IP:211.20.xxx.xxx 未訂閱
我有一個問題想請教各位 客戶要在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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-02-03 16:15:11 IP:203.73.xxx.xxx 未訂閱
可以參考下面文章的作法 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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-02-03 16:18:04 IP:219.68.xxx.xxx 未訂閱
可參考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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-02-05 11:33:20 IP:211.20.xxx.xxx 未訂閱
謝謝 不過我試了一下您提供的方法 他在判斷行數部分 仍以 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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-02-05 14:03:54 IP:61.221.xxx.xxx 未訂閱
可以考慮定義一個變數來儲存使用者目前的行數, 從KeyPress 的事件上來著手,當使用者按下 Enter 便做一次記錄, 可以順便限制使用者超過三行時便 不能在做換行的動作,不過也得考慮到使用者將行數 拉回的情況,這邊在搭配SelStart來做處理就行了。 發表人 -
chris_shieh
高階會員


發表:46
回覆:308
積分:240
註冊:2004-04-26

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-02-14 16:00:47 IP:61.30.xxx.xxx 未訂閱
原理一樣 我們乾脆全部利用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.
@瞭解越多.懂得越少@
系統時間:2024-05-19 0:56:00
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!