13.4 创建ActiveX控件
13.4.1 ActiveX概述
ActiveX是Microsoft提出的一组使用COM技术来使软件部件在网络环境中进行交互的技术集,它与具体的编程语言无关。作为针对Internet应用开发的技术,ActiveX被广泛应用于WEB服务器以及客户端应用程序各个方面。
vC++通常提供MFC和ATL(ActiveX Template Library)两个途径来开发ActiveX控件。使用MFC开发ActiveX控件,可以不必理会控件接口的细节,而把注意力集中在控件本身的功能上,但是生成的控件将比较大。而且,客户端如果要运行此ActiveX控件,必须拥有相应版本MFC类库的DLL,否则则必须同时下载这些巨大的类库;使用ATL开发ActiveX控件时,由于不涉及MFC的标准类库,因而生成的控件相对较小,但开发者必须要了解COM和OLE技术的细节。在这里,将主要介绍使用MFC开发ActiveX控制的方法,因为这种方法相对会比较容易。
如果使用MFC开发ActiveX控件,则可以用MFC ActiveX Control Wizard生成工程框架,vc++会自动产生三个类:(假设MyName是控件的名字)
· CMyNameApp:从类COleControlModule派生,而类COleControlModule则派生自CwinApp。
· CMyNameCtrl:从类COleControl派生,而类COleControl则派生自CWnd。
· CMyNamePropPage:从类COlePropertyPage派生,而类COlePropPage则派生自CDial09。
可以看出,这个框架与一般的MFC应用程序有些类似。开发人员的大部分工作是在CMyNameCtrl中,通过为此类添加属性、方法来完成相应的功能。
在下面的一节中,就来介绍使用MFC向导创建一个简单的ActiveX控件的方法。
13.4.2 使用MFC向导创建一个简单的ActiveX控件
本节所要创建的ActiveX控件并没有什么实际的用处,它只是演示了使用MFC创建
ActiveX控件的方法过程,具体包括属性创建、方法创建以及事件创建等。在创建了ActiveX控件后,将使用VC++编写一个客户端程序,来演示如何在Windows CE下访问ActiveX控件。
1.使用MFC向导创建ActiveX
(1)使用VS2008句导创建一个“MFC智能设备ActiveX控件”工程,将项目名称设为MyCEActiveX,然后按照默认设置完成向导。将编译环境设置yinchengos。
(2)为CMyCEActiveXCtrl类添加属性和方法。在类视图中,选中DMyCEActiveX接口,通过右键快捷菜单“添加”,来为ActiveX控件添加属性和方法,如图13-20所示。
图13-20 为ActiveX控件添加属性和方法
MFC ClassWizard对话框单击“添加属性”菜单,添加一个MsgContext属性,其类型为BSTR,如图13-21所示。
图13-21 “添加属性向导”对话框
单击“添加方法”,添加一个ShowMessage方法,该方法没有返回值。
图13-22 “添加方法向导”对话框
(3)实现属性和方法。
1)在CMyCEActiveXCtrl类里添加~个私有变量m_MsgContext,代码如下:
private:
CString m_MsgContext;
2)修改属性实现代码,代码如程序清单。
BSTR CMyCEActiveXCtrl::GetMsgContext(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加调度处理程序代码
return m_MsgContext.AllocSysString();
}
//设置MsgContext属性
void CMyCEActiveXCtrl::SetMsgContext(LPCTSTR newVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加属性处理程序代码
if (m_MsgContext.Compare(newVal) != 0 )
{
m_MsgContext = newVal;
//出发OnChange事件
OnMsgChange();
SetModifiedFlag();
}
}
3)添加ShowMessage方法实现代码. 、
void CMyCEActiveXCtrl::ShowMessage(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
AfxMessageBox(m_MsgContext);
}
(4)编辑属性编辑框。
1)在资源编辑器中编辑属性对话框,设计界面如图13-23所示,将消息输入框标识为IDC EDT MSG。
图l3-23编辑属性对话框
2)为输入框控件添加关联变量m_Msg,类型为CString。这里还需要修改CmyCE ActiveX PropPage::DoData Exchange函数,实现消息输入框与控件的MsgContext属性关联。CmyCE ActiveX PropPage::DoData Exchange函数的实现如下:
//cMycEActivexPropPage::DoDataExchange一在页和属性问移动数据
void CMyCEActiveXPropPage::DoDataExchange(CdataExchange*pDX)
{ .
DDP_Text(pDX,IDC_EDT_MSG,m_Msg,L”MsgContext”);
DDX_Text(pDX,IDC_EDT_MSG,m_Msg);
DDP_PostProcesSing(pDX);
}
3)在CMyCEActiveXCtrl类的DoPropExchange方法里添加如下代码,用于关联属性,并初始化MsgContext属性值。PX—String(pPX,L”MsgContext”,m MsgContext,L”欢迎使用此Acitvex,呵呵”);至此,除事件以外,其他的功能都基本得到了实现。
(5)添加事件。
在该示例中,将添加一个MsgContext属性被改变时的通知事件。该事件的实现也很简单,具体实现如下:
1)在类视图中选择CMyCEActiveXCtrl类,通过右键快捷菜单“添加事件”来添加OnMsgChange事件。该事件在属性MsgContext值发生变化时被触发。如图13-24
2)修改SetMsgContext方法。在CMyCEActiveXCtrl类的SetMsgContext方法里,因MsgContext的值发生变化而触发OnMsgChange事件,其代码如下。
void CMyCEActiveXCtrl::SetMsgContext(LPCTSTR newVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加属性处理程序代码
if (m_MsgContext.Compare(newVal) != 0 )
{
m_MsgContext = newVal;
//出发OnChange事件
OnMsgChange();
SetModifiedFlag();
}
}
图13-24事件向导
最后编译部署该项目,系统将自动远程注册此0CX。同时到这里MyCEActiveX控件也编写完成了,下面就介绍如何来使用该ActiveX控件。
2.应用ActiveX控件
在该节中,将编写Windows CE中的ActiveX测试程序,编写步骤如下所示。
(1)使用vs2008智能设备IMFC智能设备应用程序向导创建一个基于对话框的应用程序MyCEActiveX ,编译环境设置为yinchengos.
注意:在向导对话框中,一定要选中“ActiveX控件”复选框,表示应用程序支持ActiveX组件。
(2)选择VS2008主菜单“项目添加类MFCActiveX控件中的MFC类,来添加MyCEActiveX控件的定义。
在“从以下来源添加类”项中选择“文件”单选框,然后指定OCX的位置,将接口_DMyCEActiveX和_DMyCEActiveXEvents添加到“生成的类”列表中,单击“完成”按钮,就添加了MyCEActiveX控件的定义。如图13-25
图13-25类向导
打_DMyCEActiveX接口定义文件CDMyCEActiveX.h,由于通过向导创建的MyCEActiveX控件缺少了访问MsgContext的属性方法,因此在CDMyCEActiveX.h中还需要添加GetMsgContext和SetMsgContext两个公有方法,以便访问属性。
CString GetMsgContext()
{
CString result;
GetProperty(0x1, VT_BSTR, (void*)&result);
return result;
}
void SetMsgContext(LPCTSTR propVal)
{
SetProperty(0x1, VT_BSTR, propVal);
}
(3)为CMyCEActiveX_TestDlg类添加私有成员m_myCEActiveX,存储MyCEActiveX控件对象。
private:
//定义MyCEActiveX控件对象
CDMyCEActiveX m_myCEActiveX;
在CMyCEActiveXTestDlg::0nInitDialog()中创建MyCEActiveX对象,代码如下:
//创建MyCEActiveX控件对象
CRect rc(0,0,100,100);
m_myCEActiveX.CreateControl(m_myCEActiveX.GetClsid(), L" ",
WS_VISIBLE,rc,this,5678,NULL,FALSE,NULL);
(4)在主对话框上添加一个按钮(IDC—BTN—TEST),在该按钮的单击事件中设置Activex
属性和调用ActiveX控件方法,代码如下:
//测试MyCEActiveX控件使用
void CMyCEActiveX_TestDlg::OnBnClickedBtnTest()
{
m_myCEActiveX.SetMsgContext(L"欢迎使用Eric制作的ACTIVEX控件");
m_myCEActiveX.ShowMessage();
}
(5)实现MyCEActiveX控件的OnMsgChange事件。
首先在MyCEActiveX_TestDlg.h文件中添加OnMsgChangeMyceactivexctrl事件函数以及OLE COM事件映射宏。定义如下:
//MycEActivex控件0nMsgChange事件
afx_msg void onMsgChangeMyceactiVexctrl();
//定义0LE COM事件映射
DECLARE_EVENTS INK_MAP()
接着在MyCEActiveXTestDlg.cpp文件中添加OLE事件宏,用于关联ActiveX事件函数,具体实现如下:
BEGIN_MESSAGE_MAP(CMyCEActiveX_TestDlg, CDialog)
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BTN_TEST, &CMyCEActiveX_TestDlg::OnBnClickedBtnTest)
END_MESSAGE_MAP()
BEGIN_EVENTSINK_MAP(CMyCEActiveX_TestDlg, CDialog)
ON_EVENT(CMyCEActiveX_TestDlg, 5678, 1 /* OnMsgChange */, OnMsgChangeMyceactivexctrl, VTS_NONE)
END_EVENTSINK_MAP()
最后再来实现0nMsgChangeMyceactivexctrl函数,代码如下:
//MyCEActiveX控件MsgContext属性被改变事件
void CMyCEActiveX_TestDlg::OnMsgChangeMyceactivexctrl()
{
AfxMessageBox(L"MsgContext属性已被改变");
}
至此,就实现了MyCEActiveX控件的OnMsgChange事件,这其中主要包括3部分内容,通过逐层学习,就会很快理解ActiveX事件函数的实现机制了。
经过以上5个步骤,客户应用程序就编写完成了。把它下载到模拟器上运行以查看其运行效果。当单击按钮时,系统将会先后弹出“欢迎使用Eric制作的ACTIVEX控件”和“MsgContext属性已被改变”提示框。
本示例只是粗略地介绍了使用MFC创建简单的ActiveX的方法,如果读者想要更深入地了解ActiveX,则可以参考其他一些ActiveX书籍,来创建更加复杂和实用的ActiveX控件。
13.5小结
COM是由Microsoft提出的组件标准,它不仅定义了组件程序之间交互的标准,而且还提供了组件程序运行所需要的环境。COM体现了组件化程序设计的思想,复杂的应用程序被设计成一些小的、功能单一的组件模型,这些组件模块可以在同一台计算机或者不同的计算机上运行。本章的范例基本实现了Windows Embedded Compact 7用到的COM开发框架与简单实例,希望读者认真编程实践。