2024年1月31日发(作者:)
2.1 ActiveX控件介绍
ActiveX是在M$与JAVA抗争时产生的一个新名词(1996年3月),ActiveX技术的前身是OLE技术是M$为了适应Internet的发展对OLE进行的扩展(当时的含义是“Activeate the Internet”),当时只是为了发展一种小型的可从网络上快速下载的可重用组件。但是随着ActiveX技术的发展ActiveX很快成为了M$新的口号。ActiveX由定义WEB页面到OLE控件的所有内容发展到定义一种可重用组件技术的规范。现在ActiveX已经成为一种概念和潮流。
ActiveX的基础是OLE和COM,但是通过M$的各种开发工具可以屏蔽掉COM模型中许多另人费解的技术细节。本节主要讨论如何开发ActiveX控件,其实这只是AcitveX组件技术中的一部分。ActiveX组件技术包括以下一些方面:
自动化服务器
自动化控制器
控件
COM对象
文档
容器
现在的ActiveX控件等价与以前的OLE控件或OCX,一个典型的控件包括设计时和运行时的用户界面,唯一的IDispatch接口定义了控件的属性和方法,唯一的IConnectionPoint接口定义控件可引发的事件。一个控件可以在容器中运行,所以从运行的角度看它类似与一个DLL。由于在IE中添加了对控件的支持,所以你可以在WEB页面中通过VBScript对控件进行操纵。
此外COM组件间在二进制上兼容,当其中一个组件的代码被修改并且被重新编译连接后只要能够保持原来已经存在并被使用的接口不变化(可以添加其他接口)那么其他使用这个组件的文件都不需要重编译。所以利用COM组件技术可以很大程度上的提高软件重用性。同样如果在程序中使用了ActiveX控件那么你在以后升级程序时可以单独升级控件而不需要升级整个程序。在提供灵活性的同时会带来性能上的牺牲,但和ActiveX为我们代码的好处上看来这些牺牲都算不了什么。
利用MFC的Application Wizard我们可以方便的创建一个工程,首先在工程类型中选择MFC ActiveX Control,然后选择在工程中创建多少个控件。在接下来的对话框中并且为每个控件输入相关信息,通过Edit Name按钮可以为控件指定名称,通过Advanced按钮可以为控件指定各种附加特性,此外你还可以将控件指定为一个继承了某种现有窗口类的子类。在本节的例子中我们创建三个控件,分别是:
普通窗口控件 CSam_windowCtrl
无窗口控件 CSam_nowindowCtrl
EDIT窗口控件 CSam_editwindowCtrl
在工程创建完毕后你就可以编译并测试控件了,但是这时候的控件还不能做任何事情。我们需要为控件添加方法和属性。简单的讲,方法就相当与类中的函数调用,而属性就相当与类中的成员变量。
假设在普通窗口控件中我们将显示一份学生资料,包括姓名,出生年月,班级名称,为了能够设置这些数据,我们为控件添加一个方法。选择Class Wizard,并选中对话框中的Automation页,按下Add Method按钮以添加消息,然后在弹出的对话框中输入相关信息。我们为新添加的方法取名为SetMertial,同时指定三个参数LPCTSTR pszName,LPCTSTR pszBirth,LPCTSTR pszClass,返回值设置为void,在保存后Class Wizard会生成一个函数,该函数的名称就是你所指定的方法名称。此外我们还添加一个属性用于让用户设置显示文字的颜色。在添加属性对话框中为属性取名为TextColor,并且接收的参数为OLE_COLOR,并且将实现方法设定为Get/Set Methods。在保存后Class Wizard会为你生成GetXXX/SetXXX两个函数XXX就代表你所指定的属性名,当控件容器更改属性时就通过这两个函数。
然后我们为CSam_windowCtrl添加三个成员变量保存这些学生资料和一个用于保存颜色,当然别忘了在构造函数中对它们初始化。然后修改和添加与方法和属性有关的函数,我们可以看到在数据被修改后都会调用Invalidate()使窗口重绘。
// 添加成员变量
class CSam_windowCtrl : public COleControl
{
DECLARE_DYNCREATE(CSam_windowCtrl)
// Constructor
public:
CSam_windowCtrl();
CString m_szName,m_szBirth,m_szClass;
...
}
//初始化
CSam_windowCtrl::CSam_windowCtrl()
{
InitializeIIDs(&IID_DSam_window, &IID_DSam_windowEvents);
m_szName="name";
m_szBirth="birth";
m_szClass="class";
...
}
void CSam_windowCtrl::SetMertial(LPCTSTR pszName, LPCTSTR pszBirth,
LPCTSTR pszClass)
{
//保存数据
m_szName=pszName;
m_szBirth=pszBirth;
m_szClass=pszClass;
Invalidate();
}
OLE_COLOR CSam_windowCtrl::GetTextColor()
{
//得到属性
return m_ocText;
}
void CSam_windowCtrl::SetTextColor(OLE_COLOR nNewValue)
{
//设置属性
m_ocText=nNewValue;
Invalidate();
SetModifiedFlag();
}
最后我们再为控件添加一个事件,在Class Wizard中选择ActiveX Events页面,并添加一个事件。Timer事件,当你需要触发该事件时你可以通过调用FireTimer()来进行。我们在控件中设置一个定时间器每两秒钟触发一次事件
具体代码如下:
//在头文件中由Class Wizard生成的事件触发代码
// Event maps
//{{AFX_EVENT(CSam_windowCtrl)
void FireTimer()
{FireEvent(eventidTimer,EVENT_PARAM(VTS_NONE));}
//}}AFX_EVENT
DECLARE_EVENT_MAP()
//创建定时器与触发事件
int CSam_windowCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
SetTimer(1,2000,NULL);
return 0;
}
void CSam_windowCtrl::OnTimer(UINT nIDEvent)
{
FireTimer();
COleControl::OnTimer(nIDEvent);
}
现在你可以通过VC开发包中的ActiveX Control Test Container对你的控件进行测试了。在插入了控件后可以通过容器来调用控件的方法和设置属性,此外如果打开事件日志窗口(Event Log)就可以看见所有产生的事件列表。
对于无窗口对话框,我们为它创建一个方法DoCalc,该方法接收两个参数,并返回一个long型数,其作用就是将两个值相加并在消息框中显示。对于无窗口特性的控件加载时间要明显快于有窗口的控件,但是必须要容妻支持这一特性时才会有效,否则控件窗口还是会被产生。
对于EDIT窗口子类的控件,你可以直接进行测试,你会发现它与普通的EDIT框没有区别。
此外ActiveX还可以具备其他一些特性,比如说无闪烁特性,当拥有这一特性时窗口在活动与非活动状态间转换时不会收到UI消息。而对于非活动状态鼠标通知特性允许控件在非活动状态时能够接收到鼠标消息。
2.3 利用ATL(ActiveX模板库)创建ActiveX控件
ATL可以作为一个完整的控件开发框架,它的主要目标是提供方便的开发手段和生成更小的目标文件。由于ATL可以脱离开MFC所以它的执行速度和加载速度都比MFC开发的控件快。当然你也可以在ATL中使用MFC,但这样就失去了ATL的优势,因为利用MFC开发控件在目前来讲还是要比ATL方便和快捷。由于在ATL中不使用MFC所以所有的的功能调用都是通过WIN32 API函数和C运行库函数来完成。但利用ATL我们可以很方便的开发出COM对象,而这点是MFC较弱的地方,但这个问题已经超出了本章的内容。
在本节中我通过一个例子来看看如何利用ATL创建一个工程并添加相应的功能,首先利用Class Wizard创建一个ATL工程,在创建时几乎没有什么选项。所有的ATL接口都要在创建后才添加。在菜单Insert中选择New ,这时你需要选择Control类中的Full Control项,然后输入对象的名称,并且为了添加容错和事件支持你需要在Attributes选项中选中Support
ISupportErrorInfo和Support Connection Points。
接下来我们为ATL接口添加方法,然后在对话框中输入方法名称和参数,你可以看到参数定义前可以利用中括号对参数的属性进行定义,可用的指令有:
in 调用方传入的参数
out 给调用方返回的值
in,out 既作为输入参数有作为返回值
接下来我们添加两个方法:SetCaption([in]BSTR pszCaption)和GetCaptionLength([out]long* lLen)其作用是设置标题和得到标题的字符串长度。相关代码如下:
STDMETHODIMP CATLSam::SetCaption(BSTR pszCaption)
{
USES_CONVERSION; //由于COM传送字符时使用UNICODE所以在此要进行转换,unicode->ansi
LPTSTR pTemp=W2A(pszCaption);
delete m_pszCaption; //删除原来的数据
m_pszCaption = new char[strlen(pTemp)+1];
strcpy(m_pszCaption,pTemp);
return S_OK;
}
STDMETHODIMP CATLSam::GetCaptionLength(long *lLen)
{
*lLen=strlen(m_pszCaption);
return S_OK;
}
接下来为了在界面上显示出所做的改动,让我们重写OnDraw函数,相关代码如下:
HRESULT CATLSam::OnDraw(ATL_DRAWINFO& di)
{
RECT& rc = *(RECT*)nds;
Rectangle(w, , , , );
DrawText(w, _T(m_pszCaption), -1, &rc, DT_CENTER |
DT_VCENTER | DT_SINGLELINE);
}
return S_OK;
在本节中我以上节中的ATL控件做为对象讲解一下如何调试和使用ActiveX控件。
由于控件并不能单独运行,所以你必须利用另一个程序来装载控件并进行调试,VC中提供了ActiveX容器供使用,在工程/设置菜单(project/setting)中选择Debug页并选择ActiveX Container。
然后开始调试,进入Container时VC会提示Container中是没有调试代码的错误,不用理会并继续。
进入Container后首先要装载你所需要调试的控件,选择菜单Edit/Insert OLE
,在弹出的对话框中选择你需要插入的控件。
如果Container成功创建了控件在屏幕中就会显示出控件,根据上节的内容我们可以看到控件中显示了一串字符,接下来我们需要测试一下控件所提供的方法是否能够正确运行。请选择菜单Edit/,在弹出的对话框上选择你要使用的方法,但你选择了方法后,对话框上的参数输入区会显示输入参数的列表,你输入参数后按下Invoke按钮就可以执行。
在调试时你可以如同调试其他程序一样在代码中使用TRACE宏,也可以设置断点。
其实你在插入控件时会看见其他在系统中已经注册的控件,如果有兴趣可以自己试试加载几个看看效果。
如果要在VC的工程中使用已经存在的ActiveX控件,最简单的方法就是利用VC的插入功能,在菜单中选择Project/Add To Project/Component and Control(在不同版本的VC中可能菜单位置不同),然后选择插入的控件,VC会为你生成这个控件的定义文件,当然和你最开始编写的会完全不一样,但是没有关系。你会在定义文件看见这个控件所实现的方法和属性,这些都可以让你通过函数的方式进行调用。(所以在使用控件时如果没有该控件的说明是很难使用的)
还有一种方法就是在对话框中插入一个控件。如果该控件的定义文件没有生成VC也可以帮助你生成。
在对话框中的控件是不需要手工创建的,但是如果你希望在其他地方创建窗口就需要调用控件的创建函数,其实这个函数很简单,和CWnd::Create函数定义的区别不大。定义为:
class CATLSam : public CWnd
{
BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT& rect, CWnd* pParentWnd, UINT nID,
CFile* pPersist = NULL, BOOL bStorage = FALSE,
BSTR bstrLicKey = NULL)。
可以使用如下方式调用:
Create("window
text",WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(0,0,200,200),this,1001);由于是CWnd的派生类所以CWnd的相关功能都可以使用。在程序中创建了控件窗口后就可以调用控件的各种方法(对属性的控制也是通过函数调用来实现的,在前面的教程中我们已经认识到这点)。
在控件创建后就可以使用控件的各种属性和方法,由于控件是你自己编写的所以调用起来应该不会有什么问题。
本文发布于:2024-01-31 02:15:20,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170663852024616.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |