我自己没事做了一个小程序,也就是一个主程序通过菜单调用多个子模块(dll实现),每个子模块完成特定功能。
现在我想实现是:
  调用一个子模块后,不退出,可以再调用另一个子模块,怎么实现??
  我想实现的要求是不是多文档程序,不是很清楚.......希望提供一个思路.....

解决方案 »

  1.   

    我所说的模块就是一个个dll文件,每个dll文件有窗体、按钮和浏览控件组成,比如说打印模块,录入模块等等.....不知道我说清楚没有
      

  2.   


    在子模塊內的窗體將showmodal 改為show;不就行了麼.既然你想實現這種功能,推荐用MDI! 
    否則打開多個子窗體時,找不到它的父窗體, 使屏幕一片混亂!
      

  3.   

    用mdi可以调用dll作为子窗口么?自己up
      

  4.   

    主程序定义一个MDIForm,DLL中定义MDIChild,谁能提供一些思路,hoho......
      

  5.   

    tomboy0(小波波) 
    用mdi可以调用dll作为子窗口么?自己up
    -------------------------------------
    可以,调用DLL函数的时候传个APPLICATION参数即可
    一两句话说不清,自己摸索,呵呵
      

  6.   

    lzy6204兄弟:能不能写一段调用dll的代码给我参考一下,困扰了我好长时间,棒棒忙拉
      

  7.   

    {dll公共单元}
    unit dllpGlobalVar;interfaceuses
      Forms;
    var
      DLLApplication: TApplication;procedure SaveDLLApp(app: TApplication); //保存DLL的APPLICATIONfunction FindChildForm(MainApplication: TApplication; sClassName: string
      ): Boolean; //查找MDI窗口implementationprocedure SaveDLLApp(app: TApplication);
    begin
      if not Assigned(DLLApplication) then
      begin
        DLLApplication := Application;
        Application := app;
      end;
    end;function FindChildForm(MainApplication: TApplication; sClassName: string
      ): Boolean;
    var
      i: Integer;
    begin
      Result := False;
      SaveDLLApp(MainApplication);
      with Application.MainForm do
        for i := 0 to (MDIChildCount - 1) do
          if (MDIChildren[i].ClassName = sClassName) then
          begin
            MDIChildren[i].BringToFront;
            Result := True;
            Break;
          end;
    end;
    end.
    ---------------------------------
    {dll输出函数单元}
    unit UntExportFunction;interfaceuses
      Forms, DB, ADODB, Graphics, Windows, ComCtrls;//显示其中某个窗口
    procedure ShowExampleForm(
      MainApp: TApplication);
    implementationprocedure ShowExampleForm(
      MainApp: TApplication);
    var
      Child: TExampleForm;
    begin
      SaveDLLApp(MainApp);
      adoCon := con;
      if not FindChildForm(MainApp, 'TExampleForm') then
      begin
        Child := ExampleForm.Create(Application);
        CurrentUser := strCurrentUser;
        Child.Show;
      end;
    end;
    ----------------------------------------------------
    {工程文件单元}
    library DllprjHRM;{ Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }uses
      Sharemem,
      SysUtils,
      Forms,
      Classes,
      windows,
      ...
    {$R *.res}procedure MyLibraryProc(Reason: integer);
    begin
      if Reason = DLL_PROCESS_DETACH then
        if Assigned(DLLApplication) then
          Application := DLLApplication;
    end;exports
      ShowExampleForm;
    begin
      DllProc := @MyLibraryProc;
    end.---------------------------------
    调用应该会了吧^_^
      

  8.   

    现在调用dll问题解决了,可以在关闭应用程序时报内存出错(Access violation)!窗体释放的方法是在close
    事件中写action:=caFree,然后把窗口指针置为nil。
    请问为什么在应用程序关闭的时候会出错呢??
    如何解决??
      

  9.   

    内存管理单元Sharemem必须同时出现在exe和dll工程中,要么都不要,要么都包含
      

  10.   

    刚才写错了在关闭应用程序时报指针出错(invalid pointer operation)窗体释放的方法是在close
    事件中写action:=caFree,然后把窗口指针置为nil。
    请问为什么在应用程序关闭的时候会出错呢??
    如何解决??
      

  11.   

    h回 fjx99(fjx99):我在exe和dll工程中都加了内存管理单元Sharemem,还是报错,(Access violation),怎么回事?
      

  12.   

    我把每次的dll句柄存放在数组中,在应用程序结束的时候释放,
    for i:=1 to count_num do
      begin
        freeLibrary(dll_form[i]);
      end;
      application.Terminate ;
    唉,怎么办?每人帮帮我么?
      

  13.   

    搞复杂了
    dll里面的子窗口就跟平常的一样用
      

  14.   

    lzy6204兄弟:我没有用你的方法,我参照了大富翁上的一篇文章做的。具体如下:
    在DLL中建立一个TMDIChildForM
    1 Dll中的MDIForm.FormStyle不用为fmMDIChild.
    2 在CreateForm后写以下两句:
    function ShowForm(mainForm:TForm):integer;stdcall
    var
      Form1: TForm1;
      ptr:PLongInt;
    begin
      ptr:=@(Application.MainForm);//先把dll的MainForm句柄保存起来,也无须释放,只不过是替换一下
      ptr^:=LongInt(mainForm);//用主调程序的mainForm替换DLL的MainForm。MainForm是特殊的WINDOW,它专门管理Application中的Forms资源.
    //为什么不直接Application.MainForm := mainForm,因为Application.MainForm是只读属性
      Form1:=TForm1.Create(mainForm);//用参数建立
    end;
    备注:参数是主调程序的Application.MainForm九 示例:
    DLL源代码:
    library Project2;uses
      SysUtils,
      Classes,
      Dialogs,
      Forms,
      Unit2 in 'Unit2.pas' {Form2};{$R *.RES}
    var
      ccc: Pchar;procedure OpenForm(mainForm:TForm);stdcall;
    var
      Form1: TForm1;
      ptr:PLongInt;
    begin
      ptr:=@(Application.MainForm);
      ptr^:=LongInt(mainForm);
      Form1:=TForm1.Create(mainForm);
    end;procedure InputCCC(Text: Pchar);stdcall;
    begin
      ccc := Text;
    end;procedure ShowCCC;stdcall;
    begin
      ShowMessage(String(ccc));
    end;exports
      OpenForm;
      InputCCC,
      ShowCCC;
    begin
    end.调用方源代码:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Edit1: TEdit;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.DFM}
    procedure OpenForm(mainForm:TForm);stdcall;External'project2.dll';
    procedure ShowCCC;stdcall;External'project2.dll';
    procedure InputCCC(Text: Pchar);stdcall;External'project2.dll';procedure TForm1.Button1Click(Sender: TObject);
    var
      Text: Pchar;
    begin
      Text := Pchar(Edit1.Text);
    //  OpenForm(Application.MainForm);//为了调MDICHILD
      InputCCC(Text);//为了实验DLL中的全局变量是否在各个应用程序间共享
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      ShowCCC;//这里表明WINDOWS 32位应用程序DLL中的全局变量也是在应用程序地址空间中,16位应用程序或许不同,没有做实验。
    end;
      

  15.   

    我在主程序的窗口设置为fsMDIForm,其他子程序(dll的子窗口)中仍然设置为fsNormal,这几天一直在搞这个,还望大家多提意见,元旦之前不管解决与否都结贴。
      

  16.   

    其他子程序(dll的子窗口)中仍然设置为fsNormal
    ----------------------------------------------
    为什么不设置fsMDIChild?
      

  17.   

    我设置了fsMDIChild,结果dll没有调用起来,不知道什么原因,疑惑中........
    我认为我所用的方法不是完全的mdi程序,因为子程序没有用fsMDIChild,我认为肯定是资源没有释放,但是具体的就不知道,希望大家讨论一下
      

  18.   

    麻烦你发给我,参考一下,下午揭帖!!地址:[email protected]