ActiveX学习
新发现:
在msdn中刚刚找到了资料(主题) ActiveX Controls.一下子又明白了很多.原来ActiveX是利用了COM技术的.而ActiveX利用的技术还真的多:
COM, Connectable objects可连接对象 ,Uniform data transfer统一数据传输 ,Compound documents 复合文档,Property pages 属性页,OLE automation 就是对象链接与嵌入,Persistent storage持久存储 ,Font and picture objects两个系统对象.
这也可以大概看得见个究竟了.怪不得别人问我懂不懂ATL编程,原来一问就知道我水平在哪里了.
不过还是那个观点:复合文档àOLEàCOMàActiveXàMFC_ActiveX和ATL_ActiveX(查了msdn,就这两种开发ActiveX的方式(MFC和ATL),而不是ActiveX分为这两种!) 而COMàCOM+,后来又有了.NET(实在找不到权威的说法哈!)
ActiveX提供了三种与容器应用程序集成的机制:属性﹑事件和方法.就这句话暗含了什么??多着啊.明显的有复合文档,属性页,OLE,Font and picture object这些技术.
属性:控件的属性,在二次开发的时候与程序员交互的.VC环境下的那个属性页啊,每个控件的属性都不一样,就是从这来的.
方法:控件提供的函数.就是控件中的类提供的函数.
事件(Events,点中控件,右键然后有个Events菜单选项;选中了就可以添加消息处理函数了):控件发生的情况,如用户单击控件.
创建MFC ActiveX项目:
新建MFC ActiveX ControlWizard项目,输入名字MFCActiveX_05_12_16
在剩下的步骤中,最主要的是选择两大项:控件类和属性页类两个的类名,类型名和类型ID.在vc6.0和vc7.0中都是这样的.
生成的几个类的介绍:
CMFCActiveX_05_12_16PropPage派生于COlePropertyPage,而后者由CDialog派生的.在开发者的属性页中可以显示它的威力.当然可以和ActiveX控件交互,然后就能得到很好的开发效果了.想开发控件卖个好价钱?这里可是不能忽视的地方哦.
CMFCActiveX_05_12_16Ctrl派生于COleControl,而后者派生于CWnd派生的,是真正的和用户(开发者开发的程序的使用者)交互的地方.它从CWnd派生而来,注定了其可以处理很多的命令消息和非命令消息.而且注意哈,比如用户鼠标左键点击控件,可以在COleControl这个类种进行消息处理的哈,记住,是和最终用户交互的. 它是你发挥才华,实现你的ActiveX控件功能的主要地方之一.
CMFCActiveX_05_12_16App派生于COleControlModule,而后者派生于CWinApp派生的.而且有一个全部变量the_App,但不能在别的地方引用,MFC基础知识哈,可以看出控件本身就是一个包含完整应用程序框架的ocx文件,所以可以添加消息处理函数等.COleControlModule的派生类只有初始化(整个win32应用程序的框架都被封装了)和退出的作用.
对MFC开发的ActiveX控件编程,主要的工作是基于四个方面的:定制控件(不好定义),定义属性,方法,属性页和事件.基本都要用到ClassWizard类向导来完成的.
定制控件:
1:我们从资源文件中装载一个位图并把它显示出来.
在资源文件中insert或new一个位图文件,ID:IDB_BITMAP1;
指针和变量的操作是用区别的.指针一定要指向一个实际存在的内存地址;基本知识哈.
用变量
为CMFCActiveX_05_12_16Ctrl添加一个成员变量:CBitmap m_Bitmap;
在构造函数中加载入位图资源: m_Bitmap. LoadBitmap(IDB_BITMAP1);;
在CMFCActiveX_05_12_16Ctrl::OnDraw()中去掉画椭圆的函数.
然后在该函数最后添加代码:
BITMAP BM;//数据结构
//现在内存中装载入位图,为后来的BitBlt()转换位置提供资源.
CDC MemDC;//
MemDC.CreateCompatibleDC(NULL);//创建一个内存设备上下文.
MemDC.SelectObject(m_Bitmap);
m_Bitmap.GetObject(sizeof(BM),&BM);
//利用BitBlt()从内存设备向窗口设备转移位图
pdc->BitBlt((rcBounds.right-BM.bmWidth)/2,
(rcBounds.bottom-BM.bmHeight)/2,
BM.bmWidth,BM.bmHeight,
&MemDC,
0,0,SRCCOPY);
用指针:
为CMFCActiveX_05_12_16Ctrl添加一个成员变量:CBitmap m_Bitmap;
在构造函数中加载入位图资源: m_Bitmap. LoadBitmap(IDB_BITMAP1);;
在CMFCActiveX_05_12_16Ctrl::OnDraw()中去掉画椭圆的函数.
然后在该函数最后添加代码:
BITMAP BM;//数据结构
//现在内存中装载入位图,为后来的BitBlt()转换位置提供资源.
CDC MemDC;//
MemDC.CreateCompatibleDC(NULL);//创建一个内存设备上下文.
MemDC.SelectObject(m_Bitmap);
m_Bitmap.GetObject(sizeof(BM),&BM);
//利用BitBlt()从内存设备向窗口设备转移位图
pdc->BitBlt((rcBounds.right-BM.bmWidth)/2,
(rcBounds.bottom-BM.bmHeight)/2,
BM.bmWidth,BM.bmHeight,
&MemDC,
0,0,SRCCOPY);
2:添加消息处理:
在类向导中选中Message maps,类选CMFCActiveX_05_12_16Ctrl(当然可以选CMFCActiveX_05_12_16PropPage,但那样是为属性页添加消息处理.最终是和二次开发者交互的).Object IDs选CMFCActiveX_05_12_16Ctrl;最后选一个你想和最终用户交互的消息来处理就好了.
3:其它的处理:这里是最主要的了,不过没想到要做个什么功能的控件,所以就没例子.这是控件的核心;其他的是为了交互的,这里才是处理的核心!
定义属性:
要很好的交互,必须要添加自定义属性,如添加BackColor,Caption,Font等固有属性,和其他的自定义属性. 不管是自定义还是固有的属性,最终都会显示在VC的控件对应的属性页中,和二次开发人员进行友好的交互.
固有属性:
首先了解什么是固有属性:有MFC存放和初始化的共用属性(应该在CWnd类中吧),如BackColor,Font,Caption等
添加很简单,就是用类向导,然后选中CMFCActiveX_05_12_16Ctrl类,选中Automation选项卡,右边有一个Add Property按钮.点击后选一个External name,然后选下面的一个Stock单选按钮就好了.其他的含义自己理解哈.
自定义属性:同上.在External name中输入一个名字,选择类型,选中Menber variable;这样生成了名为:ShowFrame;数据类型为:BOOL的自定义属性.
但是要写代码实现的!
首先在CMFCActiveX_05_12_16Ctrl::DoPropExchange(CPropExchange* pPX)中添加PX_Bool(pPX,_T(“ShowFrame”),m_showFrame,FALSE);意思明确,将ShowFrame和变量m_showFrame初始化为FALSE.
再在OnShowFrameChanged()(这个函数是添加了ShowFrame自定义属性后向导自动添加的,用来对自定义属性进行消息处理)中添加函数:InvalidateControl();该函数强制调用重绘控件.
下面自然的是处理OnDraw()函数了.想怎么响应ShowFrame就怎么响应.
上面的逻辑是这样的:当容器应用程序改变了m_showFrame变量的值后,调用OnShowFrameChanged()函数,然后就可以调用OnDraw()函数进行重绘了.
比如:
CBrush Brush(TranslateColor(GetBakcColor()));
Pdc->FillRect(rcBounds,&Brush);
if(m_showFrame)
{
CBrush* pOldBrush=(CBrush*)pdc->SelectStockObject(NULL_BRUSH);
CPen Pen(PS_SOLID|PS_INSIDEFRAME,10,RGB(0,0,0));
CPen* pOldPen=(CPen*)pdc->SelectObject(&Pen);
pdc->Rectangle(rcBounds);
pdc->SelectObject(pOldBrush);
pdc->SelectObject(pOldPen);
}