• delphi的DLL封装MDI子窗体


    前天遇到一个疑问:主窗体是fsMDIForm时,调用DLL的窗体不可以嵌入在主窗体中。于是就这个问题,我在网上找了相关资料,并找到答案:DLL封装子窗体。

    了解后,使用相同方法在DLL的子窗体再调用另一个DLL窗体也可以。如果需要回传参数,可以通过函数获得。
    实例如下:
    新增Dll Application,在工程中新建一个Form,现在这个Dll就是拥有窗体的DLL了。
    DLL中的代码:
    library Project2;

    { 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,
    Classes,
    Forms,
    Windows,
    Messages,
    Unit1 in 'Unit1.pas' {Form1};

    {$R *.res}
    var
    DLLApp: TApplication;

    function ShowForm(var App: TApplication;ParentForm: TForm): Boolean;export; stdcall;
    begin
    {获取调用窗体的Application,显而易见的功能是 能使你的窗体融合到调用程序中。通过它还能进行很多操作}
    Application:= App;//将DLL的Application转为App
    Form1:= TForm1.Create(ParentForm);//创建子窗体,子窗体随着ParentForm存在、释放。
    Form1.FormStyle:= fsMDIChild;//设置窗体模式
    Form1.Show;
    end;

    {重写Dll入口函数,否则程序会出错}
    procedure DLLUnloadProc(Reason: Integer); register;
    begin
    {DLL取消调用时,发送DLL_PROCESS_DETACH消息,此时将DLL的Application返回为本身}
    if Reason = DLL_PROCESS_DETACH then Application:=DLLApp;
    end;

    exports
    ShowForm;

    begin
    {在DLL入口预先储存DLL的Application}
    DLLApp:=Application;
    {DllProc:DLL入口函数指针。Delphi定义为 DllProc: TDLLProc;}
    {在此指向我们自己定义的函数}
    DLLProc := @DLLUnloadProc;
    end.

    调用主程序单元,只需要一个TButton 就可以。
    unit Unitmain;

    interface

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, ComCtrls, Menus, ToolWin, RzPanel, cxControls, cxContainer,
    cxTreeView, dxNavBar, dxDockPanel, dxDockControl, ExtCtrls, RzSplit;

    type
    TForm1 = class(TForm)
        mm1: TMainMenu;
        N1: TMenuItem;
        pnl1: TPanel;
        fsMDIChild1: TMenuItem;
        DLL1: TMenuItem;
        procedure DLL1Click(Sender: TObject);
    private
        { Private declarations }
    public
        { Public declarations }
    end;

    var
    Form1: TForm1;

    function ShowForm(var App: TApplication; ParentForm: TForm): Boolean;stdcall; external 'Project2.dll';//为了简单,使用静态调用方法

    implementation

    {$R *.dfm}


    procedure TForm1.DLL1Click(Sender: TObject);
    begin
    ShowForm(Application, Self);//调用DLL函数调出窗体。传入当前主程序的Application对象和Form1本身
    end;

    end.

  • 相关阅读:
    MyBatis 延迟加载
    超经典的 25 道 MyBatis 面试题
    公钥与私钥,HTTPS详解
    分布式,集群,微服务的理解
    单例模式的饿汉式和懒汉式的实现以及比较它们的区别比较(Java实现)
    Mybatis的一级缓存和二级缓存详解
    Maven install没有将jar包加载到本地仓库
    Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
    数据结构_C语言_单链表
    Java实现一个简单的LRUCache
  • 原文地址:https://www.cnblogs.com/kfarvid/p/1763753.html
Copyright © 2020-2023  润新知