关于动态调用dll 中的非模式窗体的问题?
----DLL 工程文件--
library BOMI01;uses
  SysUtils,
  Forms,
  Windows,
  Messages,
  Classes,
  uBOMI01 in 'uBOMI01.pas' {frmBom};{$R *.res}
var
  DLLApp: TApplication;
  DLLScr: TScreen;function CreateForm(App: TApplication; Scr: TScreen):TForm;
begin
  Application := App;
  Screen := Scr;
  Application.CreateForm(TfrmBom, frmBom);
  result:=frmBom;
end;procedure ExitDLL(Reason: Integer);
begin
  if Reason = DLL_PROCESS_DETACH then
  begin
    Application := DLLApp;
    Screen := DLLScr;
  end;
end;exports
  CreateForm;begin
  DLLApp := Application;
  DLLScr := Screen;
  DLLProc := @ExitDLL;
end.
--- dll 中的 窗体单元---
unit uBOMI01;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;type
  TfrmBom = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  frmBom: TfrmBom;implementation{$R *.dfm}end.
--调用的主窗体单元
unit uMainFrm;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ToolWin;type
  InvokeDLLForm = function(App: TApplication; Scr: TScreen): TForm;
  TfrmMain = class(TForm)
    StatusBar1: TStatusBar;
    CoolBar1: TCoolBar;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    procedure ToolButton1Click(Sender: TObject);
  private
    procedure LoadDllForm(DllName: string);
  public
    { Public declarations }
  end;var
  frmMain: TfrmMain;
  DLLForm: TForm;
implementation{$R *.dfm}
procedure TfrmMain.LoadDllForm(DllName: string);
var
  dllhandle: THandle;
  Dllsub: InvokeDLLForm;
begin
  dllhandle := loadlibrary('BOMI01.dll');
  if dllhandle <> 0 then
  begin
    @dllsub := GetProcAddress(dllhandle,'CreateForm');
    if Assigned(Dllsub) then
      DLLForm := Dllsub(application,screen) ;
      //dllform.Show;-- 问题点???
  end;
end;procedure TfrmMain.ToolButton1Click(Sender: TObject);
begin
  LoadDllForm('BOMI01.dll')
end;
end.问题: 因为是初学DLL ,所以上属代码是简单的抄别人的代码,不知为何别的人代码在调用时不需要在调用的地主加上dllform.show ,就能正常运行,而我的不加dllform.show 就不法显示dll 中的窗体,而且我加上dllform.show 后,dll 中的窗体能显示出来,
但在关闭了dll 中的窗体后,再关闭调用的主程序,会报内存地址错误!
--别人的代码如下:
library prjDLL;uses
  SysUtils,
  Forms,
  Windows,
  Messages,
  Classes,
  DLLFormUnit in 'DLLFormUnit.pas' {frmDLLFrm};{$R *.res}var
  DLLApp: TApplication;
  DLLScr: TScreen;
function CreateDLLForm(App: TApplication; Scr: TScreen):TForm;
begin
  Application := App;
  Screen := Scr;
  Application.CreateForm(TfrmDLLFrm, frmDLLFrm);
  result:=frmDLLFrm;
end;procedure ExitDLL(Reason: Integer);
begin
  if Reason = DLL_PROCESS_DETACH then
  begin
    Application := DLLApp;
    Screen := DLLScr;
  end;
end;
exports
  CreateDLLForm;begin
  DLLApp := Application;
  DLLScr := Screen;
  DLLProc := @ExitDLL;
end.
------------
unit MainUnit;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, DB, ADODB, Grids, StdCtrls;type
  InvokeDLLForm = function(App: TApplication; Scr: TScreen): TForm;
  TfrmMain = class(TForm)
    MainMenu1: TMainMenu;
    M_Invoke: TMenuItem;
    mi_inDLL: TMenuItem;
    mi_inGeneral: TMenuItem;
    m_Windows: TMenuItem;
    N4: TMenuItem;
    N5: TMenuItem;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    procedure mi_inDLLClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  frmMain: TfrmMain;
  DLLForm: TForm;
implementationuses GeneralFormUnit, AboutUnit;{$R *.dfm}procedure TfrmMain.mi_inDLLClick(Sender: TObject);
var
  DLLHandle: THandle;
  DLLSub: InvokeDLLForm;
begin
  DLLHandle := LoadLibrary('prjDLL.dll');
  if DLLHandle <> 0 then
  begin
    @DLLSub := GetProcAddress(DLLHandle, 'CreateDLLForm');
    if Assigned(DLLSub) then
    begin
      DLLForm := DLLSub(Application, Screen);
    end;
  end;
end;end.

解决方案 »

  1.   

    >>不知为何别的人代码在调用时不需要在调用的地主加上dllform.show ,就能正常运行,而我的不加dllform.show 就不法显示dll 中的窗体,你说的问题,关键都在'DLLFormUnit.pas' 这个文件中,看看它的
    TfrmDLLFrm 的 onCreate 和 onClose 事件中做了什么
      

  2.   

    编号:20786 发送者:microd 发送时间:2005-11-5 8:26:20 删除  回复 
    接受者:aiirii 重要性:重要性:1 非常不重要重要性:2 不重要重要性:3 一般重要性:4 重要重要性:5 非常重要 
    内容 http://community.csdn.net/Expert/topic/4372/4372786.xml?temp=.6672785
    朋友 ,你好,我看了'DLLFormUnit.pas' ,在onCreate 和 onClose 事件中没做了什么? 
    如果没有,那
    Application.CreateForm(TfrmBom, frmBom);应该是第一个create 的窗体,只有主窗体,才会自动显示,感觉,但你的代码,又是在一个窗体的button click 中调用的,我就不明白
      

  3.   

    另外,关于动态调用DLL中的窗体,我看了不少代码,但都不一样,有没有一种比较标准的写法。
      

  4.   

    关于动态调用DLL中的窗体肯定你遗漏了那里的代码,要么,还必须导出个函数来释放,
    从上面的代码看,肯定会出问题的