dll文件:delphi.dlllibrary Delphi; uses SysUtils, Forms, Classes, Dialogs, Unit2 in 'Unit2.pas' {dllform};exports ShowCalendar; begin end. 在此Dll中有一个dllform在unit2.pas中。dllform中有一些简单控件。如就两个button,没有事件。unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type Tdllform = class(TForm) Button1: TButton; Button2: TButton; private { Private declarations } public { Public declarations } end; function ShowCalendar(AHandle: THandle; ACaption: String):TDateTime;implementation{$R *.dfm} function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime; var DLLForm: TDLLForm; begin Application.Handle := AHandle; DLLForm := TDLLForm.Create(Application); //创建并显示窗体 try DLLForm.Caption := ACaption; DLLForm.ShowModal; //显示方式为模式化 Result :=555555; //返回设定日期 finally DLLForm.Free; //用完后卸载该窗体 end; end;end. 主程序如下:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TShowCalendar=function(AHandle: THandle; ACaption: String):TDateTime;StdCall; EDLLLoadError = class(Exception);//同时分创建一个出错记录类 TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Button2: TButton; Label1: TLabel; procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button2Click(Sender: TObject); var OneHandle : THandle; //定义一个句柄变量 begin OneHandle := LoadLibrary('Clendar.dll'); //动态载入DLL,并返回其句柄 try if OneHandle <> 0 then //如果载入成功则获取ShowCalendar函数的地址 @ShowCalendar:=GetProcAddress(OneHandle,'ShowCalendar'); if not (@ShowCalendar = nil) then //如果找到该函数则在主窗体的Label1中显示DLL窗体中设定的日期 Label1.Caption := DateToStr(ShowCalendar(Application.Handle, Caption)) else RaiseLastWin32Error; finally FreeLibrary(OneHandle); //调用完毕收回DLL占用的资源 end; end;end.
看起来没什么错亚。。ShowCalendar 的声明完全匹配吧。。if not (@ShowCalendar = nil) then ?? 看起来有点怪。。-> if @ShowCalendar <> nil then // 不更好么。。
procedure TfrmMain.mi_inDLLClick(Sender: TObject); var DLLHandle: THandle; DLLSub: InvokeDLLForm; begin DLLHandle := LoadLibrary('TTDLL.dll'); if DLLHandle <> 0 then begin @DLLSub := GetProcAddress(DLLHandle, 'CreateDLLForm'); if Assigned(DLLSub) then begin DLLForm := DLLSub(Application, Screen); end; end; end;
uses
SysUtils,
Forms,
Classes,
Dialogs,
Unit2 in 'Unit2.pas' {dllform};exports ShowCalendar;
begin
end.
在此Dll中有一个dllform在unit2.pas中。dllform中有一些简单控件。如就两个button,没有事件。unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
Tdllform = class(TForm)
Button1: TButton;
Button2: TButton;
private
{ Private declarations }
public
{ Public declarations }
end;
function ShowCalendar(AHandle: THandle; ACaption: String):TDateTime;implementation{$R *.dfm}
function ShowCalendar(AHandle: THandle; ACaption: String): TDateTime;
var
DLLForm: TDLLForm;
begin
Application.Handle := AHandle;
DLLForm := TDLLForm.Create(Application); //创建并显示窗体
try
DLLForm.Caption := ACaption;
DLLForm.ShowModal; //显示方式为模式化
Result :=555555; //返回设定日期
finally
DLLForm.Free; //用完后卸载该窗体
end;
end;end.
主程序如下:unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TShowCalendar=function(AHandle: THandle; ACaption: String):TDateTime;StdCall;
EDLLLoadError = class(Exception);//同时分创建一个出错记录类
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Label1: TLabel;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button2Click(Sender: TObject);
var
OneHandle : THandle; //定义一个句柄变量
begin
OneHandle := LoadLibrary('Clendar.dll'); //动态载入DLL,并返回其句柄
try
if OneHandle <> 0 then //如果载入成功则获取ShowCalendar函数的地址
@ShowCalendar:=GetProcAddress(OneHandle,'ShowCalendar');
if not (@ShowCalendar = nil) then
//如果找到该函数则在主窗体的Label1中显示DLL窗体中设定的日期
Label1.Caption := DateToStr(ShowCalendar(Application.Handle, Caption))
else
RaiseLastWin32Error;
finally
FreeLibrary(OneHandle); //调用完毕收回DLL占用的资源
end;
end;end.
看起来有点怪。。-> if @ShowCalendar <> nil then // 不更好么。。
var
DLLHandle: THandle;
DLLSub: InvokeDLLForm;
begin
DLLHandle := LoadLibrary('TTDLL.dll');
if DLLHandle <> 0 then
begin
@DLLSub := GetProcAddress(DLLHandle, 'CreateDLLForm');
if Assigned(DLLSub) then
begin
DLLForm := DLLSub(Application, Screen);
end;
end;
end;
去这里下载源码:
http://www.delphibox.com/article.asp?articleid=937
在调用者的project.dpr的 uses中 也要[首先]加入ShareMem
肯定就好了我有一样的东西 可以成功调用
要源码可以联系我 [email protected]
但是在OCX的ActiveForm中调用时Free会有问题 还请帮忙测试一下
因为这时的宿主是IE ShareMem不知道写在哪里好..
在dll的工程文件里写入口函数创建窗体,而一旦创建就可以象普通exe文件一样使用了。如:
dll文件:delphi.dlllibrary Delphi;
uses
SysUtils, Forms, Classes, Dialogs;procedure ShowDllFrm;
var
dllfrm:Tdllfrm;
begin
dllfrm:=Tdllfrm.create(nil);
dllfrm.showmodal;
dllfrm.free;
end;exports
ShowDllFrm;
begin
end.
DLL中声明是:
function ShowCalendar(AHandle: THandle; ACaption: String):TDateTime;而在调用时却是:
TShowCalendar=function(AHandle: THandle; ACaption: String):TDateTime;StdCall;后面的这个声明强制使用stdcall的标准。把后面这stdcall去掉,或者在DLL中加上就行了,不过建议加上,和Windows保持一致嘛。