主程序分别调用stock.dll、sell.dll,非模式状态显式,指定了他们的父窗体Parent为主程序中的一个Panel,(在模式状态下显式不能指定dll的父窗体,不知道什么原因...)现在有几个问题请教各位:
1、点击菜单调用了stock.dll,不进行任何操作,直接关闭主程序,主程序窗体是不见了,但实际上程序没有关闭,在进程中仍可以看到!必须按Ctrl+F2强行退出调试状态才结束!
但是点击stock.dll窗体里面的close按钮后,dll关闭了,主程序也正常关闭了.现在的问题也就是直接关闭主程序,已调用的dll没有自动释放?2、看到资料是说一般显式调用dll的非模式窗体必须有配套的两个过程或函数,一个调用、显示窗体,另外一个用于释放窗体,对于释放窗体的这个过程或者函数不晓得在主程序中应该怎么调用?在什么时候调用呢?下面是部分代码:
stock.dll内容:
function ShowDllForm(AHandle: THandle):Boolean;
var DllForm:Tcggl_main_f;
begin
Result := True;
try
CoInitialize(nil);
if cggl_main_f=nil then
begin
DllForm := Tcggl_main_f.Create(Application);
try
DllForm.ParentWindow:=AHandle;
dm:=Tdm.Create(Application);//创建dm
DllForm.Show;
except
on e:exception do
begin
cggl_main_f.Free;
dm.Free;
end;
end;
end;
except
Result:=False;
end;
end;function FreeDLLForm(AHandle:THandle):Boolean;//【这段释放的不知道该怎么写,请教各位帮忙写下 ^_^ 】
begin
Application.Handle:=AHandle;
//dm中用到SocketConnection的要先于dll主窗体之前关闭~~
if dm.SocketConnection1.Connected then dm.SocketConnection1.Connected:=False;
if cggl_main_f.Showing then cggl_main_f.Close;
if not cggl_main_f.Showing then
begin
cggl_main_f.Free;
Result:=True;
end else Result:=False;end;主程序中:
Type
TShowDllForm = Function(AHandle:THandle):boolean;stdcall;
TFreedllForm = Function(AHandle:THandle):boolean;stdcall;var
main_f: Tmain_f;
HandleCall:THandle;//stock.dll窗口句柄procedure Tmain_f.MyEXImage9Click(Sender: TObject);
var
ShowDllForm: TShowDllForm;
begin
try
if HandleCall=0 then
begin
HandleCall:=LoadLibrary('stock.dll');
if HandleCall=0 then
begin
Messagebox(Handle,'没有找到附带DLL文件,请确认程序是否完整!','加载DLL失败',MB_OK+MB_ICONEXCLAMATION);
Exit;
end ;
@ShowDllForm:=GetProcAddress(HandleCall,'ShowDllForm') ;
if @ShowDllForm<>nil then
try
ShowDllForm(RzPanel10.Handle);
except
raise Exception.Create('加载DLL失败');
end;
end;
finally
FreeLibrary(RzPanel10.Handle);
end;
end;procedure Tmain_f.FormDestroy(Sender: TObject);
begin
if HandleCall<>0 then
begin
FreeLibrary(HandleCall);
HandleCall:=0;
end;
end;不知道FreeDllForm在主程序中何时调用?该怎么样调用?以上描述的如不清楚随时跟贴说明~~~~麻烦大家了!~
1、点击菜单调用了stock.dll,不进行任何操作,直接关闭主程序,主程序窗体是不见了,但实际上程序没有关闭,在进程中仍可以看到!必须按Ctrl+F2强行退出调试状态才结束!
但是点击stock.dll窗体里面的close按钮后,dll关闭了,主程序也正常关闭了.现在的问题也就是直接关闭主程序,已调用的dll没有自动释放?2、看到资料是说一般显式调用dll的非模式窗体必须有配套的两个过程或函数,一个调用、显示窗体,另外一个用于释放窗体,对于释放窗体的这个过程或者函数不晓得在主程序中应该怎么调用?在什么时候调用呢?下面是部分代码:
stock.dll内容:
function ShowDllForm(AHandle: THandle):Boolean;
var DllForm:Tcggl_main_f;
begin
Result := True;
try
CoInitialize(nil);
if cggl_main_f=nil then
begin
DllForm := Tcggl_main_f.Create(Application);
try
DllForm.ParentWindow:=AHandle;
dm:=Tdm.Create(Application);//创建dm
DllForm.Show;
except
on e:exception do
begin
cggl_main_f.Free;
dm.Free;
end;
end;
end;
except
Result:=False;
end;
end;function FreeDLLForm(AHandle:THandle):Boolean;//【这段释放的不知道该怎么写,请教各位帮忙写下 ^_^ 】
begin
Application.Handle:=AHandle;
//dm中用到SocketConnection的要先于dll主窗体之前关闭~~
if dm.SocketConnection1.Connected then dm.SocketConnection1.Connected:=False;
if cggl_main_f.Showing then cggl_main_f.Close;
if not cggl_main_f.Showing then
begin
cggl_main_f.Free;
Result:=True;
end else Result:=False;end;主程序中:
Type
TShowDllForm = Function(AHandle:THandle):boolean;stdcall;
TFreedllForm = Function(AHandle:THandle):boolean;stdcall;var
main_f: Tmain_f;
HandleCall:THandle;//stock.dll窗口句柄procedure Tmain_f.MyEXImage9Click(Sender: TObject);
var
ShowDllForm: TShowDllForm;
begin
try
if HandleCall=0 then
begin
HandleCall:=LoadLibrary('stock.dll');
if HandleCall=0 then
begin
Messagebox(Handle,'没有找到附带DLL文件,请确认程序是否完整!','加载DLL失败',MB_OK+MB_ICONEXCLAMATION);
Exit;
end ;
@ShowDllForm:=GetProcAddress(HandleCall,'ShowDllForm') ;
if @ShowDllForm<>nil then
try
ShowDllForm(RzPanel10.Handle);
except
raise Exception.Create('加载DLL失败');
end;
end;
finally
FreeLibrary(RzPanel10.Handle);
end;
end;procedure Tmain_f.FormDestroy(Sender: TObject);
begin
if HandleCall<>0 then
begin
FreeLibrary(HandleCall);
HandleCall:=0;
end;
end;不知道FreeDllForm在主程序中何时调用?该怎么样调用?以上描述的如不清楚随时跟贴说明~~~~麻烦大家了!~
解决方案 »
- 哪位大哥有用panel做的房态图的DEMO呢?高分求
- update语句问题!在线等!急
- 一个看似没问题的自动生成窗口代码却不能正确执行。
- 如何屏蔽要访问的远程服务器IP?求救!!!
- DBGrid中CheckBox问题
- DELPHI如何实现在代理服务器上映射端口???
- 救救我!!为什么我设置ADOTABLE的ACTIVE为TRUE时有一个“FROM子句语法错误”?
- 如何触发activefrom中定义的事件
- !用水晶报表5.0的OCX控件预览报表时如何知道预览窗口是否已关闭?
- 各位路过的虾虾近来侃侃
- 庆祝网站上线,散分喽!!!人人有份!!
- 如何知道IdTCPServer的写缓冲WriteBuffer区已经满了,非常感谢
var
DllForm:Tcggl_main_f = nil;function FreeDLLForm:Boolean
begin
if Assigned(DllForm) then
begin
DllForm.Free;
DllForm := nil;
end;
end;exe中退出时调用FreeDllForm但是这里需要注意一个问题,就是多次调用ShowDllForm的问题
如果你允许多次调用,那么你就应该维护一个DllForm:Tcggl_main_f的数组
每次创建新的Form时,把Form记录到数组里面如果只有一个这种窗口出现,那么你的ShowDllForm应该如下:function ShowDllForm(AHandle: THandle):Boolean;
begin
....
if not Assigned(DllForm) then
DllForm := Tcggl_main_f.Create(Application);
DllForm.Show;
...
end;
//再次提醒下,DllForm是全局的
procedure Tmain_f.FormClose(Sender: TObject; var Action: TCloseAction);
var FreeCgForm:TFreeCgForm;
begin
if HandleCall<>0 then FreeCgForm(HandleCall);
end;这样写仍是错误的?原意是不想让客户多次ShowDllForm的,但因为要让Dll在指定的Parent上显示只能采取非模式显示Show,如果用ShowModal则DLL窗体不能在Parent中....请问有没有什么好的方法控制如果DLL已经Show了不能再次加载ShowDllForm呢?通过什么来检测?当客户重复点击如何让已经存在的DllForm显示在最上层呢?