一个没想通的问题,同事问的!(300大分)(300分)

  • 主题发起人 主题发起人 人在昆明
  • 开始时间 开始时间

人在昆明

Unregistered / Unconfirmed
GUEST, unregistred user!
我的exe(主程序)要调用我的dll 中的 窗体。而dll 中有好多窗体。<br>看看我的调用过程,dll中 fome的名字,caption 要求动态传入。<br>例如调用方法:<br>  RunDLLForm(dllname, formname, formcaption,Application, Screen);<br>则:<br>  RunDLLForm('test.dll', 'frmtest', 'caption test',Application, Screen);<br>那么就调用test.dll 中的 frmtest 窗体,并设置窗口<br>标题为 'caption test'。<br>那位高手指点一下<br><br>
 
一种方法就是用一个定死的DLL来调用这个动态传入的DLL<br>另一种就先判断一个这个dllname 再去调用这个DLL<br>好像和一般的调用一样嘛,比如点个菜单的某个功能,取个这个菜单的相关DLL名<br>去调用即可<br>
 
我也是这么想,但是写的时候却发现行不通,能不能搞段代码来看看!
 
应该传入窗体的类名,然后用GetClass()得到。以下代码未经测试,做个参考吧。<br>Var theClass:TPersistentClass;<br>theForm:TForm;<br>begin<br>&nbsp; &nbsp;theClass:= GetClass('TForm1');<br>&nbsp; &nbsp;if theClass = TForm then<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp;theForm:=TForm(aa).Create(Application);<br>&nbsp; &nbsp; &nbsp;...<br>&nbsp; &nbsp;end;<br>end;
 
to tata1:<br>&nbsp; &nbsp;你说得我也测试过,不过问题是 theForm:TForm;<br>恐怕就不对啦,因为这个类你在写调用方法的时候不能定死掉。
 
如果你的所有窗体都是继承TForm的话应该是可以的。另外代码应该改为:<br>Var theClass:TPersistentClass;<br>theForm:TForm;<br>begin<br>&nbsp; &nbsp;theClass:= GetClass('TForm1');<br>&nbsp; if theClass.InheritsFrom(TForm) then<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp;theForm:=TForm(aa).Create(Application);<br>&nbsp; &nbsp; &nbsp;...<br>&nbsp; &nbsp;end;<br>end;
 
真心感谢老哥!
 
给错分啦,tata1 老哥来这里领<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=1561583<br>
 
