中TMemo控件的应用,编辑多行文本
分类:多线程

TMemo中的两个方法:
TMemo.Lines.Add(stringxxx);意思是向TMemo中增加字符串stringxxx;
TMemo.Lines.Text :=stringxxx,意思是清空了Memo1,然后写入stringxxx。
TMemo中的属性:
TMemo的属性中没有Scrollbar这个属性,不知道为什么,设置showscrollbars为true也没有用。属性AutoHide默认为True,这样文本中一行显示不完就被隐藏了,于是文本显示不完整。所以我们设置AutoHide为False。这样一行显示不完会换行。
属性WordWrap属性默认为False,这样显示不完的字符串会被省略。自己设置为true,再把AutoHide设置为False,这样就能完全显示字符串了。

多行编辑框组件(TMemo)TMemo组件可以显示、编辑多行文本,是一个标准的Windows多行编辑组件。对一些比较多的文本内容可以利用TMemo组件来显示、编辑。

恩恩,有这么一篇转载自这里的文章;

1.TMemo组件的典型用法

 

TMemo组件主要用于输入备注型的字符串,它不能进行文字格式的设置。利用TMemo组件Lines属性的LoadFromFile方法打开文本文件,对文本文件进行编辑。编辑完成后再利用Lines属性的SaveToFile方法将编辑后的文本进行保存。
例如下面的代码,在拥有一个Memo1组件和两个Button组件的窗体上,实现了文本文件的打开和保存功能:

PageControl位于Win32选项卡中,可以在控件上右键点击“New Page”,来实现静态的页面添加。

procedure TForm1.OpenBtnClick(Sender: TObject);
begin
Memo1.Lines.LoadFromFile(’C:a.txt’); //打开C:a.txt文件
end;

先说说几个重要的属性:

procedure TForm1.SaveBtnClick(Sender: TObject);
begin
Memo1.Lines.SaveToFile(’C:a.txt’); //保存为C:a.txt文件
end;

ActivePage:当前活动的页面(在设计模式中切换页面会更改ActivePage属性)

TMemo组件主要是利用Lines属性进行控制,它的取值类型为TStringList属性。

MultiLine:选项卡以多行形式显示。

2.TMemo组件的重要属性

Style:页面样式。

Lines---------------可以访问多行文本中的每一行
ScrollBars----------此属性用于设置是否要加上滚动条
WantReturn----------用于解决按下“enter”键是用于换行还是作用于按钮WantTabs每按一次Tab键,将使光标在多行文本编辑器中移动一个制表位WordWrap当输入文字到了多行文本编辑器的右边界时,文字自动换行下面介绍程序中TMemo组件常用的属性。

style="color: #ff00ff;">tsTabs:(默认)选项卡样式

style="color: #ff00ff;">tsButtons:按钮样式(经典样式)

style="color: #ff00ff;">tsFlatButtons:按钮样式2(经典样式)

(1)Lines属性
单击Lines属性后边的“...”按钮打开编辑框,可以对Memo组件的内容进行编辑,通过此属性可以对Memo组件内的每一行进行访问。例如取出Memo1组件第2行的内容显示为Form1的标题:
Form1.Caption:=Memo1.Lines.Strings[1];
利用Line属性的Add方法和Delete方法可以对Memo的内容进行动态地添加和删除。如下代码的功能是向Memo1组件中添加一行内容:
Memo1.Lines.Add(’在Memo的末尾添加一行内容’);
删除Memo的第1行内容可以这样写:
Memo1.Lines.Delete(0);

TabHeight, TabWidth:选项卡位置设置(默认为0,单位:px)

(2)ScrollBars属性
ScrollBars属性用于设置是否要加上滚动条(因为需要输入多行文字)。本属性设定了以下4个用户可选值。
. ssNone:不加上滚动条。
. ssHorizontal:加上水平滚动条。
. ssVertical:加上垂直滚动条。
. ssBoth:水平和垂直滚动条都加上。

TabPosition:选项卡的位置

