首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 動態 DFM 文件應用:超媒體卡片設計與元件動態建立完整實作

     編輯:Delphi

20.3.1.5 動態 DFM 文件應用揭秘

1. 動態 DFM 概述

相對於設計期固定的靜態 DFM,動態 DFM 指執行期生成或存取的 DFM。兩種來源:

  • 執行期 Create 動態建立元件並插入生成
  • 設計期預製 DFM,執行期透過串流/檔案工具讀入記憶體處理後存盤

靜態 DFM 犧牲彈性換取便利;動態插入控制項優勢在於任意時刻、位置、數量、類型,適合介面客製化、狀態保存、對話框保存等場景。缺點為非可視化,可輔以靜態 DFM 可視化設計。

使用動態 DFM 兩大注意事項

  1. 每個動態插入的控制項/元件必須呼叫 RegisterClass 註冊
  2. 讀入 DFM 自動建立元件後,若呼叫 InsertControl,關閉視窗時必須呼叫 RemoveControl 移除,否則產生異常

2. 動態 DFM 應用之一:超媒體系統卡片設計

Delphi 多樣可視元件(文字、編輯、圖像、資料庫、媒體播放、OLE)均佔螢幕區域、具豐富表現力,可作為卡片媒體。卡片要求媒體數量類型不受限、可修改存取,動態 DFM 最適合。若搭配串流存入資料庫 BLOB 欄位,更能融合超文本與關聯資料庫技術。

完整原始碼實作

① 應用程式註冊元件類別

procedure TMainForm.FormCreate(Sender: TObject);
begin
  RegisterClass(TLabel); RegisterClass(TEdit); RegisterClass(TMemo);
  RegisterClass(TButton); RegisterClass(TPanel); RegisterClass(TPanelP);
  RegisterClass(TBitBtn); ...
end;

② 建立與插入物件(點擊表單時依當前工具建立對應控制項)

procedure TMDIChild.FormClick(Sender: TObject);
var Ctrl: TControl; Point: TPoint;
begin
  GetCursorPos(Point); Point := BackGround.ScreenToClient(Point);
  case CurToolIndex of
    1: begin { Label }
      Ctrl := TLabel.Create(Self);
      TLabel(Ctrl).AutoSize := False;
      TLabel(Ctrl).Caption := 'Label'+S;
      { 設定位置、大小、顏色、字型、事件... }
      BackGround.InsertControl(Ctrl);
    end;
    2: begin { Edit }
      Ctrl := TEdit.Create(Self);
      TEdit(Ctrl).AutoSize := True;
      { 設定位置、高度... }
      BackGround.InsertControl(Ctrl);
    end;
    3: ...;
  end;
end;

③ 存取動態 DFM 文件

{ 開啟 }
procedure TMainForm.FileOpen(Sender: TObject);
begin
  if OpenDialog.Execute then
  begin
    DesignWin := TMDIChild.Create(Application);
    ReadComponentResFile(OpenDialog.FileName, DesignWin);
    DesignWin.Init;
    FileName := OpenDialog.FileName;
    DesignWin.Caption := FileName;
  end;
end;

{ 儲存 }
procedure TMainForm.FileSave(Sender: TObject);
begin
  if DesignWin.CurControl <> nil then DesignWin.CurControl.Enabled := True;
  WriteComponentResFile(FileName, DesignWin);
  DesignWin.Caption := FileName;
end;

{ 關閉時移除動態控制項 }
procedure TMDIChild.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var I: Integer; Ctrl: TControl; Removed: Boolean;
begin
  if Modified then if MessageDlg(...) = mrCancel then CanClose := False;
  if CanClose then
  begin
    repeat
      Removed := False; I := 0;
      repeat
        if BackGround.Controls[I].Name <> '' then
        begin BackGround.RemoveControl(BackGround.Controls[I]); Removed := True; end;
        Inc(I);
      until (I >= BackGround.ControlCount) or Removed;
    until not Removed;
    SendMessage(ObjectIns.Handle, WM_MDICHILDCLOSED, 0, 0);
  end;
end;

DesignWin.Init 將 BackGround 面板中具名控制項加入屬性編輯器列表。儲存用 WriteComponentResFile,關閉時必須逐一 RemoveControl 避免記憶體錯誤。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved