ActiveX控件
容器和服务器程序
容器应用程序是可以嵌入或链接对象的应用程序。Word就是容器应用程序。
服务器应用程序是创建对象并且当对象被双击时,可以被启动的应用程序。Excel就是服务器应用程序。
◆ ColeControlModule: CclockApp是,的派生类,他是应用程序类,他的实例表示控件的本身,而ColeControlModule又是CwinApp的派生类
◆ ClockCtl:它是从ColeControl派生出来的,而ColeControl继承了CWnd,她也是一个窗口类。
◆ CclockPropPage是从对话框派生出来的,也就是Cdialog。用来显示自定义类型的属性。显示控件的属性页。
◆ Dispatch maps调度映射,主要是MFC提供让外部应用程序可以访问控件的属性和方法
◆ Event maps事件映射,控件向包含它的容器发送事件通知
◆ ActiveX Control Container用来加载ActiveX控件。
◆ regsvr32 ...注册控件 regsvr32 /u....卸载控件。
◆ STDAPI DllRegisterServer(void)将控件信息写入注册表中
STDAPI DllUnregisterServer(void)卸载注册信息。
STDAPI DllUnregisterServer(void)卸载注册信息。
◆ 制作一个时间控件
void CClockCtrl::OnDraw(CDC* pdc, const CRect& rcBounds,
const CRect& rcInvalid)中添加以下代码:
CTime time=CTime::GetCurrentTime();
CString str=time.Format("%H : %M : %S");
pdc->TextOut(0,0,str);
const CRect& rcInvalid)中添加以下代码:
CTime time=CTime::GetCurrentTime();
CString str=time.Format("%H : %M : %S");
pdc->TextOut(0,0,str);
◆让时间走起来:创建windows窗口处理:WM_CREATE:OnCreate()
SetTimer(1,1000,NULL)
◆然后增加WM_TIMER消息,在OnTimer的Invalidate();使窗口有效
还有一个方法:ColeControl::InvalidateControl实现同样的功能
代码:
int CClockCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
int CClockCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
SetTimer(1,1000,NULL);
return 0;
}
return 0;
}
void CClockCtrl::OnTimer(UINT nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
Invalidate(); //立即引起窗口重绘
//也可以使用InvalidateControl(); //强制窗口重绘,效果相同
COleControl::OnTimer(nIDEvent);
}
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
Invalidate(); //立即引起窗口重绘
//也可以使用InvalidateControl(); //强制窗口重绘,效果相同
COleControl::OnTimer(nIDEvent);
}
◆ 要为控件实现背景颜色和前景颜色:ClassWizardr然后AutoMation然后增加属性
◆ 改变控件的背景前景颜色:CClockCtrl::GetBackColor, CClockCtrl::GetForeColor
◆ 要修改控件的背景色前景色和字体颜色,在OnDraw中添加,使用画刷
◆ CBrush brush(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds,&brush);
pdc->SetBkMode(TRANSPARENT);
pdc->SetTextColor(TranslateColor(GetForeColor()));
pdc->FillRect(rcBounds,&brush);
pdc->SetBkMode(TRANSPARENT);
pdc->SetTextColor(TranslateColor(GetForeColor()));
将背景设置成透明:pdc->SetBkMode(TRANSPARENT);
◆ ActiveX控件的四种属性
Stock:为每个控件提供的标准属性,如字体或颜色。
Ambient:围绕控件的环境属性——已被置入容器的属性。这些属性不能被修改,但控件可以使用它们调整自己的属性。
Extended:这些是由容器处理的属性,一般包括大小和在屏幕上的位置。
Custom:由控件开发者添加的属性。
Stock:为每个控件提供的标准属性,如字体或颜色。
Ambient:围绕控件的环境属性——已被置入容器的属性。这些属性不能被修改,但控件可以使用它们调整自己的属性。
Extended:这些是由容器处理的属性,一般包括大小和在屏幕上的位置。
Custom:由控件开发者添加的属性。
◆ 找到Property Pages,代码如下:
BEGIN_PROPPAGEIDS(CClockCtrl, 2)
PROPPAGEID(CClockPropPage::guid)
PROPPAGEID(CLSID_CColorPropPage)
END_PROPPAGEIDS(CClockCtrl)
需要注意的是要显示几个属性页BEGIN_PROPPAGEIDS(CClockCtrl, 2)中的代码为几,如果没有修改或修改错误,会产生不可预料错误。
BEGIN_PROPPAGEIDS(CClockCtrl, 2)
PROPPAGEID(CClockPropPage::guid)
PROPPAGEID(CLSID_CColorPropPage)
END_PROPPAGEIDS(CClockCtrl)
需要注意的是要显示几个属性页BEGIN_PROPPAGEIDS(CClockCtrl, 2)中的代码为几,如果没有修改或修改错误,会产生不可预料错误。
◆ 时间间隔的追加,增加一个属性,然后在ClockCtl中追加
void CClockCtrl::OnIntervalChanged()
{
// TODO: Add notification handler code
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);
}
SetModifiedFlag();
}
◆ ActiveX的Clock中添加事件和方法:都是可以用ClassWizardr来实现
◆ 增加事件:_DclockEvents接口的说明,source表明他是原接口,也就是控件用这个接口发送和通知事件,容器会实现该接口
coclass Clock
{
[default] dispinterface _DClock;
[default, source] dispinterface _DClockEvents;
};
◆ 如果要将自定义的控件属性保存下来,需要在
void CClockCtrl::DoPropExchange(CPropExchange* pPX)加入如下代码:
PX_Short(pPX,"Interval",m_interval,1000);
之后再在程序中修改代码:
void CClockCtrl::DoPropExchange(CPropExchange* pPX)加入如下代码:
PX_Short(pPX,"Interval",m_interval,1000);
之后再在程序中修改代码:
◆ 属性页通知属性面板做相应的改变:BoundPropertyChanged(0x1); 0x1为控件绑定属性调用的ID
◆ 如果希望用户在设计模式时时钟控件停止运行,而在用户模式下运行,可以
在void CClockCtrl::OnTimer(UINT nIDEvent)下修改代码如下:
if(AmbientUserMode()) //查询环境属性
InvalidateControl();
在void CClockCtrl::OnTimer(UINT nIDEvent)下修改代码如下:
if(AmbientUserMode()) //查询环境属性
InvalidateControl();