这样写当然不行了,Application.CreateForm这些语句是project用的。
如你要实现调用api时出现你要的form时可这样做。
调用时
var
Form1: TForm1;implementation{$R *.dfm}procedure DoTest(H: THandle; { 传递句柄 }
AConn: TADOConnection; { 传递数据库连接 }
S: string; { 传递文本信息 }
N: Integer); { 传递数值信息 }
cdecl; { 指定调用协议 }
external 'Project2.dll'; { 指定过程来源 }procedure TForm1.Button1Click(Sender: TObject);
begin
DoTest(Application.Handle,
ADOConnection1,
'Call OK',
256);
end;Dll文件library Project2;uses
SysUtils,
Classes,
Unit2 in 'E:\delphi5\dll\Unit2.pas' {Form1};{$R *.res}
exports
DoTest;
beginend.Unit2.pas文件
unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB;type
TForm2 = class(TForm)
ADOConnection1: TADOConnection;
Memo1: TMemo;
private
{ Private declarations }
public
{ Public declarations }
end;procedure DoTest(H: THandle; { 获得调用者的句柄 }
AConn: TADOConnection; { 获得调用者的数据库连接 }
S: string; { 获得一些文本信息 }
N: Integer); { 获得一些数值信息 }
cdecl; { 指定调用协议 }
function showform(Ahandle: Thandle; Acaption: string): longint; stdcall;procedure closeform(Aformref: longint); stdcall;implementation{$R *.DFM}procedure DoTest(H: THandle; AConn: TADOConnection; S: string; N: Integer);
begin
Application.Handle := H; { 将过程的句柄赋值为调用者的句柄 }
{ 上面语句的作用在于, DLL的句柄和调用者的句柄相同,在任务栏中就不会 }
{ 各自出现一个任务标题了。 }
with TForm2.Create(Application) do
try { 创建窗体 }
Memo1.Lines.Append('成功调用'); { 显示一行信息 }
ADOConnection1 := AConn; { 获得数据库连接的实例 }
Memo1.Lines.Append(
ADOConnection1.ConnectionString +
' - ' + S + ' - ' + IntToStr(N)); { 根据得到的参数显示另一行信息 }
ShowModal; { 模式化显示窗体 }
finally
Free; { 调用结束时销毁窗口 }
end;
end;function showform(AHandle: THandle; Acaption: string): longint;
var
form2: Tform2;
begin
showmessage('0');
Application.Handle := AHandle;
showmessage('1');
form2 := Tform2.Create(application);
showmessage('2');
result := longint(form2);
showmessage('3');
form2.Caption := Acaption;
form2.Show;end;procedure closeform(Aformref: longint);
begin
if Aformref > 0 then
Tform2(Aformref).Free;
end;
end.
如你要实现调用api时出现你要的form时可这样做。
调用时
var
Form1: TForm1;implementation{$R *.dfm}procedure DoTest(H: THandle; { 传递句柄 }
AConn: TADOConnection; { 传递数据库连接 }
S: string; { 传递文本信息 }
N: Integer); { 传递数值信息 }
cdecl; { 指定调用协议 }
external 'Project2.dll'; { 指定过程来源 }procedure TForm1.Button1Click(Sender: TObject);
begin
DoTest(Application.Handle,
ADOConnection1,
'Call OK',
256);
end;Dll文件library Project2;uses
SysUtils,
Classes,
Unit2 in 'E:\delphi5\dll\Unit2.pas' {Form1};{$R *.res}
exports
DoTest;
beginend.Unit2.pas文件
unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB;type
TForm2 = class(TForm)
ADOConnection1: TADOConnection;
Memo1: TMemo;
private
{ Private declarations }
public
{ Public declarations }
end;procedure DoTest(H: THandle; { 获得调用者的句柄 }
AConn: TADOConnection; { 获得调用者的数据库连接 }
S: string; { 获得一些文本信息 }
N: Integer); { 获得一些数值信息 }
cdecl; { 指定调用协议 }
function showform(Ahandle: Thandle; Acaption: string): longint; stdcall;procedure closeform(Aformref: longint); stdcall;implementation{$R *.DFM}procedure DoTest(H: THandle; AConn: TADOConnection; S: string; N: Integer);
begin
Application.Handle := H; { 将过程的句柄赋值为调用者的句柄 }
{ 上面语句的作用在于, DLL的句柄和调用者的句柄相同,在任务栏中就不会 }
{ 各自出现一个任务标题了。 }
with TForm2.Create(Application) do
try { 创建窗体 }
Memo1.Lines.Append('成功调用'); { 显示一行信息 }
ADOConnection1 := AConn; { 获得数据库连接的实例 }
Memo1.Lines.Append(
ADOConnection1.ConnectionString +
' - ' + S + ' - ' + IntToStr(N)); { 根据得到的参数显示另一行信息 }
ShowModal; { 模式化显示窗体 }
finally
Free; { 调用结束时销毁窗口 }
end;
end;function showform(AHandle: THandle; Acaption: string): longint;
var
form2: Tform2;
begin
showmessage('0');
Application.Handle := AHandle;
showmessage('1');
form2 := Tform2.Create(application);
showmessage('2');
result := longint(form2);
showmessage('3');
form2.Caption := Acaption;
form2.Show;end;procedure closeform(Aformref: longint);
begin
if Aformref > 0 then
Tform2(Aformref).Free;
end;
end.
在你的过程里动态调用试试!
的原因,估计你的form中有ado之类的组件吧!
好像有一个coInitialize的api函数,具体查下help或msdn吧!
你在程序初始化时先调用一下那个函数,至少就不会出来这个错误了!
另外dll还要注意
1.Application.Handle := H; { 将过程的句柄赋值为调用者的句柄 }
2.build with run time package要选上!
CreateOleObject('comsql.getdata');
在exe中使用没问题;
但放在dll中就有问题了,这该如何解决?