DLL窗体关闭时报错(100分)

  • 主题发起人 主题发起人 小天
  • 开始时间 开始时间

小天

Unregistered / Unconfirmed
GUEST, unregistred user!
①FirstDLL.DLL文件
library FirstDLL;
uses
SysUtils, Classes,
Forms, ActiveX,
Ufirst in 'Ufirst.pas' {firstForm};

{$R *.RES}
procedure OpenfirstForm(cl:String;l,t,w,h:Integer);stdcall;
begin
Application.CreateForm(TfirstForm, firstForm);
firstForm.CurrLanguage:=cl;
firstForm.FormLeft:=l;
firstForm.FormTop:=t;
firstForm.FormWidth:=w;
firstForm.FormHeight:=h;
firstForm.Show;
end;

procedure ClosefirstForm;stdcall;
begin
firstForm.Free;
end;

exports
OpenfirstForm,
ClosefirstForm;
begin
CoInitialize(nil);
end.

②主窗体Ufirst.pas文件
type
TfirstForm = class(TForm)
.
.
.
private
{ Private declarations }
public
CurrLanguage:string[2];
FormTop,FormLeft,FormWidth,FormHeight:Integer;
{ Public declarations }
end;
procedure TFirstForm.FormPaint(Sender: TObject);
begin
Left:=FormLeft;
Top:=FormTop;
Width:=FormWidth;
Height:=FormHeight;
End;

③调用
implementation
{$R *.DFM}
procedure OpenFirstForm(cl:String;l,t,w,h:Integer);stdcall; external ' FirstDLL.dll';
procedure CloseFirstForm;stdcall; external ' FirstDLL.dll';
.
.
.
procedure TForm1.FormCreate(Sender: TObject);
Begin
OpenFirstForm(‘cn’,0,0,640,480);
End;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
Begin
CloseFirstForm;
End;

此文件关闭时报错,请问这是什么原因呢?
 
我想问提就出在 free 上, 用close 就好了吧
 
close根本关不了
 
句柄不一致的问题,你可以返回一个句柄,然后指定关闭。
 
我的理解:
小天:是不是提示AV错误??
一、将 firstForm.Show换成firstform.ShowModal试试。
二、应该将应用程序的句柄传给DLL中的体中去,这样就可避免不可预料的错误。
三、将传入参数String改成ShortString或Pchar,我使用String时在关闭时也总是报错,但我检查代码,shareMem并没有放错位置,不知怎么回事??后来改成ShortString时就没有报错了!(注意:要将你放置的shareMem单元去掉。)
四、你的 Application.CreateForm(TfirstForm, firstForm)这样不太好吧?具我的理解,这行代码创建了一个主程序的窗体,而DLL的代码是被映射到当前进程去执行的,当前进程一般有一个主线程(主窗体),是不是会有冲突呢?(此问题待验证。)
五、按你的代码,请问:当DLL Form没有关闭,而用户把调用DLL的主程序(主窗体)关闭了,谁来释放DLL Form空间呢?
六、我总是用下面的代码书写DLL中的Form(模式与非模式,从来没有出现错误),代参考:
function ShowModalForm(ahandle : THandle;aCaption : ShortString) : Boolean;stdcall;export;
function ShowFormMe(aHandle : THandle;aCaption : ShortString) : LongInt; stdcall;export;
procedure CloseFormMe(var ahandle : Longint);
implementation

{$R *.DFM}
function ShowFormMe(aHandle : THandle;aCaption : ShortString) : LongInt;stdcall;
var
aForm : TForm1;
begin
Application.Handle := aHandle;
aForm := TForm1.Create(Application);
aform.Caption := aCaption;
Result := LongInt(aForm);
aForm.show;
end;

procedure CloseFormMe(var aHandle : LongInt);
begin
if ahandle>0 then
TForm1(ahandle).free;
ahandle:=0;
end;

function ShowModalForm(aHandle : THandle;aCaption : ShortString) : Boolean;stdcall;
var
aForm : TForm1;
begin
Result := false;
Application.Handle := ahandle;
aForm := TForm1.Create(Application);
try
aForm.Caption := aCaption;
aForm.ShowModal;
Result := True;
finally
aForm.free;
end;
end;

大家继续讨论!呵呵!

加说一句:
你的procedure TFirstForm.FormPaint(Sender: TObject);不太好吧(太浪费CPU时间了)?用OnActivate可能会更好。

 
我记得好象在调用string的时候要使用sharemem的。不妨try?
 
参数用pchar不要用string
 
对!D的String比较特殊,
与其他语言不是很兼容。
其实用应该也可以,
可是要分布几个动态链接库以支持String,
总而言之,比较的麻烦!
 
接受答案了.
 
后退
顶部