tsTabs:(默认)选项卡样式 tsButtons:按钮样式(经典样式) tsFlatButtons:按钮样式2(经典样式)TabHeight, TabWidth:选项卡位置设置(默认为0,单位:px)
TabPosition:选项卡的位置
tpBottom:下面(很奇怪) tpLeft:左面(经典样式) tPRight:右面(经典样式) tpTop:(默认)上面
然后是PageControl中的TabSheet:
Caption:在选项卡中显示的内容 TabVisible:选项卡可见性 PageIndex:页面的索引值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,接下来设置主菜单。如图: 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,选择要使用的过程即可。 当用户关闭窗口的时候,应该询问用户没保存的文件是否保存,当然,这里面会用到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.