to:人在昆明<br><br>为什么我按你的例子进行测试时在主程序关闭后就会出现AV错误?<br><br>to LiChaoHui:<br>&nbsp; &nbsp;给我一个txyqbf_Gxx@163.com<br>其实没什么可以保留的,我就贴一个我写得吧(SDI):<br>exe 调用dll 中窗体的例子,sdi 和 mdi 基本上一样:<br>DLL 部分:<br><br>{****************************************************************}<br>{ }<br>{ Project: UDllTest   &nbsp; &nbsp; &nbsp; &nbsp;            }<br>{ Copyright(c) 2003, 2005                 }<br>{ Unit for UDllTest &nbsp; &nbsp;     &nbsp; &nbsp; &nbsp;              &nbsp;}<br>{ Create &nbsp;: 2003-01-05 by 林红卫             }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{****************************************************************}<br><br>library UDllTest;<br><br>uses<br>&nbsp; SysUtils,<br>&nbsp; Forms,<br>&nbsp; Messages,<br>&nbsp; Windows,<br>&nbsp; Classes,<br>&nbsp; UFrmTestForm1 in 'UFrmTestForm1.pas' {Form1},<br>&nbsp; UFrmTestForm2 in 'UFrmTestForm2.pas' {Form2};<br><br>var<br>&nbsp; DLLApp: TApplication;<br>&nbsp; DLLScreen: TScreen;<br>&nbsp; TheForm: TForm;<br>&nbsp; theClass: TPersistentClass;<br><br>procedure RunDLL(DLLName, FormName, FormCaption: string;<br>&nbsp; APP: TApplication; SC: TScreen) stdcall;<br><br>begin<br>&nbsp; Application := App;<br>&nbsp; Screen := sc;<br>&nbsp; RegisterClasses([TForm1, TForm2]);<br><br>&nbsp; theClass := GetClass('T' + FormName);<br><br>&nbsp; if theClass.InheritsFrom(TForm) and (theClass &lt;&gt; nil) then<br>&nbsp; begin<br>&nbsp; &nbsp; TheForm := TForm(theClass.Create).Create(Application);<br>&nbsp; &nbsp; TheForm.Caption := FormCaption;<br>&nbsp; &nbsp; TheForm.Show;<br>&nbsp; end;<br>end;<br><br>procedure DLLUnloadProc(Reason: Integer);<br>begin<br>&nbsp; if Reason = DLL_PROCESS_DETACH then<br>&nbsp; begin<br>&nbsp; &nbsp; Application := DLLApp; //恢复<br>&nbsp; &nbsp; Screen := DLLScreen;<br>&nbsp; &nbsp; FreeAndNil(TheForm);<br>&nbsp; &nbsp; FreeAndNil(theClass); // 卸载时释放资源<br>&nbsp; end;<br>end;<br><br>exports<br>&nbsp; RunDLL;<br><br>begin<br>&nbsp; DLLApp := Application; //保存 DLL 中初始的 Application 对象<br>&nbsp; DLLScreen := Screen;<br>&nbsp; DLLProc := @DLLUnloadProc; //保证 DLL 卸载时恢复原来的 Application<br>end.<br>这是dpr &nbsp;你加入form1,form2 就行啦!<br><br>exe 的dll 调用部分:<br><br>{****************************************************************}<br>{ }<br>{ Project: DllDebug &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;            }<br>{ Copyright(c) 2003, 2005                 }<br>{ Unit for UCommonUnit &nbsp;    &nbsp; &nbsp; &nbsp;              &nbsp;}<br>{ Create &nbsp;: 2003-01-05 by 林红卫             }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{****************************************************************}<br><br>unit UCommonUnit;<br><br>interface<br><br>uses<br>&nbsp; Windows,<br>&nbsp; SysUtils,<br>&nbsp; Forms;<br><br>type<br>&nbsp; TRunDLL = procedure(DLLName, FormName, FormCaption: string;<br>&nbsp; &nbsp; Application: TApplication; Screen: TScreen) stdcall;<br><br>procedure RunDLLForm(DLLName, FormName, FormCaption: string;<br>&nbsp; APP: TApplication; SC: TScreen) stdcall;<br><br>implementation<br><br>procedure RunDLLForm(DLLName, FormName, FormCaption: string;<br>&nbsp; APP: TApplication; SC: TScreen) stdcall;<br>var<br>&nbsp; GetDllHWND: HWND;<br>&nbsp; RunDLL: TRunDLL;<br>begin<br>&nbsp; GetDllHWND := LoadLibrary(PChar(DllName));<br>&nbsp; if GetDllHWND &lt; 32 then<br>&nbsp; begin<br>&nbsp; &nbsp; MessageBox(0, '没有找到附带DLL文件,请确认程序是否完整!',<br>&nbsp; &nbsp; &nbsp; '加载DLL失败', MB_OK);<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br><br>&nbsp; @RunDLL := GetProcAddress(GetDllHWND, 'RunDLL');<br>&nbsp; if @RunDLL &lt;&gt; nil then<br>&nbsp; begin<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; RunDLL(UpperCase(Trim(DLLName)), UpperCase(Trim(FormName)),<br>&nbsp; &nbsp; &nbsp; &nbsp; FormCaption, APP, SC);<br>&nbsp; &nbsp; except<br>&nbsp; &nbsp; &nbsp; raise Exception.Create('T' + FormName + '不存在');<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>end;<br>end.<br>dll 的Form Name 可以从Exe 传入。<br>
 
后退
顶部