//DLL工程代码procedure SyScallForm(Mainform: Tform; FormName: string); stdcall;
begin
  if FormName = 'frm_base' then
  begin
    frm_base := Tfrm_base.Create(Mainform);
    frm_base.Show;
  end;
end;exports
  SyScallForm;end.
//Frm_Main代码
var
  Frm_Main: TFrm_Main;
  SysMoudle: Thandle;
  SyScallForm: procedure(Formu: TForm; FormName: string); stdcall;implementation{$R *.dfm}procedure TFrm_Main.FormCreate(Sender: TObject);
begin
  try
    SysMoudle := LoadLibrary('.\Sysmdl.dll');
    SyScallForm := GetProcAddress(SysMoudle, 'SyScallForm');
  except
    showmessage('出错啦!');
  end;
end;procedure TFrm_Main.b1Click(Sender: TObject);
begin
  SyScallForm(Frm_Main, 'frm_base',)
end;
//点击出现no mdi form are active错误

解决方案 »

  1.   

    是不是你的Form使用MDI的问题呀??http://lysoft.7u7.net
      

  2.   

    exe和dll编译时都使用Package
    BTW,参数最好不使用string,使用PChar或者ShortString,否则要包含ShareMem单元
      

  3.   

    那DLL那个是MDICHILD
    EXE是MDIFORM
    加了ShareMem也不行
      

  4.   

    ?为什么在FormCreate事件中做?
      

  5.   

    //上面我写错了,你的代码问题很多呀,呵呵,没有必要传TForm对象的,用下面的代码,不过,你的初始化化事件也要写的
    procedure SyScallForm(AppHandle: HWND; FormName: string); stdcall;
    begin
      Application.Handle := AppHandle;
      if FormName = 'frm_base' then
      begin
        if frm_base = nil then
          frm_base := Tfrm_base.Create(Application);
        frm_base.Show;
      end;
    end;exports
      SyScallForm;end.
      

  6.   

    楼上的SHOW出来的只是普通的窗口,不是子窗口来的。
      

  7.   

    ????你懂不懂呀,楼上的SHOW出来的只是普通的窗口,不是子窗口来的。????
    没有办法,看来你还是菜的,我无话可说了
      

  8.   

    我要SHOW出来的就是子窗口啊,DLL中的SHOW出来的出口是子窗口,EXE中的窗口是父窗口啊。
      

  9.   

    是show出自窗体呀,目前你连MDI都没有搞清楚,
    管它是不是DLL,具体的原理都是一样的
    父类窗体设为MDIForm就可以了,组件的内部窗体只要你设为MDIChild按照正常窗体输出方法完全可以达到Show的操作。
    具体的接口一般是这样的:
    在DLL中定义全局的变量用于置换
    var
      DllApplication: TApplication;
      DllScreen: TScreen;
    procedure ShowForm1;
    begin
      if form1 = nil then
       form1 := Tform1.Create(Application);
      Form1.Show;
    end;procedure ShowFormProc(iFuncId: Integer; hParentAppHandle: HWND; 
      pScreen: TScreen);Stdcall;
    begin
      Application.Handle := hParentAppHandle;
      Screen := pScreen;
      case iFuncId of
       1: ShowForm1;//触发事件1 输出TForm对象
       2: 触发事件2
       ....
      end;
    end;
    //DLL入口事件
    procedure DllUnLoadProc(Reason: Integer);
    begin
      if Reason = DLL_PROCESS_DETACH then
      begin
        Application := DllApplication;
        Screen := DllScreen;
      end;
    end;exports
      ShowFormProc name 'ShowFormProc';begin
      DllApplication := Application;
      DllScreen := Screen;
      DllProc := @DLLUnloadProc;
    end;DLL只是一个组件,如果把它集成到一个工程里就是一样的,只不过组件化管理易于升级和维护。Delphi输出窗体,必须将DLL的TApplication对象赋值为宿主程序的TApplication对象,为了方便接口的书写,目前一般是将TApplication对象的句柄传到DLL组件内部,否则你的Show出的窗体肯定会报内存错误。这是一个完整的输出窗体的Form的接口实例,不要认为一定要不主窗体对象传进来,如果是非MDI的多文档窗口显示,你需要将相关的宿主对象句柄传进来
    比如可以将Dll中的Form Show到一个Panel上、Form上,这样的操作就稍微麻烦一些,不过在论坛里有解决的方案
      

  10.   

    TO:czx0514(自己创业) 
    DLL执行老是有问题,请问你有没有这方面的代码啊?按你在论坛上说的,还错,刚接触希望能帮帮忙
    //DLL单元,form1为DLL中的中的窗口,Formstyle为fsMDIChildlibrary bb;uses
      forms,
      Windows,
      Unit1 in 'Unit1.pas' {Form1};
    var
      DllApplication: TApplication;
      DllScreen: TScreen;{$R *.res}procedure ShowForm1;
    begin
      if form1 = nil then
        form1 := Tform1.Create(Application);
      form1.Show;
    end;procedure ShowFormProc(iFuncId: Integer; hParentAppHandle: HWND; pScreen: TScreen); stdcall;
    begin
      Application.Handle := hParentAppHandle;
      Screen := pScreen;
      case iFuncId of
        1: ShowForm1; //触发事件1 输出TForm对象
    //    2: 触发事件2
    //      ....
      end;
    end;//DLL入口事件
    procedure DllUnLoadProc(Reason: Integer);
    begin
      if Reason = DLL_PROCESS_DETACH then
      begin
        Application := DllApplication;
        Screen := DllScreen;
      end;
    end;exports
      ShowFormProc name 'ShowFormProc';begin
      DllApplication := Application;
      DllScreen := Screen;
      DllProc := @DllUnLoadProc;
    end.
    //EXE单元,执行TFrm_Main.b1Click事件时,出现NO MDICHILD FOUND的错误,怎么解决啊?unit Main;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Menus;type
      TFrm_Main = class(TForm)
        MainMenu1: TMainMenu;
        a1: TMenuItem;
        b1: TMenuItem;
        procedure FormCreate(Sender: TObject);
        procedure b1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Frm_Main: TFrm_Main;
      SysMoudle: Thandle;
      ShowFormProc:procedure(iFuncId: Integer; hParentAppHandle: HWND; pScreen: TScreen);Stdcall;implementation{$R *.dfm}procedure TFrm_Main.FormCreate(Sender: TObject);
    begin
      try
        SysMoudle := LoadLibrary('.\bb.dll');
        ShowFormProc := GetProcAddress(SysMoudle, 'ShowFormProc');
      except
        showmessage('出错啦!');
      end;
    end;procedure TFrm_Main.b1Click(Sender: TObject);
    begin
      ShowFormProc(1, Frm_Main.Handle,Screen);end;end.
      

  11.   

    不好意思,我将宿主的父类对象搞错了,你将
    procedure ShowFormProc(iFuncId: Integer; hParentAppHandle: HWND;...)  
    改为procedure ShowFormProc(iFuncId: Integer; hParent: TApplcation; ...) 
    就可以了代码可以稍微改一下
    //下面是我做的测试
    //Dll组件程序
    library DllMoudle;
    uses
      SysUtils,
      Classes,
      Windows,
      Forms,
      f_ModuleSample1 in 'f_ModuleSample1.pas' {Form1};{$R *.res}var
      DllApplication: TApplication;
      DllScreen: TScreen;procedure ShowFormProc(lBusinId: Integer; pApp: TApplication; pScreen: TScreen);stdcall;
    begin
      Application := pApp;
      Screen := pScreen;
      case lBusinId of
        1: ShowForm1Proc;
        2: ;
      else ;
      end;  
    end;//DLLÈë¿Úʼþ
    procedure DllUnLoadProc(Reason: Integer);
    begin
      if Reason = DLL_PROCESS_DETACH then
      begin
        Application := DllApplication;
        Screen := DllScreen;
      end;
    end;exports
      ShowFormProc name 'ShowFormProc';begin
      DllApplication := Application;
      DllScreen := Screen;
      DllProc := @DllUnLoadProc;end.//DLL Form单元
    unit f_ModuleSample1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;type
      TForm1 = class(TForm)
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;procedure ShowForm1Proc;implementationprocedure ShowForm1Proc;
    begin
      if Form1 = nil then
        Form1 := TForm1.Create(Application);
      Form1.Show;
    end;{$R *.dfm}procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action := caFree;
      Form1 := nil;
    end;end.
    //Exe程序
    unit f_Exe;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Menus;type
      TShowFormProc = procedure (lBusinId: Integer; pAppHandle: TApplication; pScreen: TScreen);stdcall;
      TForm1 = class(TForm)
        MainMenu1: TMainMenu;
        N1: TMenuItem;
        ShowForm11: TMenuItem;
        procedure ShowForm11Click(Sender: TObject);
      private
        { Private declarations }
        FShowFormProc: TShowFormProc;
        FDllHandle: Longint;
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}procedure TForm1.ShowForm11Click(Sender: TObject);
    begin
      FDllHandle := LoadLibrary('DllMoudle.dll');
      if FDllHandle = 0 then
      begin
        ShowMessage('组件装载出错!');
        Exit;
      end;
      @FShowFormProc := GetProcAddress(FDllHandle, PChar('ShowFormProc'));
      if @FShowFormProc = nil then
      begin
        ShowMessage('组件事件装载出错!');
        Exit;
      end;
      //响应事件
      FShowFormProc(1, Application, Screen);
    end;end.