OCX控件包装类的生成

本文详细介绍了在使用VS2008学习VC++时,如何正确添加并整合ActiveX控件,通过逐步操作和代码移植,最终实现控件的完整封装和调试。面对复杂的控件类生成问题,作者分享了解决方法,包括添加类、比较类结构、代码移植等步骤,最终成功解决了学习过程中的困扰。
本人也是位学习孙鑫的VC++深入详解的初学者,在学到ActiveX控件章节时,遇到非常多的麻烦。浏览过各种各样的帖子,终于在摸索中找到了答案。楼主可以听听我的解法。

   第一步:在“解决方案管理器”中,选中项目名称“CVTest”(我命名为CVTest,用来调试前面编写的Cliok控件),右键->添加->类。在打开的添加类对话框中,选中“Active控件中的MFC类”->添加。在打开的向导中,以注册表为来源,找到Clock control控件。用下面的“_DClock”接口生成相应的类“CDClock”。完成添加。
   这时可以看到在头文件中已经有了“CDClock.h”,里面写着“由 Microsoft Visual C++ 创建的 ActiveX 控件包装类的声明”,并且还派生于CWnd类,拥有Create函数。乍一看,以为添加成功,后来发现,里面只有两个函数:“AboutBox()”和“Hello()”。我的理解是:它只包含我们在Clock控件中添加的显性的方法,也就是指,可以由自己添加几行代码就可以完成的方法,不需要MFC内部机制完成。总之,这是个极不完整的控件类,需要继续添加原控件方法、属性、事件。

   第二步:仍然是同第一步的方法,打开添加类的对话框。这次选择添加“TypeLib中的MFC类”,找到Clock control控件。可以发现这次的接口有两个“_DClock”和“_DClockEvents”。把它们的类都添加上,由于第一步已经有一个“CDClock.h”了,所以它新生成的类为“CDClock0.h”,“CDClockEvents.h”。
   我们也打开这两个类,发现它们就包含了其他的方法和属性等。但是,一个控件怎么会生成这么多类呢?肯定有问题。通过比较,发现CDClockEvents和CDClock0类都派生于COleDispatchDriver这个类,并且都是调用父类的InvokeHelper()函数实现自己的方法。由此,我们可以淡定的把CDClockEvents类中的成员函数Click()和NewMinute(),都复制到CDClock0类中,然后直接删掉“CDClockEvents.h”。如此,就简化掉一个类。
   继续分析CDClock类和CDClock0类,发现CDClock类虽然派生于CWnd,但通过GetClsid()函数,得到了控件中的CLSID,也就是用这个函数也能关联到COleDispatchDriver这个类上去(个人形象的理解,真正的机理我也不懂)。并且通过MSDN查InvokeHelper()函数,发现CWnd和COleDispatchDriver类都有这个函数,都用它实现了AboutBox()和Hello()。那么我们就可以断定CDClock类和CDClock0类的成员函数(方法)多半是可以相互移植的。

   第三步:把CDClock0类中的函数复制到CDClock类中去,再删掉“CDClock0.h”。

   最后:调试运行,无误;把孙鑫那剩下的代码写完,再运行,成功!

   感叹一下,用VS2008去学VC6.0的人,真是伤不起啊!!!
不用工具箱的话,自己手工添加,需要注意一个问题,就是要用Aximp.exe来包装一下ocx控件,然后再程序中引用生成的dll就可以了。 aximp [options]{file.dll | file.ocx} The following command generates MediaPlayer.dll and AxMediaPlayer.dll for the Media Player control msdxm.ocx. aximp c:\systemroot\system32\msdxm.ocx 将 ActiveX 控件的 COM 型库中的型定义转换为 Windows 窗体控件。 Windows 窗体只能承载 Windows 窗体控件,即从 Control 派生的。Aximp.exe 生成可承载于 Windows 窗体上的 ActiveX 控件包装。这使您得以使用可应用于其他 Windows 窗体控件的同一设计时支持和编程方法论。若要承载 ActiveX 控件,必须生成从 AxHost 派生的包装控件。此包装控件包含基础 ActiveX 控件的一个实例。它知道如何与 ActiveX 控件通信,但它显示为 Windows 窗体控件。这个生成控件承载 ActiveX 控件并将其属性、方法和事件公开为生成控件的属性、方法和事件。 如果不包装一下直接用,会出现 灾难性 错误。上面已经说明了原因。 在项目中引用生成的ax开头的dll,在窗体代码中增加: 声明一个公有的控件对象: public AxISPICRECLib.AxISPICREC AxISPICREC; 在InitializeComponent()方法内初始化控件: AxISPICREC = new AxISPICRECLib.AxISPICREC();//必须new对象,否则窗体设计器出问题 ((System.ComponentModel.ISupportInitialize)(this.AxISPICREC)).BeginInit();//初始化开始 this.Controls.Add(this.AxISPICREC);//添加控件 ((System.ComponentModel.ISupportInitialize)(this.AxISPICREC)).EndInit(); this.AxISPICREC.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("AxISPICREC.OcxState")));//设计控件状态 如果遇到“正试图在 os 加载程序锁内执行托管代码”这个错误,请设置“调试”--“异常” "----"Managed Debugging Assistants"中勾掉"LoaderLock" 就可以了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值