时钟控件鼠标事件.docx
- 文档编号:4746523
- 上传时间:2023-05-07
- 格式:DOCX
- 页数:18
- 大小:61.67KB
时钟控件鼠标事件.docx
《时钟控件鼠标事件.docx》由会员分享,可在线阅读,更多相关《时钟控件鼠标事件.docx(18页珍藏版)》请在冰点文库上搜索。
时钟控件鼠标事件
时钟控件-鼠标事件
例2利用MFC创建一个ActiveX控件Clock,该控件用数字时钟显示当前时间。
并且,当用鼠标单击控件时,数字时钟就变成了表盘查模拟钟。
[编程说明与实现]
(1)执行File|New命令,选择Project页,选择MFCActiveXControlWizard项目,类型,项目名称为Clock,单击OK按钮。
在向导Stepof2设置控件的数目,并选择是否需要口令、注释和帮助文件,本例选择默认值。
在向导Step 2of2确定控件的类名Clock和文件名,选择控件属性、控件的基类,确定ActiveX高级特性。
(2)控件类CClockCtrl的OnDraw()函数用于绘制控件,但调用OnDraw()函数只能显示一次当前时间。
要想使时钟走动起来,需要处理WM_TIMER消息。
利用ClassWizard为类CClockCtrl添加WM_TIMER的消息处理函数OnTimer(),在函数中通过不断调用重画控件函数,从而自动调用OnDraw()函数动态显示当前时间。
Cpp代码
1.void CClockCtrl:
:
OnTimer(UINT nIDEvent)
2.{
3. // TODO:
Add your message handler code here and/or call default
4. InvalidateControl(); //重画控件
5. COleControl:
:
OnTimer(nIDEvent);
6.}
voidCClockCtrl:
:
OnTimer(UINTnIDEvent)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
InvalidateControl();//重画控件
COleControl:
:
OnTimer(nIDEvent);
}
(3)在控件窗口创建时建立定时器,利用ClassWizard为类CClockCtrl添加消息WM_CREATE的处理函数CClockCtrl:
:
OnCreate();在控件窗口销毁时删除所建立的定时器,利用ClassWizard为类CClockCtrl添加消息DestroyWindow的处理函数。
为类CClockCtrl添加属性为protected、类型为UINT的成员变量m_timer。
Cpp代码
1.int CClockCtrl:
:
OnCreate(LPCREATESTRUCT lpCreateStruct)
2.{
3. if (COleControl:
:
OnCreate(lpCreateStruct) == -1)
4. return -1;
5.
6. // TODO:
Add your specialized creation code here
7. //建立定时器,时间间隔为m_updateInterval(在第5步添加该成员变量)
8. m_timer=SetTimer(1,(UINT)m_updateInterval,NULL);
9. return 0;
10.}
intCClockCtrl:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(COleControl:
:
OnCreate(lpCreateStruct)==-1)
return-1;
//TODO:
Addyourspecializedcreationcodehere
//建立定时器,时间间隔为m_updateInterval(在第5步添加该成员变量)
m_timer=SetTimer(1,(UINT)m_updateInterval,NULL);
return0;
}
Cpp代码
1.BOOL CClockCtrl:
:
DestroyWindow()
2.{
3. // TODO:
Add your specialized code here and/or call the base class
4. KillTimer(m_timer); //销毁时钟
5. return COleControl:
:
DestroyWindow();
6.}
BOOLCClockCtrl:
:
DestroyWindow()
{
//TODO:
Addyourspecializedcodehereand/orcallthebaseclass
KillTimer(m_timer); //销毁时钟
returnCOleControl:
:
DestroyWindow();
}
(4)为了在控件窗口响应单击事件,必须添加该控件事件,该事件是ActiveX控件的库存(stock)事件。
启动ClassWizard,选择ActiveEvents页面,单击AddEvent按钮,在打开对话框AddEvent的Externalname下列框中选择click。
库存事件不需要添加代码,ClassWizard自动在ClockCtl.cpp文件中合适位置加入以下事件映射。
Cpp代码
1.EVENT_STOCK_CLICK()
EVENT_STOCK_CLICK()
再利用ClassWizard为类CClockCtrl添加单击消息OnClick的处理函数
Cpp代码
1.void CClockCtrl:
:
OnClick(USHORT iButton)
2.{
3. // TODO:
Add your specialized code here and/or call the base class
4. //单击控件时,切换钟表的显示方式
5. m_ifDigitShape=!
m_ifDigitShape; //m_ifDigitShape是控件的自定义属性成员变量
6. InvalidateControl();
7. COleControl:
:
OnClick(iButton);
8.}
voidCClockCtrl:
:
OnClick(USHORTiButton)
{
//TODO:
Addyourspecializedcodehereand/orcallthebaseclass
//单击控件时,切换钟表的显示方式
m_ifDigitShape=!
m_ifDigitShape;//m_ifDigitShape是控件的自定义属性成员变量
InvalidateControl();
COleControl:
:
OnClick(iButton);
}
(5)显示时钟需要获取控件的背景颜色,因此为控件添加库存属性BackColor。
启动ClassWizard类向导,选择Automation页面,单击AddProperty按钮,在打开对话框AddProperty的Externalname下拉框中选择BackColor,单击OK按钮。
Clock控件还需要表示显示间隔和显示方式的两个自定义属性,启动ClassWizard选择Automation页面,单击AddProperty按钮,在打开对话框AddProperty的Externalname下拉框中输入UpdateInterval(显示间隔),Type选择Long,Implementation选择MemberVariable。
向导将自动加入属性变量m_updateInterval和处理属性的成员函数。
用同样方法加入自定义属性IfDigitShape(显示方式),其类型为BOOL。
(6)程序员编程使用ActiveX控件时,与标准控件一样,可打开控件属性对话框设置ActiveX控件的属性。
ActiveX控件属性对话框包含多个属性页(propertypage)。
利用MFCActiveXControlWizard创建ActiveX控件时,已经提供了默认的属性页。
在创建的Clock控件中,除子默认的General属性页,还要加入Color属性页。
在ClockCtl.cpp中找到说明PropertyPages的宏,进行如下修改:
Cpp代码
1.BEGIN_PROPPAGEIDS(CClockCtrl, 2) //2表示共两个属性页
2. PROPPAGEID(CClockPropPage:
:
guid)
3. PROPPAGEID(CLSID_CColorPropPage) //颜色属性页码
4.END_PROPPAGEIDS(CClockCtrl)
BEGIN_PROPPAGEIDS(CClockCtrl,2)//2表示共两个属性页
PROPPAGEID(CClockPropPage:
:
guid)
PROPPAGEID(CLSID_CColorPropPage)//颜色属性页码
END_PROPPAGEIDS(CClockCtrl)
(7)为了使控件能够保存设置的属性,需向DoProExchange()函数添加如下代码。
Cpp代码
1.void CClockCtrl:
:
DoPropExchange(CPropExchange* pPX)
2.{
3. ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
4. COleControl:
:
DoPropExchange(pPX);
5. PX_Bool(pPX,"IfDigitShape",m_ifDigitShape,TRUE);
6. PX_Long(pPX,"UpdateInterval",m_updateInterval,1000);
7.
8. // TODO:
Call PX_ functions for each persistent custom property.
9.}
voidCClockCtrl:
:
DoPropExchange(CPropExchange*pPX)
{
ExchangeVersion(pPX,MAKELONG(_wVerMinor,_wVerMajor));
COleControl:
:
DoPropExchange(pPX);
PX_Bool(pPX,"IfDigitShape",m_ifDigitShape,TRUE);
PX_Long(pPX,"UpdateInterval",m_updateInterval,1000);
//TODO:
CallPX_functionsforeachpersistentcustomproperty.
}
(8)在ClockCtl类的构造函数中添加代码,初始化控件大小。
Cpp代码
1.CClockCtrl:
:
CClockCtrl()
2.{
3. InitializeIIDs(&IID_DClock, &IID_DClockEvents); //通知控件要用的IIDS的基类
4. SetInitialSize(150,120); //设置控件在容器中第一次显示时的大小150*120
5. // TODO:
Initialize your control's instance data here.
6.}
CClockCtrl:
:
CClockCtrl()
{
InitializeIIDs(&IID_DClock,&IID_DClockEvents);//通知控件要用的IIDS的基类
SetInitialSize(150,120);//设置控件在容器中第一次显示时的大小150*120
//TODO:
Initializeyourcontrol'sinstancedatahere.
}
(9)OnDraw()函数用于绘制控件,即显示时间。
在OnDraw()函数中调用了一些数学函数,因此需在ClockCtl.cpp文件开始位置添加包含文件语句:
#include"math.h"。
以下是OnDraw()函数的完整代码。
Cpp代码
1.void CClockCtrl:
:
OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
2.{
3. // TODO:
Replace the following code with your own drawing code.
4. //pdc->FillRect(rcBounds, CBrush:
:
FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
5. //pdc->Ellipse(rcBounds);
6. CRect Rect;
7. :
:
GetClientRect(this->m_hWnd,&Rect);
8. int nCenterX=Rect.right/2;
9. int nCenterY=Rect.bottom/2;
10. pdc->SetTextColor(TranslateColor(GetForeColor()));
11. pdc->SetBkMode(TRANSPARENT); //将控件背景颜色设置为透明方式
12. //建立一具刷子,该画刷的颜色为背景所设置的颜色
13. CBrush* pBrush=new CBrush(TranslateColor(GetBackColor()));
14. pdc->FillRect(&Rect,pBrush);
15. delete pBrush;
16. CFont* pOldFont;
17. pOldFont=SelectStockFont(pdc); //选择库存字体
18. CTime Time=CTime:
:
GetCurrentTime(); //获取当前时间
19. if(m_ifDigitShape) //如果是数字时钟,在表盘中以电子表的方式显示当前时间
20. {
21. CString CurrentTime=Time.Format("%B:
%d:
%Y %H:
%M:
%S");
22. pdc->ExtTextOut(rcBounds.left,rcBounds.top,ETO_CLIPPED,rcBounds,CurrentTime,strlen(CurrentTime),NULL);
23. }
24. else //模拟时钟的方式显示当前时间
25. {
26. CString strDigits;
27. int i,x,y;
28. CSize size;
29. CPen pen(PS_SOLID,5,RGB(0,0,255)); //创建一支蓝笔来绘制椭圆
30. CPen* pOldPen=pdc->SelectObject(&pen); //将新笔选入设备描述表
31. pdc->Ellipse(5,5,Rect.right-5,Rect.bottom-5); //绘制时钟边界
32. double Radians;
33. pdc->SetTextColor(RGB(255,0,0)); //时钟上的文字选择红色
34. for(i=1;i<=12;i++)
35. {
36. strDigits.Format("%d",i); //对输出的时钟数字进行格式化
37. //获得时钟数值的范围,以便计算中心
38. size=pdc->GetTextExtent(strDigits,strDigits.GetLength());
39. Radians=(double)i*6.28/12.0; //计算文本输出的位置
40. x=nCenterX-(size.cx/2)+(int)((double)(nCenterX-20)*sin(Radians));
41. y=nCenterY-(size.cy/2)+(int)((double)(nCenterY-20)*cos(Radians));
42. pdc->TextOut(x,y,strDigits); //显示钟表盘上的数字
43. }
44. Radians=(double)Time.GetHour()+(double)Time.GetMinute()/60.0
45. +(double)Time.GetSecond()/3600.0; //计算时针半径
46. Radians*=6.28/12.0;
47. CPen HourPen(PS_SOLID,5,RGB(0,255,0)); //创建绘制时针的画笔
48. pdc->SelectObject(&HourPen); //将该笔选入设备描述表
49. pdc->MoveTo(nCenterX,nCenterY); //绘制时针
50. pdc->LineTo(nCenterX+(int)((double)(nCenterX/3)*sin(Radians)),
51. nCenterY-(int)((double)(nCenterY/3)*cos(Radians)));
52.
53. Radians=(double)Time.GetMinute()+(double)Time.GetSecond()/60.0; //计算分针半径
54. Radians*=6.28/60.0;
55. CPen MinutePen(PS_SOLID,3,RGB(255,255,0)); //创建绘制分针的画笔
56. pdc->SelectObject(&MinutePen); //将该笔选设备描术述表
57. pdc->MoveTo(nCenterX,nCenterY); //绘制分针
58. pdc->LineTo(nCenterX+(int)((double)((nCenterX*2)/3)*sin(Radians)),
59. nCenterY-(int)((double)((nCenterY*2)/3)*cos(Radians)));
60.
61. Radians=(double)Time.GetSecond(); //计算秒针半径
62. Radians*=6.28/60.0;
63. CPen SecondPen(PS_SOLID,1,RGB(0,255,255)); //创建绘制秒针的画笔
64. pdc->SelectObject(&SecondPen); //将该笔选入设备描述表
65. pdc->MoveTo(nCenterX,nCenterY); //绘制秒针
66. pdc->LineTo(nCenterX+(int)((double)((nCenterX*4)/5)*sin(Radians)),
67. nCenterY-(int)((double)((nCenterY*4)/5)*cos(Radians)));
68. pdc->SelectObject(pOldPen); //恢复设备描述表中的旧笔
69. }
70.}
voidCClockCtrl:
:
OnDraw(CDC*pdc,constCRect&rcBounds,constCRect&rcInvalid)
{
//TODO:
Replacethefollowingcodewithyourowndrawingcode.
//pdc->FillRect(rcBounds,CBrush:
:
FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
//pdc->Ellipse(rcBounds);
CRectRect;
:
:
GetClientRect(this->m_hWnd,&Rect);
intnCenterX=Rect.right/2;
intnCenterY=Rect.bottom/2;
pdc->SetTextColor(TranslateColor(GetForeColor()));
pdc->SetBkMode(TRANSPARENT);//将控件背景颜色设置为透明方式
//建立一具刷子,该画刷的颜色为背景所设置的颜色
CBrush*pBrush=newCBrush(TranslateColor(GetBackColor()));
pdc->FillRect(&Rect,pBrush);
deletepBrush;
CFont*pOldFont;
pOl
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 时钟 控件 鼠标 事件
![提示](https://static.bingdoc.com/images/bang_tan.gif)