DLL中封装窗体
在DLL中可以封装窗体,需要解决的关键问题在于DLL中的Application对象和调用的Application对象是有区别的。对于一般的应用程序来说,Application 对象是 VCL 固定的,一般不需要修改Application对象指针。但是在 DLL中,使用窗体或者使用 Application对象时,必须使 DLL的 Application和调用程序一样,这样才不至于混淆。如果不修改 Application 对象,那么应用程序退出的时候,可能会出现错误。例如使用如下代码在调用程序中导出一个函数: function DllFunction(App:TApplication;PForm:TForm):TForm2;stdcall; begin Result:=TForm2.Create(PForm); end; 当主程序退出时,就有可能发生错误。 解决该问题的步骤如下: • 按照创建 DLL 的步骤新建一个 DLL 项目。 • 在 DLL 项目中新建一个需要封装的窗体,并根据需要添加窗体代码。 • 增加一个过程,过程以应用程序的句柄作为参数,并将此句柄赋值给 DLL 的 Application 对象 的句柄,示例代码如下: procedure SynAPP(App:THandle );stdcall; begin Application.Handle := App; end; • 编译生成 DLL 文件。 • 应用程序中需要调用封装在 DLL 中的窗体时,首先调用 SynAPP 过程,然后进行其他操作。
下面举例说明这个步骤。在 DLL 中封装一个窗体,窗体中只有一个“随机颜色”按钮,单击该按 钮则改变窗体的背景色。 首先,新建一个 DLL 项目工程,新建一个窗体并在该窗体上添加一个名为“随机颜色”的按钮, 其 Click 事件处理代码如下: procedure TfrmDLL.Button1Click(Sender: TObject); begin Color := RandomRange(0,255 * 255 * 255 ); end; 然后,在窗体中增加方法 SynApp 和显示窗体的方法 ShowForm。代码如下: interface {省略了其他代码} procedure SynAPP(App:THandle);stdcall; procedure ShowForm;stdcall; implementation procedure SynAPP(App:THandle );stdcall; begin Application.Handle := App; end; procedure ShowForm;stdcall; begin try frmDLL := TfrmDLL.Create (Application); try frmDLL.ShowModal;
ally frmDLL.Free; end; except on E: Exception do MessageDlg (’Error in DLLForm: ’ + E.Message, mtError, [mbOK], 0); end; end; 在 DLL 项目文件中增加导出函数/过程的声明: exports SynAPP,ShowForm; 编译之后 DLL 就创建完成了。 在使用 DLL 时,首先必须调用 SynApp,并且将主程序的 Application 的句柄作为参数传递,否则 主程序退出时会引起操作系统错误。 主程序也非常简单,就是在一个窗口中加入一个按钮,直接显示封装在 DLL 中的窗体。 首先声明需要导入的过程: interface {省略了其他代码} procedure SynAPP(App:THandle);stdcall;external ’FormDLL.dll’; procedure ShowForm;stdcall;external ’FormDLL.dll’; 调用封装在 DLL 中的窗体的代码并添加在按钮的 Click 事件处理过程中: procedure TForm1.Button1Click(Sender: TObject); begin SynApp(Application.Handle ); {首先必须调用这个过程,并且使用 Application 的句柄作为参数} ShowForm ; end;