150大洋-请大家帮助解决一个DLL中窗体现时的问题-DLL释放主窗体缩回到开始栏. (150分)

  • 主题发起人 主题发起人 joesu
  • 开始时间 开始时间
J

joesu

Unregistered / Unconfirmed
GUEST, unregistred user!
请大家帮助解决一个DLL中窗体现时的问题-DLL释放主窗体缩回到开始栏.
我这里有一个Delphi6.0开发软件过程中遇到的问题.
我想实现登陆以后进入主窗体,然后在主窗体里面动态的创建DLL调用DLL里面的FORM.数据库用的是SQL Server, ADO实现.
下面是我主工程的代码片段:
代码:
  Application.CreateForm(TfrmDatabase, frmDatabase);
  Application.CreateForm(TfrmLogin, frmLogin);
  Application.CreateForm(TfrmMain, frmMain);

frmDatabase, frmLogin, frmMain 都是自动创建的窗体.而且创建顺序如上排列.程序运行的时候,在frmLogin中把数据库的连接作好,如果登陆成功,就是显示主窗体. 在主窗体中单击相应的按钮执行相应的DLL. 调用DLL的时候,调用三个函数,分别是实现连接创建,显示DLL中的Form,释放连接.

主窗体中动态创建DLL的代码片段:
代码:
    LibHandle:=LoadLibrary(pchar(sDllName));
    if LibHandle<>0 then
    begin
      ConnCurDB:=GetProcAddress(LibHandle,pchar(sConnDBName));
      OpenCurForm:=GetProcAddress(LibHandle,pchar(sOpenFMName));
      FreeCurDB:=GetProcAddress(LibHandle,pchar(sFreeDBName));
      if @ConnCurDB<>nil then
      begin
        ConnCurDB(Application.Handle,PChar(m_connStr),PChar(m_sUserName),PChar(IntToStr(m_iEmployeeID)));
      end;
      if @OpenCurForm<>nil then
      begin
        OpenCurForm(Application.Handle);
      end;
       if @FreeCurDB<>nil then
      begin
        FreeCurDB(1);
      end;
      FreeLibrary(LibHandle);
    end;
下面是DLL中三个函数的程序块:
1,连接数据库:
代码:
function CreateProduceCenterDataBase(H:THandle;
                                      connStr:PChar;
                                      UserName: PChar;
                                      EmployeeID: PChar):LongInt;stdcall;
begin
 try
   Application.Handle:=H;
   Application.CreateForm(TfrmDataBase, frmDataBase);
  Result:=0;                   //成功返回0,本来想返回数据模块的句柄值,如何返回?
   frmDataBase.conMain.ConnectionString:=connStr; { 获得数据库连接字符串 }
   m_connStr:= connStr; //将连接字符串复制到公用变量
 except
   Result:=-1; //调用失败,返回-1
 end;
end;
2,显示DLL中的窗体:

代码:
function ShowProduceAddMainForm(H: THandle):LongInt; stdcall;
var
  Add:TfrmAdd;
begin
  try
    Application.Handle := H;
    Add:=TfrmAdd.Create(Application);
    Result:=LongInt(Add);
    Add.Showmodal;
  finally
    Add.Free;
  end;
end;

3,释放数据库:
//释放数据DLL使用的数据模块
Procedure FreeProduceCenterDataBase(iParam: LongInt); stdcall;
begin
if iParam>0 then
   frmDataBase.Free;
end;

程序运行的时候就出现了下面的问题:
DLL里面窗体的显示非常正常,当关闭DLL的窗体的时候,发现主窗体就会缩回到工具栏,要点两下才会出来.
我后来进行改进,把FreeLibrary(LibHandle);这句删除,关闭的时候主窗体不会缩回工具栏,但是DLL却不会在关闭DLL窗体的时候自动释放.
开始怀疑是不是DLL用引用了一些指针或数据库连接没有释放,经过检查发现不是因为这个.
后来怀疑是不是由于frmLogin比主窗体frmMain先执行,我就把frmLogin整个去掉不要,直接在frmDatabase中把所有的连接的连接字符串做好.发现还是会缩回去.甚至随便创建一个DLL,都会缩回去.

小弟被这个问题快搞得崩溃了.请各位大侠执教.
我的电子邮件:hyl@gd165.com

 
我是这样作的:
procedure TMainForm.ClearButtons;
var
I: Integer;
Btn: TdxBarLargeButton;
begin
// 如果应用没有是否,则释放应用动态连接库
if LibHandle <> -1 then FreeLibrary(LibHandle);

for I := dxBarGroup1.Count - 1 downto 0 do
begin
Btn := TdxBarLargeButton(dxBarGroup1.Items);
Btn.Free;
end;
end;

procedure TMainForm.RefreshTools;
var
I: Integer;
TreeNode: TTreeNode;
FileName: string;
begin
TreeNode := TreeView1.Selected;
if CurrentTreeNode = TreeNode then Exit;
LockWindowUpdate(Self.Handle); // 锁主屏幕更新
try
ClearButtons;
if (TreeNode <> nil) and (TreeNode.Level > 0) then
begin
FileName := TFunctionItem(TreeView1.Selected.Data).Location;
FileName := ExtractFilePath(Application.ExeName) + 'Plugins/' + FileName;
LibHandle := LoadLibrary(PChar(FileName));
if LibHandle <> 0 then // 是否载入成功
begin
PluginCallProc := GetProcAddress(LibHandle, 'PluginCallProc');
if Assigned(PluginCallProc) then
begin
PluginCallProc(OGD, 0);
for I := 0 to dxBarGroup1.Count - 1 do
begin
with TdxBarLargeButton(dxBarGroup1.Items) do
Visible := ivAlways;
end;
end;
end;
end;
CurrentTreeNode := TreeView1.Selected;
finally
LockWindowUpdate(0);
end;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
ClearButtons;

DM.ADOConnection.Close;

SaveWinInfo(Self);
end;
 
后退
顶部