如果把DLL中的Form创建并显示到应用程序的Panel上?(200分)

  • 主题发起人 主题发起人 xingxingz
  • 开始时间 开始时间
X

xingxingz

Unregistered / Unconfirmed
GUEST, unregistred user!
如果把DLL中的Form创建并显示到应用程序的Panel上?<br><br>为了解决在一个MainProject.dpr中包含的Form太多,生成的Exe文件比较大,<br>想按模块把一直的Form分到各个DLL中,MainProject.dpr中只留主Form,<br>然后把DLL中的Form创建并显示到主Form的Panel上。<br><br>
 
设置Form的Parent<br>
 
设了,但还是弹出了一个窗口,没有创建到Panel上,并且关闭主程序时有异常。
 
给你个例子:<br>library DllMdiChildForm;<br><br>{ Important note about DLL memory management: ShareMem must be the<br>&nbsp; first unit in your library's USES clause AND your project's (select<br>&nbsp; Project-View Source) USES clause if your DLL exports any procedures or<br>&nbsp; functions that pass strings as parameters or function results. This<br>&nbsp; applies to all strings passed to and from your DLL--even those that<br>&nbsp; are nested in records and classes. ShareMem is the interface unit to<br>&nbsp; the BORLNDMM.DLL shared memory manager, which must be deployed along<br>&nbsp; with your DLL. To avoid using BORLNDMM.DLL, pass string information<br>&nbsp; using PChar or ShortString parameters. }<br><br>uses<br>&nbsp; Windows,<br>&nbsp; Messages,<br>&nbsp; SysUtils,<br>&nbsp; Classes,<br>&nbsp; Graphics,<br>&nbsp; Controls,<br>&nbsp; Forms,<br>&nbsp; Dialogs,MSFlexGridLib_TLB,<br>&nbsp; UnitDll in 'UnitDll.pas' {Form1};<br><br>procedure ProvaChild(ParentApplication: TApplication; ParentForm:TForm;MSGrid:TMSFlexGrid); export; stdcall;<br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; DllProc: Pointer; { Called whenever DLL entry point is called }<br><br>begin<br>&nbsp; &nbsp;Application:=ParentApplication;<br><br>&nbsp; &nbsp;Form1:=TForm1.Create(ParentForm);<br>&nbsp; &nbsp;Form1.MyParentForm:=ParentForm;<br>&nbsp; &nbsp;Form1.MyParentApplication:=ParentApplication;<br><br>// &nbsp; windows.SetParent(Form1.Handle,ParentForm.Handle);<br>// &nbsp; Form1.FormStyle:=fsMDIChild;<br>&nbsp; &nbsp;Form1.Button1.Caption :=inttostr(MsGrid.rows);<br>&nbsp; &nbsp;Form1.Show;<br>end;<br><br>procedure DLLUnloadProc(Reason: Integer); register;<br>begin<br>&nbsp; if Reason = DLL_PROCESS_DETACH then &nbsp;Application:=DllApplication;<br>end;<br><br>exports<br>&nbsp; &nbsp;ProvaChild;<br>begin<br>&nbsp; &nbsp;DllApplication:=Application;<br>&nbsp; &nbsp;DLLProc := @DLLUnloadProc;<br>end.<br>unit UnitDll;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; OleCtrls, MSFlexGridLib_TLB, StdCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; MSFlexGrid1: TMSFlexGrid;<br>&nbsp; &nbsp; procedure FormClose(Sender: TObject; var Action: TCloseAction);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; &nbsp; MyParentForm: TForm;<br>&nbsp; &nbsp; MyParentApplication: TApplication;<br>&nbsp; end;<br><br>var<br>&nbsp; DllApplication: TApplication;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br>begin<br>&nbsp; &nbsp;Action:=caFree;<br>end;<br><br>end.<br>unit MainFormUnit;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; Menus, StdCtrls, OleCtrls, MSFlexGridLib_TLB;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; MainMenu1: TMainMenu;<br>&nbsp; &nbsp; MDIChildForm1: TMenuItem;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Grd: TMSFlexGrid;<br>&nbsp; &nbsp; procedure MDIChildForm1Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>T_ProvaChild = procedure (ParentApplication: TApplication; ParentForm: TForm;MSGrid : TMSFlexGrid); stdcall;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>procedure TForm1.MDIChildForm1Click(Sender: TObject);<br>var<br>&nbsp; &nbsp;DllHandle: THandle;<br>&nbsp; &nbsp;ProcAddr: FarProc;<br>&nbsp; &nbsp;ProvaChild: T_ProvaChild;<br>begin<br>&nbsp; &nbsp;DllHandle := LoadLibrary('DllMdiChildForm');<br>&nbsp; &nbsp;ProcAddr := GetProcAddress(DllHandle, 'ProvaChild');<br>&nbsp; &nbsp;if ProcAddr &lt;&gt; nil then<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; ProvaChild := ProcAddr;<br>&nbsp; &nbsp; &nbsp; ProvaChild(Application,Self,Grd);<br>&nbsp; &nbsp;end;<br>end;<br><br>end.
 
