程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 代碼編輯器(三)-PageControl和類,編輯器-pagecontrol

代碼編輯器(三)-PageControl和類,編輯器-pagecontrol

編輯:Delphi

代碼編輯器(三)-PageControl和類,編輯器-pagecontrol


PageControl位於Win32選項卡中,可以在控件上右鍵點擊“New Page”,來實現靜態的頁面添加。 先說說幾個重要的屬性: ActivePage:當前活動的頁面(在設計模式中切換頁面會更改ActivePage屬性) MultiLine:選項卡以多行形式顯示。 Style:頁面樣式。
tsTabs:(默認)選項卡樣式
tsButtons:按鈕樣式(經典樣式)
tsFlatButtons:按鈕樣式2(經典樣式)
TabHeight, TabWidth:選項卡位置設置(默認為0,單位:px)

TabPosition:選項卡的位置

tpBottom:下面(很奇怪)
tpLeft:左面(經典樣式)
tpRight:右面(經典樣式)
tpTop:(默認)上面

然後是PageControl中的TabSheet:

Caption:在選項卡中顯示的內容 TabVisible:選項卡可見性 PageIndex:頁面的索引值
首先添加一個PopupMenu,PageControl1。PageControl不要添加TabSheet。 PageControl的Align設置為alClient,PupopMenu設置為PopupMenu1。 PopupMenu1添加如下菜單(Add的Visible是False): 簡單文本編輯器——PageControl和類(Delphi 2009) - ZomGraves - 編程為主 然後進入代碼編輯界面,在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,接下來設置主菜單。如圖: 簡單文本編輯器——PageControl(Delphi 2009) - ZomGraves - 編程為主 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,選擇要使用的過程即可。 簡單文本編輯器——PageControl和類(Delphi 2009) - ZomGraves - 編程為主 當用戶關閉窗口的時候,應該詢問用戶沒保存的文件是否保存,當然,這裡面會用到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.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved