ocx入门浅析

1.exe,ocx,dll的区别

分析:exe是一个可执行程序,而ocx看做是一个窗口上的控件(控件即ocx,如button),dll是将函数、变量、类封装在一起的库

ocx的形式如下:


图中的各个都是ocx控件(我是这样认为的),只不过MFC内置了一些控件,但是如果是自己写的ocx控件,程序运行时必须将生成的ocx控件拷到可执行目录下


2.ocx特点(根据普通的button可知)

(1)ocx是可视化窗口,一个ocx有一个ID,可以通过ID来建立一个对应的类,调用其中函数(如果看不到,那么肯定隐藏了)

(2)可以响应单击、双击等鼠标事件

(3)含有对应的属性


3.创建一个ocx程序(如何让ocx含有上面这些属性呢)

(1)利用VS2010创建一个MFC ActiveX Control工程,名为myocx


其中myocx.h中InitInstance是入口,.cpp中含有ocx注册、反注册的函数

myocxCtrl.h中CmyocxCtrl是ocx的可视化窗口类,父类是COleControl,因为是窗口,所以可以响应OnCreate,Onsize等消息,含有消息映射,调度映射,事件映射

myocxPropPage.h是ocx的属性,就像按钮button类含有属性一样

myocx.idl是对外接口,据说CmyocxCtrl类是继承它的,所有对外接口都在myocx.idl这里声明,在CmyocxCtrl类中实现

myocx.def,ocx是一种特殊的dll,所以同样有def文件,内容如下

; myocx.def : Declares the module parameters.

EXPORTS
	DllCanUnloadNow     PRIVATE
	DllGetClassObject   PRIVATE
	DllRegisterServer   PRIVATE
	DllUnregisterServer PRIVATE
其中的PRIVATE的意思是对ocx私有,即这些函数名不会加到生成的库文件中(编译ocx发现除了生成ocx,还有一个lib文件)

(2)消息映射,调度映射,事件映射

>1含义

     消息映射:即响应操作系统的消息

     调度映射:可以在外部调用的接口函数,通俗的将就是一个控件可以调用它内部的函数,如CButton btn;btn.函数名();

     事件映射:单击、双击等事件由ocx传给它的容器进行响应,如按钮的一些事件,触发后可以在它的父窗口中进行响应处理

>2添加调度映射

在myocx的idl中对应的调度映射下添加:

[id(1)] void Hello();


在myocx.h中添加:

afx_msg void Hello();
//添加调度枚举类型
enum {
        //调度ID,从1开始
	dispidHello = 1L,
		
        //事件ID,从1开始
	};


在myocx.cpp中添加:
void CmyocxCtrl::Hello()
{
	AfxMessageBox(_T("Hello world"));
}

编译并生成ocx,默认编译生成的ocx也注册好了


创建一个基于对话框的MFC工程,名为useocx,在对话框窗口右击插入ActiveX 控件,快速输入生成的ocx的前几个字母找到ocx,添加进去

右键ocx,选择添加变量,变量名设为m_myocx,设置好后,便会生成对应的ocx类

可以看到ocx类中已经自动含有:

void Hello()
{
	InvokeHelper(0x1, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}


这个时候就可以利用m_myocx调用里面的Hello函数了

附:也可以在下面这个位置右键选择添加添加函数实现


>3添加事件映射

在下图上右键


选择添加事件,选择Click,确认,效果是在idl文件事件下面多出下面一行:

[id(DISPID_CLICK)] void Click(void);


在myocx.cpp中中间多出:
BEGIN_EVENT_MAP(CmyocxCtrl, COleControl)
	EVENT_STOCK_CLICK()
END_EVENT_MAP()


效果是在useocx工程的资源对话框文件中,右键添加的Ocx控件,查看属性,发现事件中

多出了Click属性,此时可以添加函数,运行useocx工程时鼠标点击控件就会触发这个函数

如果添加自定义的事件映射,则在myocxi.idl中事件映射下添加:

[id(1)] void MyDrag(void);

在myocxCtrl.h中添加

enum {
	//调度映射ID
        dispidHelloClick = 1L,

	//事件映射ID
	eventidMyDrag = 1L,
     };

protected:
void MyDrag(void)
{
      FireEvent(eventidMyDrag, EVENT_PARAM(VTS_NONE));
}


同样查看useocx工程资源对话框文件控件属性:

多出MyDrag属性,此时可以再外面写响应函数,具体触发则需要根据需要在ocx内部调用就可以触发

这里注意ocx事件触发都是在ocx内部触发,外部进行响应处理的,如button类,点击或双击都是在按钮本身触发,最后由它的父窗口进行响应处理,自定义的事件也是要在内部进行触发


注意:InvokeHelper和FireEvent这两个函数中的表示传入形参的参数含有多个时,通过空格进行隔开(一个函数形参可以有很多个,但返回值只有一个)


总结:

1.ocx有三种映射,但idl中对外提供的只有调度映射和事件映射

2.(1)ocx的类与ocx是通过idl文件中最后的类的ID建立联系的

idl中:

//  Class information for CmyocxCtrl
	[
		uuid(EF2CFD6B-E121-47E3-BD63-5F5DD51DCCFF)
	]


在ocx类(class CMyocxctrl_use : public CWnd)中

CLSID const& GetClsid()
	{
		static CLSID const clsid
			= { 0xEF2CFD6B, 0xE121, 0x47E3, { 0xBD, 0x63, 0x5F, 0x5D, 0xD5, 0x1D, 0xCC, 0xFF } };
		return clsid;
	}


(2)调度映射是通过Idl中调度函数前的ID建立联系的

在idl中:

[id(1)] void Hello();

在在ocx类(class CMyocxctrl_use : public CWnd)中
void Hello()
{
	InvokeHelper(0x1, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}



(3)事件映射是在内部进行触发,也就是含有fireEvent的那个函数是在ocx内部调用作为触发方式,响应在外面实现

3.ocx作为控件在MFC中使用时,此时该控件与它的容器是父窗口与子窗口关系,普通控件与父窗口之间的函数调用方式它也同样适用


4ocx属性

与myocxPropPage.h中CmyocxPropPage类有关,对应的效果:



5.ocx调试

(1)在exe中进行调试

按照上面方法在useocx工程中添加好ocx后,在myocx工程中设置以下属性:


就可以调试了

(2)在IE中调试

首先编写一个html文件,后缀名为htm,添加如下内容:

HTML>  
<HEAD>  
<TITLE>Test ActiveX</TITLE>  
</HEAD>  
<OBJECT ID="TestMfcAtl Control" WIDTH=528 HEIGHT=545 classid="CLSID:EF2CFD6B-E121-47E3-BD63-5F5DD51DCCFF">  
    <PARAM NAME="_Version" VALUE="65536">  
    <PARAM NAME="_ExtentX" VALUE="12806">  
    <PARAM NAME="_ExtentY" VALUE="1747">  
    <PARAM NAME="_StockProps" VALUE="0">  
</OBJECT>  
</HTML> 


注意其中ID就是idl中类的ID,在myocx中设置如下属性:



第一个是IE的路径,第二个是IE地址栏中的数据,根据需要可填可不填,有的是IP地址,有的是htm,这样就可以了


说明:有的IE不是单进程的,可以通过附加到进程进行调试,也可以将IE设置成单进程的

我这里通过IE调试的时候打断点,调试运行鼠标不可用,也不知道什么原因,暂未解决


6.ocx程序发布

OCX不能单独运行,发布时必须拷到对应的可执行的程序中,一起发布

  • 12
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值