1. 程式人生 > >Delphi 主窗體Panel中嵌入DLL窗體功能詳細原始碼

Delphi 主窗體Panel中嵌入DLL窗體功能詳細原始碼

自從我的部落格被塵封了五年之久,終於選擇在今天以主程式嵌入DLL窗體架構的原始碼為禮物送給大家,希望資源與大家共享,共祝未來的Delphi能夠走的更遠。

由於現在技術的日益發達,各種軟體的介面日益美化,很多客戶光看到原生的Delphi程式介面就會選擇拋棄我們的產品。於是我們不得不對介面進行美化,對架構進行重新整理。首先要感謝360、QQ這些軟體給我們提供了漂亮介面的基礎:一個大標題導航欄+操作區域,簡單、適用。

今天我們就以一個Demo來實現這種窗體結構,因為是在我的專案中已經使用,架構相關的程式碼已經被我整理了一遍,雖然看著簡單,卻真的費了我好多功夫。

程式介面:(真正使用的時候自己美化吧,這裡僅僅是個例子。ps:我用的是Dev的控制元件)


其實程式的架構很簡單:一個Panel做為容器,DLL中封裝窗體,並將它停靠在panel中。

程式碼有點多,貼上處部分有用的程式碼:

DLL中的工程原始碼:

library dllForms;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  System.SysUtils,
  System.Classes,
  Vcl.Forms,
  dxCore,
  Winapi.Windows,
  FormDialog in 'FormDialog.pas' {frmDialog},
  uLoadDLLForm in '..\uLoadDLLForm.pas',
  FormShow in 'FormShow.pas' {frmShow};

{$R *.res}

procedure DLLEntryPoint(Reason: DWORD);
begin
  case Reason of
    DLL_PROCESS_ATTACH:  dxUnitsLoader.Initialize;
    DLL_PROCESS_DETACH:
    begin
      dxUnitsLoader.Finalize;
    end;
  end;
end;
/// <summary>
/// 彈出式窗體的呼叫
/// <param name="AParamStr">窗體名稱</param>
/// </summary>
procedure ShowDLLForm(AParamStr: String); stdcall;
var
  vForm: TfrmDialog;
begin
  if Sametext('TfrmDialog', AParamStr) then
  begin
    vForm := TfrmDialog.Create(nil);
    try
      vForm.ShowModal;
    finally
      FreeAndNil(vForm);
    end;
  end;
end;
/// <summary>
/// 嵌入式窗體,返回TFormClass類,由主程式管理Form
/// </summary>
function GetForm(ClassName: PChar; ADllParams: pDllParams): TFormClass; stdcall;
begin
  if FindClass(ClassName) = nil then
    Exit;
  Result:=TFormClass(FindClass(ClassName));
end;

exports
  ShowDLLForm, GetForm;

begin
  DLLProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.

主窗體呼叫的程式碼:
unit FormMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, cxGraphics, cxLookAndFeels,
  cxLookAndFeelPainters, Vcl.Menus,
  Vcl.StdCtrls, cxButtons, Vcl.ExtCtrls,
  uLoadDLLForm;//關鍵的程式碼在uLoadDllForm單元中

type
  TfrmMain = class(TForm)
    Label1: TLabel;
    pnlTitle: TPanel;
    btnJinShui: TcxButton;
    btnJiaoYu: TcxButton;
    btnMall: TcxButton;
    btnClose: TcxButton;
    btnJinrong: TcxButton;
    pnlContainer: TPanel;
    procedure btnJinrongClick(Sender: TObject);
    procedure btnJinShuiClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    FActiveForm: TForm; //儲存當前展示的Form(容器類窗體)
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.btnJinrongClick(Sender: TObject);
var
  AForm: TForm;
begin
  AForm := LoadContainerFormDLL('dllForms.dll', 'TfrmShow', pnlContainer);
  if FActiveForm = nil then
    FActiveForm := AForm
  else if FActiveForm <> AForm then
  begin
    FActiveForm.Hide;
    FActiveForm := AForm;
  end;
end;

procedure TfrmMain.btnJinShuiClick(Sender: TObject);
begin
  //主程式呼叫,彈出框
  LoadFormDLL('dllForms.dll', 'TfrmDialog');
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  //初始化DLL載入項
  initDll;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  //釋放所有資源
  uninitDll;
end;

資源下載地址:http://download.csdn.net/detail/yueyun889/9864663