單元三、共同對話方塊與剪貼簿
3.1 使用共同對話方塊
- 常用的對話方塊
3.1.1使用開檔共同對話方塊
-
- 製作開啟舊檔選項
- 加入OpenDialog。單擊Filter特性右側的省略按鈕,出現Filter Edit對話方塊。
- 按照下圖輸入資料。把FilterIndex特性設為2(預設篩選條件為*.PAS)。
- 刪除ScrollBox並加入RichEdit元件。
- 雙擊檔案|開啟舊檔項目,完成下面程式。
Procedure Tform1.Open1Click(Sender: TObject); Begin if OpenDialog1.Execute then begin RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName); Caption := Format('%s - %s', [ExtractFileName(OpenDialog1.FileName), Application.Title]); RichEdit1.SetFocus; RichEdit1.Modified := False; RichEdit1.ReadOnly := ofReadOnly in OpenDialog1.Options; End; end; |
-
- 製作開啟新檔的選項
- 再開啟新檔的OnClick事件處理程序中填入
procedure TForm1.New1Click(Sender: TObject); begin Caption := Format('%s - %s', [‘Untitled’, Application.Title]); RichEdit1.Lines.Clear; RichEdit1.Modified := False; end; |
-
- 共用程序
- 在表格的類別宣告的Private部份加上此程序宣告。
Type … private FfileName: String; Procedure SetCaption(const FileName: String); Public { Public declarations } end; |
- 在實作部份加入下面內容。
procedure Tform1.SetCaption(const FileName: String); begin FFileName := FileName; Caption := Format('%s - %s', [ExtractFileName(FileName), Application.Title]); end; |
- 將原來的程序改為
Procedure Tform1.Open1Click(Sender: TObject); Begin if OpenDialog1.Execute then begin RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName); SetCaption(OpenDialog1.FileName); RichEdit1.SetFocus; RichEdit1.Modified := False; RichEdit1.ReadOnly := ofReadOnly in OpenDialog1.Options; End; end;
procedure Tform1.New1Click(Sender: TObject); begin SetCaption('Untitled'); RichEdit1.Lines.Clear; RichEdit1.Modified := False; end; |
3.1.2 使用存檔共同對話方塊
-
- 製作儲存檔案的選項
- 加入SaveDialog元件,並將其Filter的特性設成和OpenDialog一樣的值。Default設成「PAS」,FilterIndex設成2。
- 選取檔案|儲存檔案的功能選單,在其OnClick的事件處理程序填入
procedure TForm1.Save1Click(Sender: TObject); begin if FFileName = 'Untitled' then SaveAs1Click(Sender) Else begin RichEdit1.Lines.SaveToFile(FFileName); RichEdit1.Modified := False; end; end; |
-
- 製作另存新檔的選項
- 選取檔案|另存新檔的功能選單,在其OnClick的事件處理程序填入
procedure TForm1.SaveAs1Click(Sender: TObject); begin if not RichEdit1.Modified then exit; SaveDialog1.FileName := FFileName+'.'+SaveDialog1.DefaultExt; if SaveDialog1.Execute then begin if FileExists(SaveDialog1.FileName) then if MessageDlg(Format('是否要取代原有的檔案 %s', [SaveDialog1.FileName]), mtConfirmation, mbYesNoCancel, 0) <> idYes then Exit; RichEdit1.Lines.SaveToFile(SaveDialog1.FileName); SetCaption(SaveDialog1.FileName); RichEdit1.Modified := False; End; end; |
-
- 設定初始值:在表格的OnCreate事件中加上初始值
- 選取物件Form1,雙擊OnCreate事件,在程式編輯器中輸入
procedure TForm1.FormCreate(Sender: TObject); begin OpenDialog1.InitialDir := ExtractFilePath(ParamStr(0)); SaveDialog1.InitialDir := OpenDialog1.InitialDir; SetCaption('Untitled'); end; |
3.1.3 體貼的設計
在開新檔案或儲存檔案前,要先檢查程式是否被更改過,並做處理。
-
- 在SetCaption的宣告下面加一行IsSafe宣告。
… private FFileName: String; procedure SetCaption(const FileName: String); procedure IsSafe; public { Public declarations } end; |
- 在實作部份加上下面內容。
procedure TForm1.IsSafe; var Resp: Integer; begin if not RichEdit1.Modified then Exit; Resp := MessageDlg(Format('是否要把更動儲存到檔案 %s?', [FFileName]), mtConfirmation, mbYesNoCancel, 0); case Resp of idYes: Save1Click(Self); idNo: { 不用做什麼處理 }; idCancel: Abort; end; end; |
-
- 雙擊Form1的OnCloseQuery事件,輸入下面程序。
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin try IsSafe; except CanClose := False; end; end; |
-
- 在開檔和存檔的部份也加上IsSafe的檢查。
3.2 使用剪貼簿
3.2.1 使用Tclipboard物件
-
- 剪貼簿的使用宣告
- 找到該單元的implementation部份, 將Clipbrd加到uses子句中。
- RichEdit提供的特性和方法
特性/方法 | 說明 |
SelText | 目前使用者所選取的文字 |
SelLength | 目前使用者所選取的文字的長度 |
SelStart | 目前使用者所選取的文字的起使位置 |
SelectAll | 在RichEdit中的所有文字內容 |
ClearSelection | 清除目前使用者所選取的文字 |
CutToClipboard | 將所選取的文字剪下,並複製到剪貼簿 |
CopyToClipboard | 將所選取的文字複製到剪貼簿 |
PasteFromClipboard | 將剪貼簿的內容複製到游標所在的位置 |
-
- 製作編輯選單
- 選取編輯|剪下,輸入下面程式碼。
procedure TForm1.Cut1Click(Sender: TObject); begin RichEdit1.CutToClipboard; end; |
-
- 選取編輯|複製,輸入下面程式碼。
procedure TForm1.Copy1Click(Sender: TObject); begin RichEdit1.CopyToClipboard; end; |
-
- 選取編輯|貼上,輸入下面程式碼。
procedure TForm1.Paste1Click(Sender: TObject); begin RichEdit1.PasteFromclipboard; end; |
-
- 選取編輯|復原,輸入下面程式碼。
procedure TForm1.Undo1Click(Sender: TObject); begin with RichEdit1 do if HandleAllocated then SendMessage(Handle, EM_UNDO, 0, 0); end; |
-
- 選取編輯|選取全部,輸入下面程式碼。
procedure TForm1.SelectAll1Click(Sender: TObject); begin RichEdit1.SelectAll; end; |
-
- 選取編輯|尋找,輸入下面程式碼。
procedure TForm1.Find1Click(Sender: TObject); begin FindDialog1.Execute; end; |
-
- 在finddialog1的onfind事件中加入下面程式碼
procedure TForm1.FindDialog1Find(Sender: TObject); var FoundAt: LongInt; StartPos, ToEnd: integer; begin with RichEdit1 do begin { begin the search after the current selection if there is one } { otherwise, begin at the start of the text } if SelLength <> 0 then StartPos := SelStart + SelLength else StartPos := 0; { ToEnd is the length from StartPos to the end of the text in the rich edit control } ToEnd := Length(Text) - StartPos; FoundAt := FindText(FindDialog1.FindText, StartPos, ToEnd, [stMatchCase]); if FoundAt <> -1 then begin SetFocus; SelStart := FoundAt; SelLength := Length(FindDialog1.FindText); end; end; end; |
-
- 決定選單使用時機:未選取就不能Cut或Paste
- 雙擊功能選單設計工具的編輯選單。完成下面程式:
procedure TForm1.Edit1Click(Sender: TObject); var HasSelection: Boolean; begin Paste1.Enabled := Clipboard.HasFormat(CF_TEXT); HasSelection := RichEdit1.SelLength > 0; Cut1.Enabled := HasSelection; Copy1.Enabled := HasSelection; end; |
-
- 執行看看。
3.2.2 使用TiniFile物件
如何讓程式開始時回復到上次的狀態?
-
- 撰寫第二個程式單元
- 選擇File|New,在New Items對話方塊選取Unit。
- 完成下面程式:
Unit Utils; Interface Uses SysUtils, Forms, IniFiles; Procedure SaveFrmPos(AForm: TForm; Name: String); Procedure SetFrmPos(AForm: TForm; Name: String); Implementation // 內部自己使用的函式及記錄型態 type TPosRec = record Top, Left, Height, Width, State : integer; end; { 將word型類的內容轉換為列舉式型態 } function IntToWinState(Int: Word): TWindowState; begin case Int of 0 : Result := wsNormal; 1 : Result := wsMinimized; 2 : Result := wsMaximized else Result := wsNormal; end; end; { 轉換為INI檔所要使用的字串 } function PosRecToStr(Pos:TPosRec): String; begin with Pos do if State <> 2 then // 測試看是否在最大化的狀態 Result := IntToStr(State)+ // 目前表格的狀態 ' '+IntToStr(Top)+ // 上方的位置 ' '+IntToStr(Left)+ // 左側的位置 ' '+IntToStr(Height)+ // 高度 ' '+IntToStr(Width) // 寬度 else Result := IntToStr(State); end; { 從字串中找出數字 } function StrToPosRec(AString: String): TPosRec; var Temp: String; I,J: Integer; Blanks: array[1..4] of integer; Begin { 設定變數的初始值 } I := 1; J := 1; FillChar(Result, SizeOf(Result), #0); FillChar(Blanks, SizeOf(Blanks), #0); // 檢查視窗的狀態 -- 如果是wsMaximized, 那就無需要再做任何處理了 Temp := Copy(AString, 1, 1); Result.State := StrToInt(Temp); if Result.State = 2 then exit; // 找出在字串間的空白 repeat if AString[I] = ' ' then begin Blanks[J] := I; Inc(J); end; Inc(I); until (I = Length(AString)) or (J > 4); // 從字串中取出所要的數字 Temp := Copy(AString, Blanks[1]+1, Blanks[2]-Blanks[1]-1); Result.Top := StrToInt(Temp); Temp := Copy(AString, Blanks[2]+1, Blanks[3]-Blanks[2]-1); Result.Left := StrToInt(Temp); Temp := Copy(AString, Blanks[3]+1, Blanks[4]-Blanks[3]-1); Result.Height := StrToInt(Temp); Temp := Copy(AString, Blanks[4]+1, Length(AString)-Blanks[4]); Result.Width := StrToInt(Temp); end; // 把表格的大小/狀態/和位置寫到INI檔中 procedure SaveFrmPos(AForm: TForm; Name: String); var IniFile: TIniFile; PosRec: TPosRec; Begin // 設定初始值 FillChar(PosRec, SizeOf(PosRec), #0); IniFile := TIniFile.Create (ChangeFileExt(ExtractFileName(ParamStr(0)), '.INI')); try // 取得表格的特性 with PosRec do begin State := Ord(AForm.WindowState); Top := Aform.Top; Left := Aform.Left; Width := AForm.Width; Height := AForm.Height; end; // 把資料寫到檔案中 IniFile.WriteString('Positions', Name, PosRecToStr(PosRec)); Finally IniFile.Free; end; end; // 從INI檔中讀取表格的資料 procedure SetFrmPos(AForm: TForm; Name: String); var IniFile: TIniFile; PosString: String; PosRec: TPosRec; Begin // 設定初始值 FillChar(PosRec, SizeOf(PosRec), #0); IniFile := TIniFile.Create (ChangeFileExt(ExtractFileName(ParamStr(0)), '.INI')); try // 從INI檔中讀取資料 PosString := IniFile.ReadString('Positions', Name, 'Default'); Finally IniFile.Free; end; // 如果沒有讀到東西, 那就不用做任何進一步的處理 if PosString = 'Default' then exit; PosRec := StrToPosRec(PosString); // 設定表格的處位置 with AForm do begin WindowState := IntToWinState(PosRec.State); if PosRec.State = 2 then exit; Top := PosRec.Top; Left := PosRec.Left; Width := PosRec.Width; Height := PosRec.Height; end; end; end. |
-
- 儲存表格的位置
- 在Form1的OnDestroy事件輸入下面程式:
procedure TForm1.FormDestroy(Sender: TObject); begin SaveFrmPos(Form1, Form1.ClassName); end; |
-
- 復原表格的位置
- 在Form1的OnCreate事件輸入下面程式:
procedure TForm1.FormCreate(Sender: TObject); begin SetFrmPos(Form1, Form1.ClassName); OpenDialog1.InitialDir := ExtractFilePath(ParamStr(0)); SaveDialog1.InitialDir := OpenDialog1.InitialDir; SetCaption('Untitled'); end; |