(3)WantReturn属性
假如Form上有一个按钮,并且按钮的Default属性设为True,当用户按下“Enter”键时即相当于单击这个按钮,因为这个按钮是默认按钮。这就带来一个问题—在多行文本编辑器中输入文字时按下Enter键,究竟是换行还是作用于按钮呢?
WantReturns属性用于解决这个问题。如果WantReturn设为True,按下“Enter”键就是换行。如果WantReturns设为False,按下Enter键就不是换行而是作用于按钮,这时候要换行必须按“Ctrl+Enter”组合键。

style="color: #ff00ff;">tpBottom:下面(很奇怪)

style="color: #ff00ff;">tpLeft:左面(经典样式)

style="color: #ff00ff;">tpRight:右面(经典样式)

style="color: #ff00ff;">tpTop:(默认)上面

(4)WantTabs属性
如果WantTabs属性设为True,每按一次“Tab”键,将使光标在多行文本编辑器中移动一个制表位。如果
WantTabs属性设为False,按下“Tab”键使输入焦点在同一个Form的组件之间依次切换,这时候,要在多行文本编辑器中移动一个制表位,必须按“Ctrl+Tab”组合键。

然后是PageControl中的TabSheet:

(5)WordWrap属性
如果此属性设为True,当输入的文字到了多行文本编辑器的右边界时,文字自动换行。当编辑器的水平尺寸改变时,编辑器中的文字也将自动调整。

Caption:在选项卡中显示的内容

TabVisible:选项卡可见性

PageIndex:页面的索引值

首先添加一个PopupMenu,PageControl1。PageControl不要添加TabSheet。

PageControl的Align设置为alClient,PupopMenu设置为PopupMenu1。

PopupMenu1添加如下菜单(Add的Visible是False):

图片 1

然后进入代码编辑界面,在interface中的uses引用StdCtrls。

和以前不同的是,之前是把Memo也添加到窗体中,直接在属性窗口设置好相应的属性值。但是,用代码创建的控件,就只能用代码去设置其属性了。

 

不难看出,这里面的每一个控件(包括窗体)都是一个类。当然,不同于C++和java,类定义了之后要手动创建,一般情况下是Create()。

1 procedure TForm1.Button1Click(Sender: TObject);
2 var
3   btn: TButton;
4 begin
5   btn := TButton.Create();
6   //下面是对Button的属性修改
7   btn.Caption := '按钮';
8 end;

然后,在ActionList中添加一些Action,接下来设置主菜单。如图:

图片 2

图片 3

Action里面的StandardAction可以直接使用。

只不过,有的还需要自己手动添加代码,比如:打开等等。

像撤销,剪切,粘贴等不需要自己添加代码,也不需要自己弄Enabled属性。

之前说过,只有窗体,菜单(主菜单和弹出式菜单),按钮等一些控件能使用Action。

想想如果不使用ActionList里面的StandardAction,自己去写代码的话,除了引用Clipbrd.pas之外就是使用Windows.pas里面的SendMessage了。

不过,还是得提醒一下:在菜单上添加Action会更改菜单的Caption, Checked和ShortCut属性。

所以在设置完Action之后再改Caption(StandardAction的默认的Caption是英文...)。

--如何判断当前活动的Memo

在这里,一个Page里面只有一个Memo,这样,就可以通过PageControl的ActivePageIndex来决定了。

在静态使用Memo的时候我们可以直接Memo1.Text什么的,但是现在不可以。那么,可以用下面的替代:

类名(PageControl1.Pages[PageControl1.ActivePageIndex].Controls[0]).属性

比如:

TMemo(PageControl1.Pages[PageControl1.ActivePageIndex].Controls[0])

--关闭页面与打开、保存

关闭的时候,直接调用TabSheet的Destroy()就可以了,对于容器型的控件来说,对容器进行Destroy的同时,内部的控件也同样会被Destroy。

注意,静态添加的控件也可以用代码Destroy。但是...不推荐这么做。

在关闭之前最好询问用户没保存的文件是否保存。

