急救!关于Dll方面的疑问:装载了dll后,直接关闭主程序会报错...(不够可以再加)(200分)

  • 主题发起人 主题发起人 cnhotel
  • 开始时间 开始时间
C

cnhotel

Unregistered / Unconfirmed
GUEST, unregistred user!
主程序分别调用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在主程序中何时调用?该怎么样调用?

以上描述的如不清楚随时跟贴说明~~~~

麻烦大家了!~
 
不能沉下去,希望路过也帮顶下~~
 
没弄过,帮你顶

是做stock呢,还是用;
 
谢谢楼上两位帮顶
继续自己顶~~
 
唉,大富翁的大虾们咋就不能出手相助呢?
难道大富翁真是日渐式微了吗???
 
先加sharemem再说,关注。。。。
 
加ShareMem也没变化,主程序表面上关闭了,在进程中还是运行中,仅仅是隐藏了
不晓得啥问题,哭~~
 
问题弱智,高手不答,在dll.dpr

procedure Killme(Reason:Integer);
begin
if (Reason = DLL_PROCESS_DETACH) and (DllForm<> nil) then DllForm.free;
end;

begin
DLLProc := @Killme;
end.
 
楼上,加了还是不行~~~是加在Stock.dpr中
仍是老样子,主程序窗体没了,但在进程中还没结束~~
 
网上搜一下 delphi dll 子窗体 会有解决方案的
 
Dll中Appliation.handle:=調用者的application.handle
 
搜索过部分
没有找到正解...(dll用的也不是子窗体)

楼上:stock.dll中
Appliation.handle:=AHandle;刚才添加了,这个是挂靠到主程序句柄的意思吧
重新编译了,调用仍是关不掉主程序...
 
“指定了它们的父窗体Parent为主程序中的一个Panel”,我不觉得这是种正常的编程方法,而且这种不规范的界面,给客户也是不好的感觉,我没有见过大公司的软件,使用
这种编程方法,类似这种另类的编程方法,会带来很多隐性的麻烦!

其中一种麻烦就是,父窗口已经撤销,而子窗口没有撤销,这瞬间子窗口突然没有了父
窗口,你觉得系统会应该帮你处理呢?

或者你应该考虑一下,在主窗口close事件里面,调用dll相关关闭窗口的函数,或者重
新指定子窗口的Parent:=nil,或者free。
 
特别感谢kinneng的提醒,调整方向和思路了
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部