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.



  • 相关阅读:
    基于Token的身份验证--JWT
    在eclipse中使用maven创建springMVC项目
    Mybatis框架插件PageHelper的使用
    java 中==符号的坑
    Gradle project sync failed.
    intellij idea android错误: Missing styles. Is the correct theme chosen for this layout?
    thinkpad win8.1 无线连接受限
    struts2
    在Strust2 使用datatimepicker 标签引发的一系列问题
    struts2中css,js等资源无效 非路径问题(新手问题)
  • 原文地址:https://www.cnblogs.com/jupt/p/3922938.html
Copyright © 2011-2022 走看看