继承方法,
在Mdi中,delphi没有提供在一个exe中有不同的hint操作方式.
这是delphi本身的bug,他们不想再修正mid下的错误

解决方案 »

  1.   

    没明白,什么叫exe中有不同的hint操作方式?我只是想让dll中的mdichild的hint显示出来而已,并不是不同的hint操作方式呀?
      

  2.   

    请确定你已经将 Application传递给了子窗口;并正常使用;
      

  3.   

    把Application.Handle传递给DLL的Application.Handle
      

  4.   

    我试了一下,什么问题都没有啊!,DLL工具条上的按纽HINT能正常显示啊!
      

  5.   

    到是DLL彩单的Hint没有显示出来,但也报任何错误信息!
      

  6.   

    其他控件的Hint都能出来,就是菜单不行,不可我看了WORD、DELPHI本身的菜单也没有菜单的Hint。讲讲你是怎样调用DLL的MDI子窗体吧!
      

  7.   

    问题解决了,做法如下
    把exe的Application传入DLL后,一定要重新激活传入的Application的Hint属性,如下
      Application.ShowHint := False;
      Application.ShowHint := True;当DLL在释放时,一定要设置 Application.ShowHint := False;原因:
      EXE的Application 使用HintWindowClass来创建一个新的HintWindow句柄,这个HintWindowClass的内存空间是在Exe 中,当把Application传入DLL后,原来的那个HintWindowClass的内存句柄对Application来讲已经是无效的了(可能是)地址空间不同,因此需要重新修正这个句柄的位置,办法就是重新激活Application.ShowHint事件,这样当执行DLL中的Component显示时,Application将用DLL执行空间的HintWindowClass来创建新的HintWindow显示Hint。
      同理,当DLL在被释放时,应该把Application的ShowHint属性关闭,以防止Exe中的Hint调用已经释放掉的(存在于原来的DLL)HintWindowClass句柄。  不知讲的对不对。请指教
      

  8.   

    我好象什么都没做,很自然就有了,跟在EXE中使用MDIChild一样,只是给它们的HINT赋了值,然后就行啦!
      

  9.   

    1.动态连接库中主要代码:
    1.1  Library单元
    procedure CallModule(AHandle: THandle; DCom: TDComconnection; Func_ID: Integer);export;stdcall;
    begin
       Application.Handle := AHandle;
       DComcon := DCom;
       if not Assigned(FormChildFirst) then
           FormChildFirst := TFormChildFirst.Create(Application);
       FormChildFirst.Show;
    end;1.2 MDICHILD单元procedure TFormChildFirst.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
        Action := caFree;
    end;procedure TFormChildFirst.FormDestroy(Sender: TObject);
    begin
        FormChildFirst := nil;
    end;2.宿主程序
    typeTCallModule =  procedure(AHandle: THandle; ADCom: TDComconnection; Func_ID: Integer);stdcall;
    procedure LoadModule(AModuleName: String; AFunc_ID: Integer);
    var
        CallModule: TCallModule;
    begin
        LibHandle := LoadLibrary(PChar(AModuleName));
        try
            if LibHandle = 0 then Exit;
            @CallModule := GetProcAddress(LibHandle,'CallModule');
            if @CallModule <> nil then
                CallModule(Application.Handle,PublicDM.dcomcGL,AFunc_ID);
        finally    end;
    end;
    procedure TFormMain.NKJKMGLClick(Sender: TObject);
    begin
    {}          LoadModule('DLL_Child.DLL',1);
    end;
    此外,参数Func_ID,DCOM与你无关,可以不要
      

  10.   

    先谢谢啦,不过这样调用mdichild的话好像有个问题没有解决呀? MDI的主Form的MDIChildCount不会因为子窗口的出现和消灭变化呀。这样在Exe的MDI主Form下就没有办法找特定的Form了。怎么办?
      

  11.   

    没问题啊,而且还能通过MDIChildren[index]控制子窗体,对了你编译DLL和EXE都得带RunTime Package编译
      

  12.   

    是这样,那我知道了,你是用Runtime package来建立dll和exe的。这样的运作方式是可以的,但是我不希望在给用户分发应用的时候带上几M的vclxx包。delphi的package和win32意义上的dll是有区别的,并不是真正的dll,好像delphi在这里做了特殊的处理。 package在动态载入的时候是直接映射到exe的执行空间了,所以不存在dll存在自己的映射空间问题。所以这样运作的时候所有的变量都是共享的,就好像在win16上的运行一样(类比而已)
      

  13.   

    DLL的Hint还是能出来,但DLL的菜单就失灵啦,此外,多个子窗体同时打开后最大化,然后关闭子窗体,到最后一个子窗体时,就不见该子窗体的最大、小化按纽和关闭按纽,而且不能通过MDIChildren[index] 访问子窗体,MDIChildCount也为0,这是为什么?
      

  14.   

    办法就是重新激活Application.ShowHint事件,这样当执行DLL中的Component显示时,Application将用DLL执行空间的HintWindowClass来创建新的HintWindow显示Hint。
      同理,当DLL在被释放时,应该把Application的ShowHint属性关闭,以防止Exe中的Hint调用已经释放掉的(存在于原来的DLL)HintWindowClass句柄。  这段话很正确
      

  15.   

    liusp,你的问题可以这样解决:把exe中的Application和Screen两个变量都传进去,替换掉dll中的这两个变量就可以了。记得释放dll的时候把这两个变量还原会去
      

  16.   

    Suvi ,详细点啦!我等你几天啦!
      

  17.   

    好象不行,我都传到DLL中去啦,都不行
      

  18.   

    var
      DLLApplication :TApplication;
      DLLScreen      :TScreen;
    procedure InitializeDLL(MainApplication :TApplication;
                            MainScreen :TScreen
                           );stdcall;procedure DLLUnloadProc(dwReason: Integer);register;implementation
    procedure InitializeDLL(MainApplication :TApplication;
                            MainScreen :TScreen
                            );
    begin
      Application := MainApplication;
      Application.ShowHint := False;
      Application.ShowHint := True;
      Screen := MainScreen;
    end;procedure DLLUnloadProc(dwReason: Integer);register;
    var
      i :integer;
    begin
      case dwReason of
        DLL_PROCESS_ATTACH://, DLL_THREAD_ATTACH:
          begin
            DLLApplication := Application;
            DLLScreen      := Screen;
            Application.ShowHint := False;
          end;
        DLL_PROCESS_DETACH:
          begin
            Application.ShowHint := False;
            Application := DLLApplication;
            Screen  := DLLScreen;
          end;
      end;
    end;     
    -------------------------------------------------------------------
    你在exe中调用dll的时候,就显示的调用一下InitializeDLL,这样就可以了
      

  19.   

    不行,关闭子窗体第二次再打开还出现一个错误提示:Can't Assign a TFont to Tfont
      

  20.   

    你的子窗体是否放了TMainMenu控件,如果没有放就正常,否则就有上述我说的错误!
      

  21.   

    procedure ShowChild(App: TApplication; DCom: TDispatchConnection; AScreen: TScreen);stdcall;export;
    begin    Application := App;
        Application.ShowHint := False;
        Application.ShowHint := True;
        Screen := AScreen;
        DComcon := DCOM;
        if not Assigned(FormChild1) then
           FormChild1 := TFormChild1.Create(Application);
        FormChild1.Show;
    end;procedure  MyLibraryProc(Reason: Integer);
    begin
       case Reason of
        DLL_PROCESS_ATTACH://, DLL_THREAD_ATTACH:
          begin
            DLLApp := Application;
            GScreen  := Screen;
            Application.ShowHint := False;
          end;
        DLL_PROCESS_DETACH:
          begin
            Application.ShowHint := False;
            Application := DLLApp;
            Screen  := GScreen;
          end;
      end;end;
    exports
       ShowChild;begin
        DLLProc := @MyLibraryProc;
    end.
      

  22.   

    好了,是这样的,所以还是在dll中的childwin里不要包括这些menu和statusbar了,为什么?我们在初始化dll的时候只是传入了 application和screen两个变量,这两个变量是在Forms李声明的。TMenu等是在 Menus 里定义的.delphi中有很多全局变量在个个单元中有定义,因此不可能把所有这些同步到dll中的,还是放弃比较好,你说那?
      

  23.   

    我最后还是带包编译,只要一个包即Vcl50.bpl,但也将近2M,发布时带上这个包和动态连接库BORLNDMM.DLL就行!
      

  24.   

    MDIChildCount为零的话,你不要用这个,而是自己定义一个消息,在子窗体show或 create时发消息。
      

  25.   

    传一个Screen到DLL中替代其中的Screen即可解决MDIChild为零的问题,这一点
    Suvi应该是作了研究!