歡迎光臨 Code²

Code Square, CodeSqaure, Pascal, Javascript

2008年12月15日星期一

完整範例 - Fontlist (3/10)

  在界面設計好後,我們便要對程序的實現進行一個整體規劃。雖然程序的功能總是一個一個加上去的,但是程序的整體思路卻應該儘早規劃,這可以為將來程序的發展預留空間,也可以避免大量修改原來代碼。

  在 OOP 編程中,程序的規劃主要體現在 Object 上,以下是我們對所用 object 的定義:

type
  tFontData = record
    Filename, Fontname: string;
  end;
  tFontDatas= array of tFontData;

  TForm1 = class(TForm)
    ....
    SavePictureDialog1: TSavePictureDialog;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure btnSystemClick(Sender: TObject);
    procedure btnFolderClick(Sender: TObject);
    procedure btnSelectFolderClick(Sender: TObject);
    procedure btnSaveBmpClick(Sender: TObject);
    ....
  private
    FSystemFonts: tFontDatas;
    FFolderFonts: tFontDatas;
    FFonts: ^tFontDatas;
    FFolder: String;
    FShowSystemFont: Boolean;
    procedure SetFolder(const Value: String);
    procedure SetShowSystemFont(const Value: Boolean);

    function  SelectFolder: string;
    procedure GetSystemFonts;
    procedure GetFolderFonts;
    procedure UpdateFonts;
    procedure SaveAsBitmap(const Filename: string);
  public
    property Folder: String read FFolder write SetFolder;
    property ShowSystemFont: Boolean read FShowSystemFont write SetShowSystemFont;
  end;

  在這裏我們增加了對四個TButton被按下時的處理,以及FormCreateFormResize的處理。我們還增加了ShowSystemFontFolder兩個屬性,前者表示顯示的是系統字型還是目錄內字錄,後者指定字型所在目錄。

  此外我們定義了三個tFontDatas相關的變量,顧名思義,FSystemFonts將會列出所有系統字型,FFolderFonts則是Folder內的字型。FFonts指向目前所用的tFontDatas,可以指向FFolderFontsFSystemFonts,視ShowSystemFont而定。以後我們的操作將通過此指針完成,這樣可以大大簡化代碼,不必因為ShowSystemFont不同而分開處理。

  最後還有五個private函數,它們都是未完成的部分,在下面會一一細說。

procedure TForm1.FormCreate(Sender: TObject);
begin
  Grid.ColWidths[0]:=Grid.ClientWidth;
  FFolder:='';
  SetLength(FFolderFonts,0);
  GetSystemFonts;
  FShowSystemFont:=false;
  ShowSystemFont:=true;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Grid.SetBounds(Grid.Left, Grid.Top, ClientWidth-16, ClientHeight-Grid.Top-8);
  Grid.ColWidths[0]:=Grid.ClientWidth;
end;

  FormCreate是一些簡單的初始化。第2、3、5行都是多餘的,因為這本來便是初始化的值。第一行是改變欄寬,盡量使用所有空間,第4行呼叫GetSystemFonts取得所有系統字型,第6行則設定屬性使之顯示系統字型。

  使用者改變form的大小時,FormResize使Grid的大小和欄寬隨之改變。這是運行時載圖。

procedure TForm1.btnSystemClick(Sender: TObject);
begin
  ShowSystemFont:=true;
end;

procedure TForm1.btnFolderClick(Sender: TObject);
begin
  ShowSystemFont:=false;
end;

procedure TForm1.btnSelectFolderClick(Sender: TObject);
begin
  Folder:=SelectFolder;
end;

procedure TForm1.btnSaveBmpClick(Sender: TObject);
begin
  if SavePictureDialog1.Execute then
    SaveAsBitmap(SavePictureDialog1.Filename)
end;

  對TButton的處理,實在簡單得很,只是把相關屬性設定便可以了,簡潔明瞭,這便是 OOP 的好處。這裏用到兩個函數,分別是SelectFolderSaveAsBitmap,前者的功能是要求使用者選擇目錄(目錄如果是空白表示使用者按了「取消」鍵),後者則把目前的字型樣本儲成.bmp檔案。相應地,我們在 form 中增加了一個tSavePictureDialog

procedure TForm1.SetFolder(const Value: String);
begin
  if Value='' then exit;
  FFolder:=Value;
  GetFolderFonts;
  if not ShowSystemFont then
  begin
    FFonts:=@FFolderFonts;
    UpdateFonts;
  end;
end;

procedure TForm1.SetShowSystemFont(const Value: Boolean);
begin
  if FShowSystemFont=Value then exit;
  if not Value then
  begin
    if FFolder='' then Folder:=SelectFolder;
    if FFolder='' then exit;
  end;

  FShowSystemFont:=Value;
  btnSystem.enabled:=not FShowSystemFont;
  btnFolder.enabled:=FShowSystemFont;
  btnSelectFolder.enabled:=not FShowSystemFont;
  if FShowSystemFont
    then Caption:='Fontlist - System fonts'
    else Caption:=format('Fontlist - Fonts in "%s"',[FFolder]);

  if FShowSystemFont
    then FFonts:=@FSystemFonts
    else FFonts:=@FFolderFonts;
  UpdateFonts;
end;

  這部分是主篇的重點,它處理了ShowSystemFontFolder兩個屬性改變時,程序所作出的反應。當Folder變化時,我們要做的東西比較少,首先是我們要讀取Folder內的字型(GetFolderFonts),其次是如果ShowSystemFontfalse時,表示目前顯示的是目錄下的字型,我們便要更新顯示的字型(UpdateFonts)。

  SetShowSystemFont長一點點,首先如果顯示目錄字型而目錄尚未設定,它會要求使用者選擇目錄,否則便顯示系統字型。然後它會把不適用的TButton禁用和改變標題。最後它會設定合適的tFontDatas,然後更新顯示的字型。

function TForm1.SelectFolder: string;
begin
  result:='c:\';
end;

procedure TForm1.GetSystemFonts;
begin

end;

procedure TForm1.GetFolderFonts;
begin

end;

procedure TForm1.UpdateFonts;
begin
  btnSavebmp.enabled:=length(FFonts^)>0;
end;

procedure TForm1.SaveAsBitmap(const Filename: string);
begin

end;

end.

  以上是未完成的部分,實際上是程序的真正核心。不過雖然核心部分幾乎全是空白,程序的架構卻已經完整了。

  下面是完整的pas代碼。

fontu.pas顯示代碼

沒有留言:

發佈留言