18ActiveX控件
2015-01-20 18:17
211 查看
转自 http://blog.sina.com.cn/s/articlelist_1815328704_0_1.html
第18课 ActiveX编程(下面X均为ActiveX简称)
1.在VB中调用X控件,添加方法 project->Add components。另外可以用Object Browser来查看控件
2.在VC中创建X控件
1.新建一个X工程名为Clock,注意一个文件中可以包含多个控件。
2.保持缺省设置,完成。注意它生成的三个类,以及相关的接口。
3.运行它。选择TSTCON32.exe作为容器。
4.选择Insert Control,此时我们可以看到,它画了一个椭圆。也可以在VB中测试。
5.删除注册信息。用regsvr32 /u +文件名。也可以在菜单选择反注册命令。
6.重写代码。在CClockCtrl::OnDraw()中画了一个椭圆,此时我们在其中得到系统时间,并显示它。为此我们在OnCreate()设置了一个定时器,每隔一定时间发出一个Invalidate()消息,使窗口重绘。
7.如何改变控件的背景色和前景色?ClassWizard->AutoMation->Add Property->BackColor,还需要在OnDraw()中加上相应的代码
CBrush brush(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds, &brush);
pdc->SetBkMode(TRANSPARENT);
pdc->SetTextColor(TranslateColor(GetForeColor()));
8.增加属性页。在
BEGIN_PROPPAGEIDS(CClockCtrl, 2)此时数目也得改成相应的数目
PROPPAGEID(CClockPropPage::guid)
PROPPAGEID(CLSID_CColorPropPage)
END_PROPPAGEIDS(CClockCtrl) OK~
9.增加自定义属性:ClassWizard->AutoMation->Add Property加上一个变量m_interval,类型为short,对应外部变量为Interval。在CClockCtrl中增加 OnIntervalChanged方法。添加如下代码:
if(m_interval<0 || m_interval>6000)
{
m_interval=1000;
}
else
{
m_interval=m_interval/1000*1000;
KillTimer(1);
SetTimer(1,m_interval,NULL);
BoundPropertyChanged(0x1);
}
10.测试:Control->Invoke Methods
11.将时间间隔加到属性页中,在资源视图中加入一文本框和编辑框。为EditBox关联成员变量,加入属性interval。
12.增加方法:ClassWizard->AutoMation->Add Method->Hello加入代码 OK!在VB中可以调用此方法!
void CClockCtrl::Hello()
{
// TOD Add your dispatch handler code here
MessageBox("Hello world!");
}
13.增加事件:ClassWizard->AutoMation->Add Events->Click
14.增加自定义事件:ClassWizard->AutoMation->Add Events->NewMinute
在新的一分钟到达时发出这个通知,在OnDraw()中写代码:
CTime time=CTime::GetCurrentTime();
if(0==time.GetSecond())
{
FireNewMinute();
}
15.让Interval属性具有持久性。在CClockCtrl::DoPropExchange()中调用PX_short()方法,OK!
PX_Short(pPX,"Interval",m_interval,1000);
16.让Property Page和Property属性中的interval保持一致的方法:在OnIntervalChanged()中调用BoundPropertyChanged(0x1);
17.希望控件在设计时间内不走动的方法:在OnTimer()中, if(AmbientUserMode())InvalidateControl();巧妙!
3.在VC中调用X控件
1.新建ClockTest对话框应用程序
2.点击右键->插入X控件->时钟控件
3.Project->Add Component会生成CClock类。
4.在CCLockTestDlg中增加CClock类的成员变量m_clock,然后可以动态创建一个这样的东东!
5.试验Click(),NewMinute(),SetBkColor(),SetForeColor()方法和属性
6.如何为动态创建的控件做事件响应呢?首先你得知道它的ID号,然后参考非动态的控件事件代码,呵。
容器和服务器程序
容器应用程序时可以嵌入或链接对象的应用程序。Word就是容器应用程序。
服务器应用程序是创建对象并且当对象被双击时,可以被启动的应用程序。Excel就是服务器应用程序。
ActiveX控件不能独立运行,它必须被嵌入容器应用程序中,和容器应用程序一起运行。
Dispatch maps调度映射,主要是MFC提供让外部应用程序可以访问控件的属性和方法
Event maps事件映射,控件向包含它的容器发送事件通知
接口是外部程序和控件进行通信的协议,可以把接口看作是函数的集合,外部程序通过借口提供的方法,去访问控件的属性和方法。接口中所定义的所有函数都是纯虚函数
regsvr32 ...注册控件 regsvr32 /u....卸载控件
STDAPI DllRegisterServer(void)将控件信息写入注册表中
STDAPI DllUnregisterServer(void)卸载注册信息。
***一个时间控件,在
void CClockCtrl::OnDraw(CDC* pdc, const CRect& rcBounds,
const CRect& rcInvalid)中添加以下代码:
CBrush brush(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds,&brush);
pdc->SetBkMode(TRANSPARENT);
pdc->SetTextColor(TranslateColor(GetForeColor()));
//为控件设置属性,必须在MFC ClassWizared中为控件添加属性,上面几 //行代码才有用
CTime time=CTime::GetCurrentTime();
CString str=time.Format("%H : %M : %S");
pdc->TextOut(0,0,str);
这样就能做出一个静态的时间控件,如果我们想使控件实时显示时间,需要添加两个消息响应函数 WM_CREATE,WM_TIMER.
代码:
int CClockCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
SetTimer(1,1000,NULL);
return 0;
}
void CClockCtrl::OnTimer(UINT nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
Invalidate(); //立即引起窗口重绘
//也可以使用InvalidateControl(); //强制窗口重绘,效果相同
COleControl::OnTimer(nIDEvent);
}
要修改控件的背景色前景色和字体颜色
在OnDraw中添加
CBrush brush(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds,&brush);
pdc->SetBkMode(TRANSPARENT);
pdc->SetTextColor(TranslateColor(GetForeColor()));
ActiveX控件的四种属性
Stock:为每个控件提供的标准属性,如字体或颜色。
Ambient:围绕控件的环境属性——已被置入容器的属性。这些属性不能被修改,但控件可以使用它们调整自己的属性。
Extended:这些是由容器处理的属性,一般包括大小和在屏幕上的位置。
Custom:由控件开发者添加的属性。
使控件具有多于一个属性页
首先在**ctl.cpp中找到Property Pages,代码如下:
BEGIN_PROPPAGEIDS(CClockCtrl, 2)
PROPPAGEID(CClockPropPage::guid)
PROPPAGEID(CLSID_CColorPropPage)
END_PROPPAGEIDS(CClockCtrl)
需要注意的是要显示几个属性页BEGIN_PROPPAGEIDS(CClockCtrl, 2)中的代码为几,如果没有修改或修改错误,会产生不可预料错误。
要增加标准属性,在_DClock上点击右键,选择增加属性,选中Stock,例如选择背景色和前景色
接下来会在Clock.odl下生成以下代码:
dispinterface _DClock
{
properties:
[id(DISPID_BACKCOLOR), helpstring("属性 BackColor")] OLE_COLOR BackColor;
[id(DISPID_FORECOLOR), helpstring("属性 ForeColor")] OLE_COLOR ForeColor;
methods:
[id(DISPID_ABOUTBOX)] void AboutBox();
};
接下来新增自定义属性,方法同上,只是需选中“成员变量”或“get/put”
会自动生成成员变量:m_Interval,和成员函数OnIntervalChanged。
接下来添加代码:
void CClockCtrl::OnIntervalChanged(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加属性处理程序代码
if(m_Interval<0 || m_Interval>6000)
{
m_Interval=2000;
}
KillTimer(1);
SetTimer(1,m_Interval/1000*1000,NULL);
SetModifiedFlag();
}
测试:运行ActiveX测试器,选择control---〉Invoke Methods对m_Interval进行修改。
为编辑框增加成员变量MFC ClassWizard-->Member Variables-->Add Member Variable-->
Optional property name:
选择自定义属性的外部名,这样我们不需要增加代码就能把控件和自定义属性相关联。
在void CClockPropPage::DoDataExchange(CDataExchange* pDX)中会生成下面代码:
DDP_Text(pDX, ID_EDIT_INTERVAL, m_updateInterval, _T("Interval") );
DDX_Text(pDX, ID_EDIT_INTERVAL, m_updateInterval);
在.NET2003下我始终找不到“Optional property name:”在哪,所以在我属性页上的编辑框无效,我只能选择control---〉Invoke Methods进行修改。
为控件增加函数,MFC ClassWizard-->Member Variables-->Add Method
Class Name要选择CClockCtrl
输入函数名,之后就可以在CClockCtrl类中找到了
我们选择MFC ClassWizard-->ActiveX Events--->Add Event
之后会在DClockEvents中增加一个事件,DClockEvents接口是源接口,控件将用这个接口发送通知事件,它不是控件本身实现的接口,这个接口是通过容器来实现的
如果要将自定义的控件属性保存下来,需要在
void CClockCtrl::DoPropExchange(CPropExchange* pPX)加入如下代码:
PX_Short(pPX,"Interval",m_interval,1000);
之后再在程序中修改代码:
PX_Short(pPX,"Interval",m_interval,1000);
如果想使自定义控件属性实时地显示在容器属性列表中,
在void CClockCtrl::OnIntervalChanged() 中加入如下代码:
BoundPropertyChanged(0x1); //调度代码为1
如果希望用户在设计模式时时钟控件停止运行,而在用户模式下运行,可以
在void CClockCtrl::OnTimer(UINT nIDEvent)下修改代码如下:
if(AmbientUserMode()) //查询环境属性
InvalidateControl();
第18课 ActiveX编程(下面X均为ActiveX简称)
1.在VB中调用X控件,添加方法 project->Add components。另外可以用Object Browser来查看控件
2.在VC中创建X控件
1.新建一个X工程名为Clock,注意一个文件中可以包含多个控件。
2.保持缺省设置,完成。注意它生成的三个类,以及相关的接口。
3.运行它。选择TSTCON32.exe作为容器。
4.选择Insert Control,此时我们可以看到,它画了一个椭圆。也可以在VB中测试。
5.删除注册信息。用regsvr32 /u +文件名。也可以在菜单选择反注册命令。
6.重写代码。在CClockCtrl::OnDraw()中画了一个椭圆,此时我们在其中得到系统时间,并显示它。为此我们在OnCreate()设置了一个定时器,每隔一定时间发出一个Invalidate()消息,使窗口重绘。
7.如何改变控件的背景色和前景色?ClassWizard->AutoMation->Add Property->BackColor,还需要在OnDraw()中加上相应的代码
CBrush brush(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds, &brush);
pdc->SetBkMode(TRANSPARENT);
pdc->SetTextColor(TranslateColor(GetForeColor()));
8.增加属性页。在
BEGIN_PROPPAGEIDS(CClockCtrl, 2)此时数目也得改成相应的数目
PROPPAGEID(CClockPropPage::guid)
PROPPAGEID(CLSID_CColorPropPage)
END_PROPPAGEIDS(CClockCtrl) OK~
9.增加自定义属性:ClassWizard->AutoMation->Add Property加上一个变量m_interval,类型为short,对应外部变量为Interval。在CClockCtrl中增加 OnIntervalChanged方法。添加如下代码:
if(m_interval<0 || m_interval>6000)
{
m_interval=1000;
}
else
{
m_interval=m_interval/1000*1000;
KillTimer(1);
SetTimer(1,m_interval,NULL);
BoundPropertyChanged(0x1);
}
10.测试:Control->Invoke Methods
11.将时间间隔加到属性页中,在资源视图中加入一文本框和编辑框。为EditBox关联成员变量,加入属性interval。
12.增加方法:ClassWizard->AutoMation->Add Method->Hello加入代码 OK!在VB中可以调用此方法!
void CClockCtrl::Hello()
{
// TOD Add your dispatch handler code here
MessageBox("Hello world!");
}
13.增加事件:ClassWizard->AutoMation->Add Events->Click
14.增加自定义事件:ClassWizard->AutoMation->Add Events->NewMinute
在新的一分钟到达时发出这个通知,在OnDraw()中写代码:
CTime time=CTime::GetCurrentTime();
if(0==time.GetSecond())
{
FireNewMinute();
}
15.让Interval属性具有持久性。在CClockCtrl::DoPropExchange()中调用PX_short()方法,OK!
PX_Short(pPX,"Interval",m_interval,1000);
16.让Property Page和Property属性中的interval保持一致的方法:在OnIntervalChanged()中调用BoundPropertyChanged(0x1);
17.希望控件在设计时间内不走动的方法:在OnTimer()中, if(AmbientUserMode())InvalidateControl();巧妙!
3.在VC中调用X控件
1.新建ClockTest对话框应用程序
2.点击右键->插入X控件->时钟控件
3.Project->Add Component会生成CClock类。
4.在CCLockTestDlg中增加CClock类的成员变量m_clock,然后可以动态创建一个这样的东东!
5.试验Click(),NewMinute(),SetBkColor(),SetForeColor()方法和属性
6.如何为动态创建的控件做事件响应呢?首先你得知道它的ID号,然后参考非动态的控件事件代码,呵。
容器和服务器程序
容器应用程序时可以嵌入或链接对象的应用程序。Word就是容器应用程序。
服务器应用程序是创建对象并且当对象被双击时,可以被启动的应用程序。Excel就是服务器应用程序。
ActiveX控件不能独立运行,它必须被嵌入容器应用程序中,和容器应用程序一起运行。
Dispatch maps调度映射,主要是MFC提供让外部应用程序可以访问控件的属性和方法
Event maps事件映射,控件向包含它的容器发送事件通知
接口是外部程序和控件进行通信的协议,可以把接口看作是函数的集合,外部程序通过借口提供的方法,去访问控件的属性和方法。接口中所定义的所有函数都是纯虚函数
regsvr32 ...注册控件 regsvr32 /u....卸载控件
STDAPI DllRegisterServer(void)将控件信息写入注册表中
STDAPI DllUnregisterServer(void)卸载注册信息。
***一个时间控件,在
void CClockCtrl::OnDraw(CDC* pdc, const CRect& rcBounds,
const CRect& rcInvalid)中添加以下代码:
CBrush brush(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds,&brush);
pdc->SetBkMode(TRANSPARENT);
pdc->SetTextColor(TranslateColor(GetForeColor()));
//为控件设置属性,必须在MFC ClassWizared中为控件添加属性,上面几 //行代码才有用
CTime time=CTime::GetCurrentTime();
CString str=time.Format("%H : %M : %S");
pdc->TextOut(0,0,str);
这样就能做出一个静态的时间控件,如果我们想使控件实时显示时间,需要添加两个消息响应函数 WM_CREATE,WM_TIMER.
代码:
int CClockCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
SetTimer(1,1000,NULL);
return 0;
}
void CClockCtrl::OnTimer(UINT nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
Invalidate(); //立即引起窗口重绘
//也可以使用InvalidateControl(); //强制窗口重绘,效果相同
COleControl::OnTimer(nIDEvent);
}
要修改控件的背景色前景色和字体颜色
在OnDraw中添加
CBrush brush(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds,&brush);
pdc->SetBkMode(TRANSPARENT);
pdc->SetTextColor(TranslateColor(GetForeColor()));
ActiveX控件的四种属性
Stock:为每个控件提供的标准属性,如字体或颜色。
Ambient:围绕控件的环境属性——已被置入容器的属性。这些属性不能被修改,但控件可以使用它们调整自己的属性。
Extended:这些是由容器处理的属性,一般包括大小和在屏幕上的位置。
Custom:由控件开发者添加的属性。
使控件具有多于一个属性页
首先在**ctl.cpp中找到Property Pages,代码如下:
BEGIN_PROPPAGEIDS(CClockCtrl, 2)
PROPPAGEID(CClockPropPage::guid)
PROPPAGEID(CLSID_CColorPropPage)
END_PROPPAGEIDS(CClockCtrl)
需要注意的是要显示几个属性页BEGIN_PROPPAGEIDS(CClockCtrl, 2)中的代码为几,如果没有修改或修改错误,会产生不可预料错误。
要增加标准属性,在_DClock上点击右键,选择增加属性,选中Stock,例如选择背景色和前景色
接下来会在Clock.odl下生成以下代码:
dispinterface _DClock
{
properties:
[id(DISPID_BACKCOLOR), helpstring("属性 BackColor")] OLE_COLOR BackColor;
[id(DISPID_FORECOLOR), helpstring("属性 ForeColor")] OLE_COLOR ForeColor;
methods:
[id(DISPID_ABOUTBOX)] void AboutBox();
};
接下来新增自定义属性,方法同上,只是需选中“成员变量”或“get/put”
会自动生成成员变量:m_Interval,和成员函数OnIntervalChanged。
接下来添加代码:
void CClockCtrl::OnIntervalChanged(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加属性处理程序代码
if(m_Interval<0 || m_Interval>6000)
{
m_Interval=2000;
}
KillTimer(1);
SetTimer(1,m_Interval/1000*1000,NULL);
SetModifiedFlag();
}
测试:运行ActiveX测试器,选择control---〉Invoke Methods对m_Interval进行修改。
为编辑框增加成员变量MFC ClassWizard-->Member Variables-->Add Member Variable-->
Optional property name:
选择自定义属性的外部名,这样我们不需要增加代码就能把控件和自定义属性相关联。
在void CClockPropPage::DoDataExchange(CDataExchange* pDX)中会生成下面代码:
DDP_Text(pDX, ID_EDIT_INTERVAL, m_updateInterval, _T("Interval") );
DDX_Text(pDX, ID_EDIT_INTERVAL, m_updateInterval);
在.NET2003下我始终找不到“Optional property name:”在哪,所以在我属性页上的编辑框无效,我只能选择control---〉Invoke Methods进行修改。
为控件增加函数,MFC ClassWizard-->Member Variables-->Add Method
Class Name要选择CClockCtrl
输入函数名,之后就可以在CClockCtrl类中找到了
我们选择MFC ClassWizard-->ActiveX Events--->Add Event
之后会在DClockEvents中增加一个事件,DClockEvents接口是源接口,控件将用这个接口发送通知事件,它不是控件本身实现的接口,这个接口是通过容器来实现的
如果要将自定义的控件属性保存下来,需要在
void CClockCtrl::DoPropExchange(CPropExchange* pPX)加入如下代码:
PX_Short(pPX,"Interval",m_interval,1000);
之后再在程序中修改代码:
PX_Short(pPX,"Interval",m_interval,1000);
如果想使自定义控件属性实时地显示在容器属性列表中,
在void CClockCtrl::OnIntervalChanged() 中加入如下代码:
BoundPropertyChanged(0x1); //调度代码为1
如果希望用户在设计模式时时钟控件停止运行,而在用户模式下运行,可以
在void CClockCtrl::OnTimer(UINT nIDEvent)下修改代码如下:
if(AmbientUserMode()) //查询环境属性
InvalidateControl();
相关文章推荐
- 18ActiveX控件.txt
- nyoj_18_The Triangle_201312071533
- ActiveX控件在项目中的应用
- VC2010开发MFC ActiveX控件基础教程
- 18. 4Sum
- Android菜鸟的成长笔记(18)——绑定本地Service并与之通信
- 18、Java并发性和多线程-饥饿与公平
- InstallShield内部库函数之18 扩展函数
- 在论坛中出现的比较难的sql问题:18(字符合并1)
- 机器学习18-XGBoost的推导过程
- Effective STL 条款18
- 数据结构 18 图 最短路径-迪杰斯特拉最短算法
- [机器学习入门] 李宏毅机器学习笔记-18 (Deep Generative Model-part 1:深度生成模型-part 1)
- 如何用c#来制作一个activeX控件或类似的东西
- 在HTML网页中使用ActiveX控件
- Kotlin-18.对象(object expressions/declarations)
- 18 Log4J
- hadoop安装--18-- 验证 WordCount 例子
- PAT乙级真题及训练集(18)--1006. 换个格式输出整数 (15)
- 2004年给人印象深刻的18个人博客网站[转贴]