re: abencat<br><br>&nbsp; 我也找到了这个例子,有源码,和上面基本一样,方法名都一样。<br><br>&nbsp; 有两个问题:<br>&nbsp; &nbsp; &nbsp;1、该例子在Delphi6下编译运行,关闭试有异常。<br>&nbsp; &nbsp; &nbsp;2、该例子是MDI多文档窗口,不能创建到主窗口的Panel上。<br>&nbsp; 谢谢您的关注,有其它办法吗?<br><br><br>
 
你可以贴出你的代码看看是什么问题。
 
DLL中返回TForm(DLLForm),<br>然后,<br>windows.SetParent(DLLForm.Handle,MainForm.Panel1.Handle);<br>DLLForm.Show;<br><br><br><br>
 
其实你说的这个问题我也碰到过,我开始采用DLL,然后不同的DLL输出方法不能统一,我就采用<br>DPK的格式,把各个功能模块分成多个包,编译后就生成BPL文件,和DLL差不多,不过我建议你<br>在数据库里建一个模块表,放模块的中文名称,类的名称,然后在运行是通过类名创建窗体实例,<br>不过注意一点,创建的窗体在窗体初始化时要注册.
 
to:eagle_d<br>&nbsp; &nbsp;有两个问题请教: <br>&nbsp; &nbsp;1、通过类名创建Form,怎么创建,是否类似于JAVA里面的ClassForName?具体请指教,谢谢。<br>&nbsp; &nbsp;2、可不可以把dpk里面的Form创建到主界面上的容器Panel上?<br>&nbsp; &nbsp;<br>&nbsp; &nbsp;非常感谢!对我启发很大,谢谢!<br><br><br>
 
那段代码行不通的。
 
我好象在HOTDOG里看到的 你可以查一查啊
 
在dll文件中设置参数 h:hwnd; &nbsp;application.Handle:=h;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;设置form.parent:=panel;<br>在调用时 &nbsp; &nbsp;dll_form(application.handle;panel);<br>
 
退出是报错,也许这里能找到答案<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=1772610
 
DPK里面的窗体可以在主程序里面调用的,不过你在DPK里面的窗体要添加以下语句:<br>initialization<br>&nbsp; registerclass(窗体类名);<br>finalization<br>&nbsp; unregisterclass(窗体类名);<br>最重要的一点是要创建一个统一的父类窗体,你的登陆用户参数放在这个父类里面,<br>如果使用ADO,则传CONNECTIONG连接,如果BDE,则传DATABASE,父类窗体做在一个DPK里面,<br>编译生成DCP文件,主程序里面的OPTION-PACKGE里面要添加这个DCP文件,其他的DPK里面<br>也要添加这个DCP文件.<br>子窗体从这个父窗体继承就可以了.<br><br>在主程序里面这样写,<br>{显示窗体函数 TUserInfo:自定义用户信息}<br>function Tfrm_Main.ShowDLLForm(AUserData:TUserInfo;<br>&nbsp; AFormClass:String; ACaption:String; AADOConnection:TADOConnection):Boolean;<br>var<br>&nbsp; FormClass : TFormClass;<br>&nbsp; FormInst : TParentForm; &nbsp; //父类窗体类名<br>&nbsp; InstHandle : THandle;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; {创建窗体实例}<br>&nbsp; &nbsp; FormClass := TFormClass(FindClass(AFormClass));<br>&nbsp; &nbsp; FormInst := FormClass.Create(Application,AUserData,AADOConnection);<br><br>&nbsp; &nbsp; InstHandle := FormInst.Handle;<br><br>&nbsp; &nbsp; FormInst.Caption := ACaption;<br>&nbsp; &nbsp; FormInst.Parent := InstNewTabSheet;<br>&nbsp; &nbsp; FormInst.Align := alClient;<br>&nbsp; &nbsp; FormInst.BorderStyle := bsNone;<br>&nbsp; &nbsp; FormInst.Show;<br><br>&nbsp; &nbsp; Result := True;<br>&nbsp; &nbsp; end;<br>&nbsp; except<br>&nbsp; &nbsp; Result := False;<br>&nbsp; end;<br>end;
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=872902<br>这里有你要的答案,只是再深一步我也没有解决得了:(
 
后退
顶部