那么,Memo的Modified属性就非常重要了,初始情况是False,当文本框的内容出现变化的时候Modified为True(但也有特例)。

在不考虑UTF-8编码的情况下直接使用Lines.LoadFromFile()和Lines.SaveToFile()就可以了。

 1 procedure TForm1.FileOpenAccept(Sender: TObject);
 2 var
 3   fName: string;
 4   cIndex: Integer;
 5 begin
 6   Add1.Click();
 7   cIndex := PageControl1.ActivePageIndex;
 8   fName := FileOpen1.Dialog.FileName;
 9   TMemo(PageControl1.Pages[cIndex].Controls[0]).LoadFromFile(fName);
10 end;

在不考虑类的继承的情况下,保存这部分实现比较难而且很麻烦。

首先,需要一个字符串类型的动态数组,按照PageControl1的标签的顺序记录其完整的文件名(新建的文件,值为空),而且数组的索引值要和PageControl的TabSheet的索引值对应。

然后还需要考虑什么时候需要修改这个动态数组等等。显然很麻烦。

所以,这里通过类的继承实现。则有:

1 type
2   TRecEdit = class(TMemo)
3   protected
4     fPath: string;        //用于存放通过打开的文件的完整路径
5   end;

这样子类拥有父类能继承的所有属性,以及子类定义的属性。

类的定义写在interface中。

另外,主菜单的“关闭当前”和“关闭所有”使用的过程基本相同,这样我们可以不用在另一个过程里面写xxx.Click();了。

选择一个菜单,在属性窗口中单击Events,找到OnClick,选择要使用的过程即可。

图片 4

当用户关闭窗口的时候,应该询问用户没保存的文件是否保存,当然,这里面会用到while循环,同时我定义了函数ClosePageQuery,通过其返回值来决定。

当ClosePageQuery返回False的时候使FormCloseQuery的CanClose为True。

则有如下代码:

1 procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
2 begin
3   while PageControl1.PageCount > 0 do
4     if not ClosePageQuery() then begin
5       CanClose := True;
6       Exit;
7     end;
8 end;

--扩展

字体设置:

在窗体上添加一个FontDialog。然后可以使用如下代码:

那么,在这里就可以这么用:

if FontDialog1.Execute then

  TRecEdit(PageControl1.Pages[PageControl1.ActivePageIndex].Controls[0]).Font := FontDialog1.Font

上面的几个可以根据自己的情况添加。

--调试

调试还是比较简单的。这里先说一下容易出问题的地方。

关闭所有

最开始的时候使用for循环,然后就有如下代码:

for i := 0 to PageControl1.PageCount - 1 do
  PageControl1.Pages[i].Destroy;

但是——这么做会出错。

因为i的值会变,而且PageControl1.PageCount也会变,但只能变小,而i只能变大。

所以,会出现下标越界的错误。

PageControl1.Pages[i].Destroy;

换成

PageControl1.ActivePage.Destroy;

就不会出错。

后期把保存部分添加之后,就不能直接使用Destroy了。

显然,for循环不合适。

然后是while循环,之前说ClosePageQuery为False的时候退出循环。

1 while PageControl1.PageCount > 0 do
2   if not ClosePageQuery() then
3     break;

也可以把while和if合并。

保存

保存和另存为是两回事。首先,另存为是无论文件是否是新建的,都会弹出保存对话框。

而保存就是TRecEdit的fPath是空字符串的时候,也就是文件是新建的时候弹出保存对话框。所以有:

1 pIndex := PageControl1.ActivePageIndex;
2 s := TRecEdit(PageControl1.Pages[pIndex].Controls[0]).fPath;
3 if s = '' then begin
4   if SaveDialog1.Execute then
5     TRecEdit(PageControl1.Pages[pIndex].Controls[0]).Lines.SaveToFile(SaveDialog1.FileName);
6 end else
7   if TRecEdit(PageControl1.Pages[pIndex].Controls[0]).Modified then
8       TRecEdit(PageControl1.Pages[pIndex].Controls[0]).Lines.SaveToFile(s);

