Delphi Dll 消息处理 Dll (3)
procedure DestoryDLL; stdcall;var i: Integer;begin for i := Application.ComponentCount - 1 downto 0 do begin if Application.Components[i].ClassNameIs('TDLLChildForm') then begin TDLLChildForm(Application.Components[i]).Release; end; end; if DLLForm = nil then begin Exit; end; DLLForm.Release; DLLForm := nil;end;
再给主程序主窗体的OnCloseQuery添加代码如下:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
DestoryDLL;
end;
运行. 靠, 虽然DLL里的窗体全关闭了, 可主程序还是退不出啊. 换换方法, 把 DLLForm.Release; 这里改成Application.Terminate; 试试. 还是不行. 咋回事?
反复调试, 发现虽然Terminate了, 可Run仍在循环. 并没有结束.
再研究Run的代码. 呵呵. 有了.
把Application.Terminate;换成PostMessage(Application.Handle, WM_QUIT, 0, 0);
运行, 还是不行. 但Run是循环是退出了. 那哪里还会有问题呢? 该不会是窗体没有释放吧. 好, 在PostMessage前加上DLLForm.Release;这时, DestoryDLL过程的代码如下:
procedure DestoryDLL; stdcall;var i: Integer;begin for i := Application.ComponentCount - 1 downto 0 do begin if Application.Components[i].ClassNameIs('TDLLChildForm') then begin TDLLChildForm(Application.Components[i]).Release; end; end; if DLLForm = nil then begin Exit; end; DLLForm.Release;// Application.Terminate; PostMessage(Application.Handle, WM_QUIT, 0, 0); DLLForm := nil;end;
运行. OK. 完美解决...
再加上线程试试( 这时InitDLL过程要改成如下, 这样才能真正的处理所有的消息 ) . 真爽. 与想像的一样.
procedure InitDLL(AHandle: Thandle); stdcall;begin Application.Initialize; Application.ShowMainForm := False; Application.CreateForm(TDLLForm, DLLForm); // 保存原来的句柄 DLLForm.Tag := Application.Handle; // DLL 从属的句柄 ( 如果没有此行, 线程的执行不能达到理想效果 ) // 并且这样才能真正的让消息循环处理它应处理的所有消息 Application.Handle := AHandle; Application.Run; Application.Handle := DLLForm.Tag;end;