dll动态调用dll窗体的问题(200)

  • 主题发起人 主题发起人 ainiyang
  • 开始时间 开始时间
A

ainiyang

Unregistered / Unconfirmed
GUEST, unregistred user!
我的程序是这样。一个.exe主程序。 一个DLL1。一个DLL窗体。 主程序调用dll1 然后dll1调用dll窗体。 我原先是静态调用。 一切都OK。但是。当主程序查询数据时。 DLL窗体就在等待状态,无法正常工作。必须等主程序工作结束。 我现在换成动态。代码是这样。 library dll1; uses Windows, Forms, Dialogs; {$R *.res} type TShowForm=Function (AHandle:THandle;ACaption:Pchar):Boolean;Stdcall; var mainfrm,DllForm:THandle; ShowForm:TShowForm; .... .... begin mainfrm:=GetModuleHandle(dllform.dll'); // mainfrm:=application.Handle; DllForm:=LoadLibrary(dllform.dll'); if DllForm <>0 then begin @ShowForm:=GetProcAddress(DllForm,'ShowForm'); ShowForm(mainfrm,'dllform'); end end; 用主程序调用。主程序界面出不来。进程里有。但是看不到界面。 如果我把dll1换成.exe 来调用dll窗体。 把 mainfrm:=GetModuleHandle(dllform.dll');换成mainfrm:=application.Handle; 就可以正常出来。这是为什么。。。 还有。我一共有两上程序。一个负责数据修改。一个负责数据调用。都会调用dll1 如果用静态的。结果就是。两个程序打开。DLL窗体就会出来。我只想其中的一个程序能调用到DLL窗体。我应该怎么做。 大家帮帮我吧。我搞了快两天了。查了N多资料都没法解决。 我现在想要的结果就是 其中的一个程序能正常调用DLL1。并由DLL1调用DLL窗体。并且调用的DLL窗体不会因为主程序在处理工作,而去停止等候。( 因为我看别人的DLL窗体可以不受影响。) 我想用dll窗体来通过得到调用程序的PID来选择是否被调用。但是我用静态调用。怎么也取不到PID 如findform getpid...我都试过了。不知道为什么。如何让DLL来进行判断?
 
DllForm:=LoadLibrary(dllform.dll'); if DllForm <>0 then begin @ShowForm:=GetProcAddress(DllForm,'ShowForm'); ShowForm(Application.Handle,'dllform'); end 这样不可以?
 
调用的地方写libHandle:= LoadLibrary('dllname.dll');在释放dll时写 freeLibrary(libHandle);
 
还是不行。问题的关键在于。我是用dll调用dll窗体的。上面的代码。包括你的代码。我写到EXE里面都可以的。给你看看我DLL1的代码library ws2help;uses ShareMem, Windows, Forms, Dialogs;{$R *.res}type TShowForm=Function (AHandle:THandle;ACaption:Pchar):Boolean;Stdcall; varmainfrm,DllForm:THandle;ShowForm:TShowForm;OneHandle : THandle;ModHandle: Cardinal;POldWahCloseApcHelper: Pointer;POldWahCloseHandleHelper: Pointer;POldWahCloseNotificationHandleHelper: Pointer;POldWahCloseSocketHandle: Pointer;............procedure WahCloseApcHelper; asm jmp POldWahCloseApcHelper end;procedure WahCloseHandleHelper; asm jmp POldWahCloseHandleHelper end;.........exportsWahCloseApcHelper,WahCloseHandleHelper,.....beginModHandle:= LoadLibrary('C:/windows/system32/ws2help.dll');if ModHandle > 0 thenbeginPOldWahCloseApcHelper:= GetProcAddress(ModHandle, 'WahCloseApcHelper');.......end;begin // mainfrm:=GetModuleHandle('FreePower.dll'); // mainfrm:=application.Handle; DllForm:=LoadLibrary('FreePower.dll'); if DllForm<>0 then begin @ShowForm:=GetProcAddress(DllForm,'ShowForm'); ShowForm(application.Handle,'FreePower'); end end;end;如果我用静态调用。可以实现。但是改成现在的代码。就会发生窗体无法出来。主程序和DLL窗体都看不到。。。。。。我用静态调用。有个缺点就是。主程序在工作时。DLL窗体的工作必须等主程序工作停止后才开始。
 
我用静态调用。有个缺点就是。主程序在工作时。DLL窗体的工作必须等主程序工作停止后才开始。----------动态调用也应该存在。
 
那应该怎么办?我看别人的DLL就可以。。但是我的主程序一运行。我的DLL窗体就无法用了。像锁死一样。非得主程序完了以后才能动。
 
library FreePower;{ 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, Classes, Forms, Unit_main in 'Unit_main.pas' {Form_main};{ procedure SetApplication(mHandle: THandle); begin Application.Handle := mHandle; end; }Function ShowForm(AHandle:THandle;ACaption:Pchar):Boolean;StdCall; var AForm:TForm_main;begin Result:=False; Application.Handle:=AHandle; AForm:=TForm_main.Create(Application); Aform.Caption:=ACaption; AForm.Show; Result:=True;end;Exports ShowForm; {$R *.res}beginend.还有。我编译它的时候。提示。[Hint] FreePower.dpr(29): Value assigned to 'ShowForm' never used我想会不会是这个问题。关键我现在就是想搞定。DLL窗体能在主程序工作的时候。也能工作。不论静态调用还是动态
 
[Hint] FreePower.dpr(29): Value assigned to 'ShowForm' never used------是因为DELPHI认为函数中的Result:=False;这行代码是多余的,赋值给它没意义,不会造成任何影响。我试试一个EXE动态调用DLL函数,DLL函数再调用另外一个DLL中的form,看看会不会发送问题。
 
谢谢你了。这个问题我搞了两天了。昨天搞到晚上二点。还是没解决。
 
主程序代码:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}type TShowForm = procedure; Stdcall;var DllForm: THandle;procedure ShowForm;var ShowFormTest: TShowForm;begin if DllForm = 0 then DllForm := LoadLibrary('DLL1.DLL'); if DllForm <> 0 then begin ShowFormTest := GetProcAddress(DllForm, 'ShowFormTest'); if Assigned(ShowFormTest) then ShowFormTest; endend;procedure TForm1.Button1Click(Sender: TObject);begin ShowForm;end;initialization DllForm:=0;end.=====================================第一个DLL代码:library DLL1;uses ShareMem, SysUtils, windows, Classes, Forms;type TShowForm = function(AHandle: THandle; ACaption: Pchar): Boolean; Stdcall;var DllForm: THandle;procedure ShowFormTest;var ShowForm: TShowForm;begin if DllForm = 0 then DllForm := LoadLibrary('FreePower.DLL'); if DllForm <> 0 then begin @ShowForm := GetProcAddress(DllForm, 'ShowForm'); if Assigned(ShowForm) then ShowForm(Application.Handle, 'DLL&Ouml;&ETH;&micro;÷&Oacute;&Atilde;&micro;&Auml;&frac12;&ccedil;&Atilde;&aelig;'); endend;exports ShowFormTest;{$R *.res}begin DllForm:=0;end.=========================================第二个DLL代码:library FreePower;uses ShareMem, SysUtils, Classes, Forms, Unit_Main in 'Unit_main.pas' {Form_main};{ procedure SetApplication(mHandle: THandle); begin Application.Handle := mHandle; end; }function ShowForm(AHandle: THandle; ACaption: Pchar): Boolean; stdcall;var AForm: TForm_main;begin Result := False; Application.Handle := AHandle; AForm := TForm_main.Create(Application); Aform.Caption := ACaption; AForm.Show; Result := True;end;exports ShowForm;{$R *.res}beginend.===============================以上测试可以正常显示。
 
谢谢你了。我去试下。
 
接受答案了.
 
后退
顶部