实际上是if语句的嵌套。

这里很可能弄成先if xxx.Modified then然后再if s = '' then。

但这样会忽略一种情况——新建的文件没有输入任何文字,理论上会弹出保存对话框的但实际上没有,而且没有进行保存。

 

根据前面部分(不包括扩展),整理代码:

  1 unit Unit1;
  2 
  3 interface
  4 
  5 uses
  6   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7   Dialogs, Menus, StdCtrls, ComCtrls, StdActns, ActnList;
  8 
  9 type
 10   TRecEdit = class(TMemo)
 11   protected
 12     fPath: string;
 13   end;
 14 
 15   TForm1 = class(TForm)
 16     PageControl1: TPageControl;
 17     PopupMenu1: TPopupMenu;
 18     Add1: TMenuItem;
 19     ClosePage1: TMenuItem;
 20     CloseAll1: TMenuItem;
 21     ActionList1: TActionList;
 22     FileOpen1: TFileOpen;
 23     FileSaveAs1: TFileSaveAs;
 24     EditCut1: TEditCut;
 25     EditCopy1: TEditCopy;
 26     EditPaste1: TEditPaste;
 27     EditSelectAll1: TEditSelectAll;
 28     EditUndo1: TEditUndo;
 29     EditDelete1: TEditDelete;
 30     MainMenu1: TMainMenu;
 31     F1: TMenuItem;
 32     E1: TMenuItem;
 33     N1: TMenuItem;
 34     O1: TMenuItem;
 35     S1: TMenuItem;
 36     SaveAs1: TMenuItem;
 37     Undo1: TMenuItem;
 38     N2: TMenuItem;
 39     Cut1: TMenuItem;
 40     Copy1: TMenuItem;
 41     Paste1: TMenuItem;
 42     Delete1: TMenuItem;
 43     N3: TMenuItem;
 44     SelectAll1: TMenuItem;
 45     N4: TMenuItem;
 46     C1: TMenuItem;
 47     L1: TMenuItem;
 48     N5: TMenuItem;
 49     X1: TMenuItem;
 50     SaveDialog1: TSaveDialog;
 51     procedure Add1Click(Sender: TObject);
 52     procedure FormCreate(Sender: TObject);
 53     procedure ClosePage1Click(Sender: TObject);
 54     procedure CloseAll1Click(Sender: TObject);
 55     procedure FileOpen1Accept(Sender: TObject);
 56     procedure N1Click(Sender: TObject);
 57     procedure S1Click(Sender: TObject);
 58     procedure FileSaveAs1Accept(Sender: TObject);
 59     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
 60   private
 61     { Private declarations }
 62     function ClosePageQuery(pIndex: Integer): Boolean; overload;
 63     function ClosePageQuery(): Boolean; overload;
 64   public
 65     { Public declarations }
 66   end;
 67 
 68 var
 69   Form1: TForm1;
 70   n: Integer;
 71 
 72 implementation
 73 
 74 {$R *.dfm}
 75 
 76 procedure TForm1.Add1Click(Sender: TObject);
 77 var
 78   tab: TTabSheet;
 79   TeMemo: TRecEdit;
 80 begin
 81   tab := TTabSheet.Create(PageControl1);
 82   tab.PageControl := PageControl1;
 83   TeMemo := TRecEdit.Create(tab);
 84   TeMemo.Parent := tab;
 85   TeMemo.fPath := '';
 86   TeMemo.Align := alClient;
 87   TeMemo.ScrollBars := ssVertical;
 88   C1.Enabled := True;
 89   L1.Enabled := True;
 90 end;
 91 
 92 function TForm1.ClosePageQuery(pIndex: Integer): Boolean;
 93 var
 94   ret: Integer;
 95 begin
 96   if TRecEdit(PageControl1.Pages[pIndex].Controls[0]).Modified then begin
 97     ret := Application.MessageBox('当前文件内容已经修改,想保存文件吗?', '保存', 51);    //51=48+3
 98     case ret of
 99     IDYES:      FileSave1.Click();
