zoukankan      html  css  js  c++  java
  • Dll学习一_Dll 创建并动态引用窗体且释放窗体Demo

    1、新建Dll工程

    2、Dll工程全部代码

    library SubMain;
    
    { 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
      SysUtils, Forms,
      Classes, Windows, Dialogs,
      SubMain_Unit in 'SubMain_Unit.pas' {Frm_SubMain};
    
    var
      AppHnd: Thandle;//应用程序的句柄变量
      AppScr: TScreen;//应用程序的环境变量
    {$R *.res}
    
    procedure DllEntryPoint(dwReason: DWord);
    begin
    
      case dwReason of
        DLL_PROCESS_ATTACH:
        begin
          AppHnd := Application.Handle;//备份Exe句柄
          AppScr := Screen;//备份Exe环境
        end;
        DLL_THREAD_ATTACH: ShowMessage('Create Thread'); //Dll文件中最好用Messagebox,ShowMessage部分环境中容易抽风
        DLL_THREAD_DETACH: ShowMessage('Free Thread'); //Dll文件中最好用Messagebox,ShowMessage部分环境中容易抽风 
        DLL_PROCESS_DETACH:
        begin
          if Frm_SubMain <> nil then FreeAndNil(Frm_SubMain);//防止Dll窗体未释放干净
          Application.Handle := AppHnd;      //恢复Exe句柄
          Screen := AppScr;//恢复Exe环境
        end;
      end;
    end;
    
    exports
      CreateFrm,DropFrm;//输出函数接口
    
    begin
      DllProc := @DllEntryPoint;
      DllEntryPoint(DLL_PROCESS_ATTACH);
    end.

    3、SubMain_Unit.pas源码

    unit SubMain_Unit;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, FyFun_Unit;
    
    type
      TFrm_SubMain = class(TForm)
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
      procedure CreateFrm(AppHnd: THandle);export;stdcall;//接口函数声明
      procedure DropFrm; export;stdcall;//接口函数声明
    var
      Frm_SubMain: TFrm_SubMain;
    
    implementation
    
    {$R *.dfm}
    procedure CreateFrm(AppHnd: THandle);//窗体创建函数
    begin
      Application.Handle := AppHnd;
    
      if not Assigned(Frm_SubMain) then
        Frm_SubMain := TFrm_SubMain.Create(Application);
    
      Frm_SubMain.Show;
    end;
    
    procedure DropFrm;//窗体释放函数
    begin
      if Frm_SubMain <> nil then
        FreeAndNil(Frm_SubMain);
    end;
    procedure TFrm_SubMain.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action := caFree;//dll窗体关闭自动释放
    end;
    
    procedure TFrm_SubMain.FormDestroy(Sender: TObject);
    begin
      Frm_SubMain := nil;//dll窗体关闭自动释放
    end;
    
    end.
    4、调用文件Main.pas代码

    unit Main_Unit;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TCreateFrm = procedure(AppHnd: THandle); stdcall;
      TDropFrm = procedure; stdcall;
      TFrm_Main = class(TForm)
        Btn_1: TButton;
        Btn_2: TButton;
        Btn_3: TButton;
        Btn_4: TButton;
        procedure Btn_1Click(Sender: TObject);
        procedure Btn_2Click(Sender: TObject);
        procedure Btn_3Click(Sender: TObject);
        procedure Btn_4Click(Sender: TObject);
      private
        LibHandle: THandle;
        FormRef: LongInt;
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Frm_Main: TFrm_Main;
    
    implementation
    
    {$R *.dfm}
    
    procedure TFrm_Main.Btn_1Click(Sender: TObject);		//动态加载Dll文件
    begin
      if LibHandle = 0 then
      begin
        LibHandle := SafeLoadLibrary('SubMain.dll');
        if LibHandle = 0 then
          raise Exception.Create('Not Found Dll File')
        else
          ShowMessage('Dll Loaded');
      end;
    end;
    
    procedure TFrm_Main.Btn_2Click(Sender: TObject);		//释放Dll文件
    begin
      if LibHandle > 0 then
      begin
        FreeLibrary(LibHandle);
        LibHandle := 0;
        ShowMessage('Dll UnLoaded');
      end;
    end;
    
    procedure TFrm_Main.Btn_3Click(Sender: TObject);		//读取Dll文件窗体并显示
    var
      CreateFrm: TCreateFrm;
    begin
      if LibHandle = 0 then
        raise Exception.Create('Place Load Dll File First');
    
      @CreateFrm := GetProcAddress(LibHandle,PChar('CreateFrm'));
      if @CreateFrm = nil then
        raise Exception.Create('Function Error');
    
      CreateFrm(Application.Handle);
    end;
    
    procedure TFrm_Main.Btn_4Click(Sender: TObject);		//释放Dll窗体
    var
      DropFrm: TDropFrm;
    begin
      @DropFrm := GetProcAddress(LibHandle,PChar('DropFrm'));
      if @DropFrm = nil then
        raise Exception.Create('Function Error');
    
      DropFrm;
    end;
    
    end.



  • 相关阅读:
    C语言第十一讲,预处理命令.
    C语言第十讲,枚举类型简单说明
    C语言第九讲,结构体
    C语言第八讲,指针*
    C语言第七讲,函数入门.
    C语言第六讲,数组
    C语言第五讲,语句 顺序循环选择.
    C语言第四讲,typedef 关键字,以及作用域
    C语言第三讲,基本数据类型
    64位内核第二讲,进程保护之对象钩子
  • 原文地址:https://www.cnblogs.com/jupt/p/3922938.html
Copyright © 2011-2022 走看看