动态连接库中的Hint显示问题 继承方法,在Mdi中,delphi没有提供在一个exe中有不同的hint操作方式.这是delphi本身的bug,他们不想再修正mid下的错误 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 没明白,什么叫exe中有不同的hint操作方式?我只是想让dll中的mdichild的hint显示出来而已,并不是不同的hint操作方式呀? 请确定你已经将 Application传递给了子窗口;并正常使用; 把Application.Handle传递给DLL的Application.Handle 我试了一下,什么问题都没有啊!,DLL工具条上的按纽HINT能正常显示啊! 到是DLL彩单的Hint没有显示出来,但也报任何错误信息! 其他控件的Hint都能出来,就是菜单不行,不可我看了WORD、DELPHI本身的菜单也没有菜单的Hint。讲讲你是怎样调用DLL的MDI子窗体吧! 问题解决了,做法如下把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句柄。 不知讲的对不对。请指教 我好象什么都没做,很自然就有了,跟在EXE中使用MDIChild一样,只是给它们的HINT赋了值,然后就行啦! 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与你无关,可以不要 先谢谢啦,不过这样调用mdichild的话好像有个问题没有解决呀? MDI的主Form的MDIChildCount不会因为子窗口的出现和消灭变化呀。这样在Exe的MDI主Form下就没有办法找特定的Form了。怎么办? 没问题啊,而且还能通过MDIChildren[index]控制子窗体,对了你编译DLL和EXE都得带RunTime Package编译 是这样,那我知道了,你是用Runtime package来建立dll和exe的。这样的运作方式是可以的,但是我不希望在给用户分发应用的时候带上几M的vclxx包。delphi的package和win32意义上的dll是有区别的,并不是真正的dll,好像delphi在这里做了特殊的处理。 package在动态载入的时候是直接映射到exe的执行空间了,所以不存在dll存在自己的映射空间问题。所以这样运作的时候所有的变量都是共享的,就好像在win16上的运行一样(类比而已) DLL的Hint还是能出来,但DLL的菜单就失灵啦,此外,多个子窗体同时打开后最大化,然后关闭子窗体,到最后一个子窗体时,就不见该子窗体的最大、小化按纽和关闭按纽,而且不能通过MDIChildren[index] 访问子窗体,MDIChildCount也为0,这是为什么? 办法就是重新激活Application.ShowHint事件,这样当执行DLL中的Component显示时,Application将用DLL执行空间的HintWindowClass来创建新的HintWindow显示Hint。 同理,当DLL在被释放时,应该把Application的ShowHint属性关闭,以防止Exe中的Hint调用已经释放掉的(存在于原来的DLL)HintWindowClass句柄。 这段话很正确 liusp,你的问题可以这样解决:把exe中的Application和Screen两个变量都传进去,替换掉dll中的这两个变量就可以了。记得释放dll的时候把这两个变量还原会去 Suvi ,详细点啦!我等你几天啦! 好象不行,我都传到DLL中去啦,都不行 var DLLApplication :TApplication; DLLScreen :TScreen;procedure InitializeDLL(MainApplication :TApplication; MainScreen :TScreen );stdcall;procedure DLLUnloadProc(dwReason: Integer);register;implementationprocedure 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,这样就可以了 不行,关闭子窗体第二次再打开还出现一个错误提示:Can't Assign a TFont to Tfont 你的子窗体是否放了TMainMenu控件,如果没有放就正常,否则就有上述我说的错误! 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. 好了,是这样的,所以还是在dll中的childwin里不要包括这些menu和statusbar了,为什么?我们在初始化dll的时候只是传入了 application和screen两个变量,这两个变量是在Forms李声明的。TMenu等是在 Menus 里定义的.delphi中有很多全局变量在个个单元中有定义,因此不可能把所有这些同步到dll中的,还是放弃比较好,你说那? 我最后还是带包编译,只要一个包即Vcl50.bpl,但也将近2M,发布时带上这个包和动态连接库BORLNDMM.DLL就行! MDIChildCount为零的话,你不要用这个,而是自己定义一个消息,在子窗体show或 create时发消息。 传一个Screen到DLL中替代其中的Screen即可解决MDIChild为零的问题,这一点Suvi应该是作了研究! 如何生成这样树形的字符串? dbchart的问题。急!!!!!!! Delphi 2006 代号 Dexter 与 C++Builder 10.0 即将推出 在QReport中打印固定表格线,有好的方法吗?必需解决本页合计问题! question!!! 如何判断ToolButton1被按了??? 关于三层应用系统的发布问题,我愿倾家荡产都可以! 100分在线等待,请高手指点如何生成二级菜单 怎样才能用程序关闭超级解霸的探测器呀????????? delphi的选择 工具条对应的imagelist中的图标很不清晰! 请问如何将报表翻页,报表上的哪几个翻页按钮怎么用呀???????
把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句柄。 不知讲的对不对。请指教
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与你无关,可以不要
同理,当DLL在被释放时,应该把Application的ShowHint属性关闭,以防止Exe中的Hint调用已经释放掉的(存在于原来的DLL)HintWindowClass句柄。 这段话很正确
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,这样就可以了
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.
Suvi应该是作了研究!