(1)一是从MFC提供的控件类派生一个新类,通过合理地设计派生类,可以修改控件的行为和属性以达到用户的要求,但此类控件使用范围很小。
(2)二是编写一个ActiveX控件,以后可以在不同的应用程序中重复使用。
1、创建ActiveX控件框架:
(1)创建ActiveX控件工程
使用MFC ActiveX ControlWizard创建一个名为MyTime的ActiveX控件工程,使用默认设置。
(2)MyTime控件的文件构成
查看MyTime工程的Class View页面,其中:
_DMyTime:一个dispinterface类型的结构,用来包含控件的属性和方法。
_DMyTimeEvents:也是一个dispinterface类型的结构,用来包含控件的事件。
CMyTimeApp:此类派生自COleControlModule,用于初始化控件。可以在该类的InitInstance函数中添加相应的初始化代码;在ExitInstance函数中添加清除代码。
CMyTimeCtrl:此类派生自COleControl类,主要处理控件的显示以及对消息的响应等,后面的大部分工作就是对这个类进行编程。
CMyTimePropPage:此类派生自COlePropertyPage类,这个类描述了控件属性对话框中的名为Control的选项卡。
全局对象DllRegisterServer函数用于注册控件,DllUnregisterServer用于移出注册。
注意:使用ControlWizard产生的ActiveX控件都派生自COleControl类。
(3)测试ActiveX控件
单击Tools|ActiveX Control Test Container菜单项,使用Visual C++6.0提供的ActiveX控件测试工具来测试MyTime控件。单击测试工具程序的Edit|Insert New Control菜单项,在Insert Control对话框中选择MyTime Control控件。
2、修改ActiveX控件的显示:
首先获取系统当前时间,然后将时间转换成文本在控件中输出。同时,还必须根据时、分、秒的数值将时钟画出来。
(1)显示时钟
1)修改CMyTimeCtrl类的构造函数CMyTimeCtrl如下:
CMyTimeCtrl::CMyTimeCtrl()
{
InitializeIIDs(&IID_DMyTime, &IID_DMyTimeEvents);
// TODO: Initialize your control's instance data here.
SetInitialSize(200, 230); //设置控件初始尺寸大小
}
2)修改CMyTimeCtrl类的OnDraw函数如下:
void CMyTimeCtrl::OnDraw(CDC* pdc, const CRect& rcBounds,const CRect& rcInvalid)
{
// TODO: Replace the following code with your own drawing code.
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
// pdc->Ellipse(rcBounds);
pdc->SetBkMode(TRANSPARENT); //设置背景透明
CTime time;
time = CTime::GetCurrentTime(); //获取系统时间
double pi = 3.14159265; //圆周率
int cx = rcBounds.left + 100; //时钟的中心位置x坐标
int cy = rcBounds.top + 100; //时钟的中心位置y坐标
//使用循环画出时钟盘面
for(int i=0; i<60; i++)
{
int x = cx + 80*cos(i*pi/30) +0.5;
int y = cy + 80*sin(i*pi/30) +0.5;
if(i%5 == 0) pdc->Ellipse(x-3, y-3, x+3, y+3); //大刻度
else pdc->Ellipse(x-1, y-1, x+1, y+1); //小刻度
}
CString str = time.Format("%H:%M:%S"); //将时间写入字符串
//输出字符串,在时钟下面以数字方式显示时间
pdc->TextOut(rcBounds.left+70, rcBounds.top+200, str);
///
// 下面将使用三种不同粗细的画笔来画出时钟的时针、分针和秒针
///
CPen pen1(PS_SOLID, 4, RGB(0,0,0)); //时针画笔
CPen pen2(PS_SOLID, 2, RGB(0,0,0)); //分针画笔
CPen pen3(PS_SOLID, 1, RGB(0,0,0)); //秒针画笔
//根据当前时间计算时针的终点位置(x1,y1)
int x1 = cx + 40*cos((time.GetHour()-3)*pi/6 +
(time.GetMinute()/12)*pi/30) + 0.5;
int y1 = cx + 40*sin((time.GetHour()-3)*pi/6 +
(time.GetMinute()/12)*pi/30) + 0.5;
//根据当前时间计算分针的终点位置(x2,y2)
int x2 = cx + 60*cos((time.GetMinute()-15)*pi/30) + 0.5;
int y2 = cx + 60*sin((time.GetMinute()-15)*pi/30) + 0.5;
//根据当前时间计算秒针的终点位置(x3,y3)
int x3 = cx + 70*cos((time.GetSecond()-15)*pi/30) + 0.5;
int y3 = cx + 70*sin((time.GetSecond()-15)*pi/30) + 0.5;
CPen * pOldPen = pdc->SelectObject(&pen1);
pdc->MoveTo(cx, cy); //画出时针
pdc->LineTo(x1, y1);
pdc->SelectObject(&pen2);
pdc->MoveTo(cx, cy); //画出分针
pdc->LineTo(x2, y2);
pdc->SelectObject(&pen3);
pdc->MoveTo(cx, cy); //画出秒针
pdc->LineTo(x3, y3);
pdc->SelectObject(pOldPen); //落选画笔
}
3)由于使用了数学函数sin和cos,因此在MyTimeCtl.cpp文件中包含math.h:
#include "math.h"
(2)增加计时器
接下来,要让时钟能够动起来。类似在状态栏上显示时间一样,将要为MyTime添加WM_TIMER消息处理,并设置定时器。
1)使用ClassWizard为CMyTimeCtrl类添加三个消息处理,WM_CREATE消息处理函数Oncreate,WM_TIMER消息处理函数OnTimer,WM_CLOSE消息处理函数OnClose。
2)修改OnCreate函数如下:
int CMyTimeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
SetTimer(1, 1000, NULL); //设置计时器
return 0;
}
3)修改OnTimer函数如下:
void CMyTimeCtrl::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
InvalidateControl(); //重画控件,相当于调用OnDraw函数
COleControl::OnTimer(nIDEvent);
}
4)修改OnClose函数如下:
void CMyTimeCtrl::OnClose()
{
// TODO: Add your message handler code here and/or call default
KillTimer(1); //释放计时器
CWnd::OnClose();
}
(3)修改控件示意图标
打开MyTime控件工程的资源,修改名为IDB_MYTIME的位图资源。
编译MyTime控件工程,将MyTime控件插入到Time工程。修改Time工程的IDD_TIME_DIALOG对话框模板,插入一个MyTime控件和一个分组框。
注意:(1)此时,查看MyTime控件的属性,会发现Control和All属性对话框都是空白的,因为此时还没有为MyTime控件添加任何属性。
(2)此时,如果使用ClassWizard查看MyTime控件所能产生的事件时,会发现是空的,因为此时还没有为控件添加事件。
3、添加属性:
4、使用库存属性的对应方法:
5、添加属性页:
6、添加事件:
步骤总结:
1、使用MFC ActiveX Control Wizard创建控件工程框架
2、定制控件的界面和图标
3、为控件添加属性、事件和方法并进行相应的处理