delphi dll mdi

场景:Delphi MDI加载dll的有关问题()

Delphi MDI加载dll的问题(在线等)
本帖最后由 longerhe 于 2010-08-05 14:43:59 编辑 本人的架构是:主程式是MDI的方式,各个功能用dll来实现。加载dll时,在主程式中动态创建一个form,并把dll中的窗体显示在这个form上(Dll中的窗体上有关闭按钮)。

Dll:
//点击主程式中动态创建的form的关闭按钮调用此procedure
procedure CloseDll(Application:TApplication; SenderOwner:TForm); 
begin
   try
      if frmOperate<>nil then    //释放dll中的form
         freeandnil(frmOperate);
         
      if frmMain<>nil then
         freeandnil(frmMain);
         
      freeandnil(SenderOwner);   //释放主程序中动态创建的form
   except
      on E:Exception do raise Exception.create('(CloseDll)'+E.Message);
   end;
end;

//点击菜单项时,加载dll中的form,并显示在SenderOwner(即主程式中动态创建的form)
procedure InitDll(Application:TApplication; SenderOwner:TForm; UserID:String; ADOConnection:TADOConnection);
begin
   try
      frm:=SenderOwner; //本意是想当点击dll中窗体上的关闭按钮时,释放主程式中动态创建的form
      frmMain:=TfrmMain.Create(nil);
      With frmMain do
      begin
         ParentWindow:=SenderOwner.Handle;
         Align:=alClient;
         BorderStyle:=bsNone;
         color:=SenderOwner.Color;
         sUserID:=UserID;
         Show;
      end;
   except
      on E:Exception do raise Exception.create('(InitDll)'+E.Message);
   end;
end;

procedure TfrmMain.btnExitClick(Sender: TObject);//dll中关闭按钮事件
begin
   try
      if frmOperate<>nil then
         freeandnil(frmOperate);

      if frmMain<>nil then
         freeandnil(frmMain);

      freeandnil(frm);
   except
      on E:Exception do raise Exception.create('(CloseDll)'+E.Message);
   end;
end;

主程式:
procedure TfrmMain.MenuClick(Sender: TObject);
var
   sDllName,sFrmCaption:string;
begin
   sFrmCaption:=TMenuItem(Sender).Caption;
   sDllName:=GetDllName(sFrmCaption);

   if not dmsys.FormIsOpen(sFrmCaption) then //通过caption属性判断form是否存在
   begin
      try
        with dmsys do
        begin
           m_DLLHandle := LoadLibrary(pchar(ExtractFilePath(Application.exename)+DLL_Name));
           if m_DLLHandle <= 32 then
              raise Exception.create('Can Not Find DLL File(' + DLL_Name + ')');

           m_InitDll := GetProcAddress(m_DLLHandle, 'InitDll');
           if (@m_InitDll = nil) then
              raise Exception.Create('DLL Function Not Match (1)');

           m_CloseDll := GetProcAddress(m_DLLHandle, 'CloseDll');
           if (@m_CloseDll = nil) then
              raise Exception.Create('DLL Function Not Match (2)');

           frmForm:=TfrmForm.create(self);
           frmForm.Caption:=Form_Caption;
           frmForm.Show;
        end;
      except
        on E: Exception do raise Exception.create('(' + ClassName + '.LoadDll)' + E.Message);
      end;
   end;
end;

frmForm的事件
procedure TfrmForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   //Action:=cafree;
   with dmsys do
   begin
      m_CloseDll(Application,Tform(Sender));
   end;
end;

procedure TfrmForm.FormShow(Sender: TObject);
begin
   with dmsys do
   begin
      m_InitDll(Application,Tform(Sender),UserID,AdoConnection1);
   end;
end;

这段程序的问题是当点击dll中的关闭按钮时,主程式中的frmform会关闭,但是会报一个内存错误。


------解决方案--------------------
第一次报一个内存错误,在点击关闭会报“Abstract error”