前天遇到一个疑问:主窗体是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.