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;//即使不调用此方法,下面的 Appliaciton 在运行是调试依然是当然 exe 的全名 
end;

•  编译生成DLL文件。
•  应用程序中需要调用封装在DLL中的窗体时,首先调用SynAPP过程,然后进行其他操作。
  
     下面举例说明这个步骤。在DLL中封装一个窗体,窗体中只有一个“随机颜色”按钮,单击该按钮则改变窗体的背景色。 首先,新建一个DLL项目工程,新建一个窗体并在该窗体上添加一个名为“随机颜色”的按钮, 其 Click 事件处理代码如下: 

procedure TDllTestForm.btn1Click(Sender: TObject);
begin
  Color := Random(111*111*111);//Random(0,255*255*255);
end;

      然后,在窗体中增加方法SynApp和显示窗体的方法ShowDllForm。代码如下: interface {省略了其他代码}   

interface

procedure SynAPP(App: THandle); stdcall;
procedure ShowDllForm; stdcall;

implementation

procedure SynAPP(App: THandle); stdcall;
begin
  Application.Handle := App;
end;

procedure ShowDllForm; stdcall;
var
  ADllTestForm: TDllTestForm;
begin
  try
    ADllTestForm := TDllTestForm.Create(Application);
    try
      ADllTestForm.ShowModal;
    finally
      ADllTestForm.Free;
    end;
  except
    on E: Exception do
      MessageDlg('Error in DllForm: ' + E.Message, mtError, [mbOK], 0);
  end;
end;
     
 在DLL项目文件中增加导出函数/过程的声明:
exports
  SynAPP,
  //CreateDllSkin,  //创建皮肤控件窗体
  //DestroyDllSkin, //销毁皮肤控件窗体
  ShowDllForm,
      编译之后DLL就创建完成了。 在使用DLL时,首先必须调用SynApp,并且将主程序的Application的句柄作为参数传递,否则主程序退出时会引起操作系统错误。 主程序也非常简单,就是在一个窗口中加入一个按钮,直接显示封装在DLL中的窗体。 首先声明需要导入的过程: 
interface {省略了其他代码}
procedure SynAPP(App: THandle); stdcall; external 'PDll.dll';
procedure ShowDllForm; stdcall; external 'PDll.dll';
调用封装在DLL中的窗体的代码并添加在按钮的Click事件处理过程中:
procedure TForm2.btn1Click(Sender: TObject);
begin
  //首先必须调用这个过程,并且使用 Application 的句柄作为参数,亲测不掉用也没发现问题,可能没测到
  SynApp(Application.Handle);
  ShowDllForm;
end;

 

转载于:https://my.oschina.net/u/558388/blog/171179

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值