100     IDCANCEL:   begin
101                   Result := False;
102                   Exit;
103                 end;
104     end;
105   end;
106   PageControl1.Pages[pIndex].Destroy;
107   Result := True;
108 end;
109 
110 function TForm1.ClosePageQuery: Boolean;
111 begin
112   Result := ClosePageQuery(PageControl1.ActivePageIndex);
113 end;
114 
115 procedure TForm1.CloseAll1Click(Sender: TObject);
116 begin
117   while PageControl1.PageCount > 0 do
118     if not ClosePageQuery() then
119       break;
120   if PageControl1.PageCount = 0 then begin
121     C1.Enabled := False;
122     L1.Enabled := False;
123   end;
124 end;
125 
126 procedure TForm1.ClosePage1Click(Sender: TObject);
127 begin
128   ClosePageQuery(PageControl1.ActivePageIndex);
129   if PageControl1.PageCount = 0 then begin
130     C1.Enabled := False;
131     L1.Enabled := False;
132   end;
133 end;
134 
135 procedure TForm1.FileOpen1Accept(Sender: TObject);
136 var
137   pIndex: Integer;
138   fName: string;
139 begin
140   Add1.Click;
141   pIndex := PageControl1.ActivePageIndex;
142   fName := FileOpen1.Dialog.FileName;
143   TRecEdit(PageControl1.Pages[pIndex].Controls[0]).Lines.LoadFromFile(fName);
144   TRecEdit(PageControl1.Pages[pIndex].Controls[0]).fPath := fName;
145   PageControl1.ActivePage.Caption := ExtractFileName(fName);
146   //Form1.Caption := fName;
147 end;
148 
149 procedure TForm1.FileSaveAs1Accept(Sender: TObject);
150 var
151   pIndex: Integer;
152   sPath: string;
153 begin
154   pIndex := PageControl1.ActivePageIndex;
155   sPath := FileSaveAs1.Dialog.FileName;
156   TRecEdit(PageControl1.Pages[pIndex].Controls[0]).Lines.SaveToFile(sPath);
157   TRecEdit(PageControl1.Pages[pIndex].Controls[0]).fPath := sPath;
158 end;
159 
160 procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
161 begin
162   while PageControl1.PageCount > 0 do
163     if not ClosePageQuery() then begin
164       CanClose := True;
165       Exit;
166     end;
167 end;
168 
169 procedure TForm1.FormCreate(Sender: TObject);
170 begin
171   n := 1;
172   N1.Click;
173 end;
174 
175 procedure TForm1.N1Click(Sender: TObject);        //新建
176 begin
177   Add1.Click;
178   PageControl1.ActivePage.Caption := '无标题' + IntToStr(n);
179   Inc(n);
180 end;
181 
182 procedure TForm1.S1Click(Sender: TObject);        //保存
183 var
184   s: string;
185   pIndex: Integer;
186 begin
187   with PageControl1 do begin
188     pIndex := ActivePageIndex;
189     s := TRecEdit(Pages[pIndex].Controls[0]).fPath;
190     if s = '' then begin
191       if SaveDialog1.Execute then begin
192         TRecEdit(Pages[pIndex].Controls[0]).Lines.SaveToFile(SaveDialog1.FileName);
193         TRecEdit(Pages[pIndex].Controls[0]).fPath = SaveDialog1.FileName;
194       end;
195     end else
196       if TRecEdit(Pages[pIndex].Controls[0]).Modified then
197         TRecEdit(Pages[pIndex].Controls[0]).Lines.SaveToFile(s);
198     ActivePage.Caption := ExtractFileName(s);
199   end;
200 end;
201 
202 end.

本文由10bet手机官网发布于多线程,转载请注明出处:中TMemo控件的应用,编辑多行文本

上一篇:php之微型博客的创建,WordPress增加文章排序方式 下一篇:通用图形分析,枚举SQL服务器及数据库
猜你喜欢
热门排行
精彩图文