mfc時鐘制作實例課件_第1頁
mfc時鐘制作實例課件_第2頁
mfc時鐘制作實例課件_第3頁
mfc時鐘制作實例課件_第4頁
mfc時鐘制作實例課件_第5頁
已閱讀5頁,還剩41頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

試驗三

面向對象程序設計實驗——一個簡單的可復用時鐘控件1精選課件本實驗的開發(fā)環(huán)境使用C++語言實現(xiàn)使用VC++6.0集成開發(fā)環(huán)境開發(fā)使用MFC應用程序開發(fā)框架2精選課件MFC版本簡介MFC全稱MicrosoftFoundationClasses.1989年微軟公司成立ApplicationFramework技術團隊,開發(fā)C++面向對象工具給Windows應用程序開發(fā)人員使用。這個小組即AFX小組,就是他們,開始了MFC的開發(fā)歷程。微軟公司于1992年4月推出C/C++7.0產(chǎn)品時,初次向世人介紹了MFC1.0,其32位版本也在1992年7月隨著Win32SDK推出。VisualC++1.0(也就是C/C++8.0)搭配MFC2.0于1993年3月推出。同年8月推出在WindowsNT上的VisualC++1.1forWindowsNT,搭配的是MFC2.1。3精選課件微軟在1993年12月又推出了16為的VisualC++1.5,搭配的是MFC2.5。1994年9月,微軟推出VisualC++2.0,搭配MFC3.0。1995年1月,微軟推在增加了MAPI和WinSock支持的基礎上,推出MFC3.1。1995年7月,MFC有了3.2版,這是一個小的改版。然后就是1995年9月的32位版MFC4.0。這個版本有了相當大的改進。1996年上半年又有了MFC4.1……時至今日MFC在VisualC++7.0中已經(jīng)到了7.0版本。我們常用的VisualC++6.0使用的是MFC4.2版本。微軟正不斷地為“為什么要使用MFC”加上各式各樣地強烈你有,并強烈導引它成為Windows程序設計的C++標準界面。正如我們所看到的,越來越多的MFC程序出現(xiàn)了并繼續(xù)在產(chǎn)生。4精選課件試驗設計目標完成一個可重用的C++類,可以通過該類實現(xiàn)一個簡單的模擬時鐘編寫一個簡單的MFC程序測試驗證這個時鐘控件類關于這個時鐘控件,如果按照課件繼續(xù)完善下去,請將他做得更好更強大。比如說:可以考慮為時鐘控件的各項設置(如顏色)提供外部接口,供CClockEx的使用者調(diào)用,可以考慮豐富背景繪制,加入背景圖片設置,在刻度上標上數(shù)字,為指針加上陰影效果,在時鐘上顯示日期等。有興趣的同學有空不妨試試。5精選課件應用程序框架設計過程(僅供參考)打開VC++6.0,新建一個MFC工程,輸入工程名,選擇“MFCAppWizard”如圖所示,然后點擊OK。6精選課件為簡單起見,這里選擇“Dialogbased”程序,然后可以直接選擇finish了。7精選課件在類視圖的工程名上右鍵單擊,選擇NewClass(如下圖所示)來建立一個新類。8精選課件我們可以從CStatic類(靜態(tài)控件類)派生出類CClockEx來實現(xiàn)時鐘控件類,這樣,就可以繼承MFC靜態(tài)控件的很多已經(jīng)具備的功能和特點。在建立新類的對話框中,按下圖輸入。9精選課件按Ctrl+W調(diào)出ClassWizard,在classname中選擇剛才建立的新類CClockEx,然后重載虛函數(shù)PreSubClassWindow,對時鐘控件的基本初始化工作將在該函數(shù)中進行。添加消息響應WM_PAINT,我們必須用自己完成時鐘的繪制工作。添加消息響應WM_SIZE,重載該消息響應以便我們的時鐘控件能夠自動適應其大小的變化。為了時鐘能夠走動,我們得定時刷新時鐘控件讓它走動,還得添加WM_TIMER的消息響應。最終效果如下圖所示。10精選課件到目前為止,時鐘控件的輪廓和已經(jīng)有了,下面考慮時鐘繪制的具體實現(xiàn)。一個時鐘大致可由時鐘背景、時針、分針、秒針四個部分構成。以上的時鐘四個部分可是看作四個不同的對象,可以考慮建立類CClockBackground(背景)CClockHourHand(時針)、CClockMinHand(分針)、CClockSecHand(秒針)來分別實現(xiàn)。(此處為了意義明確,類名都比較長)這四個類有它們的共同點,譬如都有自己的繪圖函數(shù),如果要具體能夠設置顏色,它們都應該有自己的繪圖顏色,同樣應該有顏色設置函數(shù),此外都有繪圖區(qū)域和區(qū)域設置函數(shù)等等。因此,可以為它們的共性建立一個基類,此處命名為CClockElement(時鐘元素)。11精選課件下面逐步實現(xiàn)各個類,首先實現(xiàn)各個組成類的基類——CClockElement。同樣,在ClassView的工程名上面點右鍵,選擇NewClass,在ClassType里面選擇GenenricClass,類CClockElement不需要從其它類派生,所以BaseClass可以不填,效果如下圖所示。12精選課件下面對類CClockElement的源代碼進行編寫。因為在后面的繪圖中需要用到sin和cos這兩個數(shù)學計算公式,因此需包含頭文件<MATH.H>以便使用數(shù)學函數(shù)庫。為后面計算使用,還需定義數(shù)學常量PI(3.1415926535)。時鐘的每個組成部分都有繪圖區(qū)域區(qū)域,因此,可在基類中定義繪圖區(qū)域變量。同理,可以定義顏色變量,為了是顏色不顯得單調(diào),這里為每個控件設置兩種顏色(如果想使程序更加絢麗,可以設置更多顏色)。對應的,這些變量需增加接口函數(shù)來進行訪問。對于每個組成部分都應該有的Draw函數(shù),當然也需在基類中定義,但是,該函數(shù)對于基類來說是無需函數(shù)實現(xiàn)的,因此可定義為純虛函數(shù)。13精選課件綜合剛才這幾點,CClockElement的實現(xiàn)的頭文件代碼如下:#include<MATH.H>#definePI3.1415926535classCClockElement{public: voidSetColor(COLORREFcrMain,COLORREFcrOther); //設置顏色 voidSetTime(constCTime&tmCur); //設置當前時間 voidSetRegion(LPRECTlprcRect); //設置繪圖區(qū)域 virtualvoidDraw(CDC*pDC)=0; //繪圖函數(shù) CClockElement(); virtual~CClockElement();protected: COLORREF m_crMain; //主要顏色 COLORREF m_crOther; //輔助的其他顏色 CTime m_tmCur; //當前時刻 CRect m_rcRegion; //繪圖區(qū)域 int m_nRadius; //時鐘半徑14精選課件CClockElement的實現(xiàn)的源文件關鍵代碼如下:CClockElement::CClockElement(){ m_nRadius=0; m_crMain=RGB(255,255,255); m_crOther=RGB(128,128,128);}CClockElement::~CClockElement(){}voidCClockElement::SetRegion(LPRECTlprcRect){ m_rcRegion=lprcRect; m_nRadius=m_rcRegion.Width()/2; if(m_rcRegion.Width()>m_rcRegion.Height()) { m_nRadius=m_rcRegion.Height()/2; }}15精選課件續(xù)上頁:voidCClockElement::SetTime(constCTime&tmCur){ m_tmCur=tmCur;}voidCClockElement::SetColor(COLORREFcrMain,COLORREFcrOther){ m_crMain=crMain; m_crOther=crOther;}16精選課件下面實現(xiàn)時鐘背景類——CClockBackground。同樣,在ClassView的工程名上面點右鍵,選擇NewClass,在ClassType里面選擇GenenricClass,類CClockBackground需要從類CClockElement派生,所以BaseClass需選擇類CClockElement,效果如下圖所示。17精選課件CClockBackground只需實現(xiàn)基類的虛函數(shù)Draw即可,因此這里重載基類的虛函數(shù)Draw,其頭文件實現(xiàn)代碼如下:#include"ClockElement.h"classCClockBackground:publicCClockElement{public: CClockBackground(); virtual~CClockBackground();};18精選課件CClockBackground源文件代碼如下:CClockBackground::CClockBackground(){ //為時鐘背景定義默認的顏色設置 m_crMain=RGB(0,255,0); m_crOther=RGB(0,128,0);}CClockBackground::~CClockBackground(){}voidCClockBackground::Draw(CDC*pDC){ //準備設備環(huán)境 CPenpenMain(PS_SOLID,1,m_crMain),penOther(PS_SOLID,1,m_crOther); CBrushbrMain(m_crMain),brOther(m_crOther); CPen*pOldPen=pDC->SelectObject(&penOther); CBrush*pOldBrush=pDC->SelectObject(&brMain);19精選課件CClockBackground源文件代碼如下(續(xù)上頁)://繪制60個小圓點,表示分針和秒針的刻度

CPointptCenter=m_rcRegion.CenterPoint(); intnRadius=m_nRadius-8; for(inti=0;i<60;i++) { CPointptEnd=ptCenter; ptEnd.Offset((int)(nRadius*sin(2*PI*(i%60)/60)), (int)(-nRadius*cos(2*PI*(i%60)/60))); CRectrcDot(-2,-2,2,2); rcDot.OffsetRect(ptEnd); pDC->Ellipse(rcDot); } //繪制12個小方框,表示12個正點 pDC->SelectObject(&penMain); pOldBrush=pDC->SelectObject(&brOther); for(i=0;i<12;i++) { CPointptEnd=ptCenter; doublefRadian=2*PI*(i%12)/12; ptEnd.Offset((int)(nRadius*sin(fRadian)), (int)(-nRadius*cos(fRadian))); CRectrcDot(-3,-3,3,3); rcDot.OffsetRect(ptEnd); pDC->Rectangle(rcDot); } //還原設備環(huán)境 pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush);}20精選課件下面實現(xiàn)時針類CClockHourHand,該類新建的過程與CClockBackground一樣,CClockHourHand同樣只需實現(xiàn)基類的虛函數(shù)Draw即可,其頭文件實現(xiàn)代碼如下:#include"ClockElement.h"classCClockHourHand:publicCClockElement{public: CClockHourHand(); virtual~CClockHourHand(); virtualvoidDraw(CDC*pDC);};21精選課件CClockHourHand源文件代碼如下:CClockHourHand::CClockHourHand(){ //定義默認顏色 m_crMain=RGB(0,255,100); m_crOther=RGB(128,128,0);}CClockHourHand::~CClockHourHand(){}voidCClockHourHand::Draw(CDC*pDC){ //初始化設備環(huán)境 CPenpenMain(PS_SOLID,1,m_crMain),penOther(PS_SOLID,1,m_crOther); CBrushbrMain(m_crMain),brOther(m_crOther); CPen*pOldPen=pDC->SelectObject(&penOther); CBrush*pOldBrush=pDC->SelectObject(&brMain); //確定當前指針的弧度 intnTime=(m_tmCur.GetHour()%12)*3600; nTime+=m_tmCur.GetMinute()*60; nTime+=m_tmCur.GetSecond(); doublefRadian=2*PI*nTime/3600/12;22精選課件CClockHourHand源文件代碼如下(續(xù)上頁):

//確定繪制菱形指針所需的四個角的坐標 CPointptDiamond[4]; for(inti=0;i<4;i++) { ptDiamond[i]=m_rcRegion.CenterPoint(); } intnRadus=m_nRadius/2; ptDiamond[0].Offset((int)(nRadus*sin(fRadian)),(int)(-nRadus*cos(fRadian))); fRadian+=0.5*PI; nRadus=m_nRadius/20; ptDiamond[1].Offset((int)(nRadus*sin(fRadian)),(int)(-nRadus*cos(fRadian))); fRadian+=0.5*PI; nRadus=m_nRadius/10; ptDiamond[2].Offset((int)(nRadus*sin(fRadian)),(int)(-nRadus*cos(fRadian))); fRadian+=0.5*PI; nRadus=m_nRadius/20; ptDiamond[3].Offset((int)(nRadus*sin(fRadian)),(int)(-nRadus*cos(fRadian)));23精選課件CClockHourHand源文件代碼如下(續(xù)上頁):

//繪制菱形時針 pDC->Polygon(ptDiamond,4); //恢復設備環(huán)境 pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush);24精選課件下面實現(xiàn)分針類CClockMinHand,該類新建的過程與CClockHourHand一樣,類的實現(xiàn)也基本相似,其頭文件實現(xiàn)代碼如下:#include"ClockElement.h"classCClockMinHand:publicCClockElement{public: CClockMinHand(); virtual~CClockMinHand(); virtualvoidDraw(CDC*pDC);};25精選課件CClockMinHand源文件代碼如下:CClockMinHand::CClockMinHand(){ //定義默認顏色 m_crMain=RGB(0,255,100); m_crOther=RGB(128,128,0);}CClockMinHand::~CClockMinHand(){}voidCClockMinHand::Draw(CDC*pDC){ //初始化設備環(huán)境 CPenpenMain(PS_SOLID,1,m_crMain),penOther(PS_SOLID,1,m_crOther); CBrushbrMain(m_crMain),brOther(m_crOther); CPen*pOldPen=pDC->SelectObject(&penOther); CBrush*pOldBrush=pDC->SelectObject(&brMain); //確定分針所在位置的弧度 intnTime=m_tmCur.GetMinute()*60; nTime+=m_tmCur.GetSecond(); doublefRadian=2*PI*nTime/3600;26精選課件CClockMinHand源文件代碼如下(續(xù)上頁): //確定繪制菱形指針所需的四個角的坐標 CPointptDiamond[4]; for(inti=0;i<4;i++) { ptDiamond[i]=m_rcRegion.CenterPoint(); } intnRadus=m_nRadius/2; ptDiamond[0].Offset((int)(nRadus*sin(fRadian)),(int)(-nRadus*cos(fRadian))); fRadian+=0.5*PI; nRadus=m_nRadius/20; ptDiamond[1].Offset((int)(nRadus*sin(fRadian)),(int)(-nRadus*cos(fRadian))); fRadian+=0.5*PI; nRadus=m_nRadius/10; ptDiamond[2].Offset((int)(nRadus*sin(fRadian)),(int)(-nRadus*cos(fRadian))); fRadian+=0.5*PI; nRadus=m_nRadius/20; ptDiamond[3].Offset((int)(nRadus*sin(fRadian)),(int)(-nRadus*cos(fRadian)));27精選課件CClockMinHand源文件代碼如下(續(xù)上頁):

//繪制菱形分針 pDC->Polygon(ptDiamond,4); //恢復設備環(huán)境 pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush);28精選課件下面實現(xiàn)秒針類CClockSecHand,該類新建的過程與CClockHourHand一樣,類的實現(xiàn)也基本相似,其頭文件實現(xiàn)代碼如下:#include"ClockElement.h"classCClockSecHand:publicCClockElement{public: CClockSecHand(); virtual~CClockSecHand(); virtualvoidDraw(CDC*pDC);};29精選課件CClockSecHand源文件代碼如下:CClockSecHand::CClockSecHand(){ //設定秒針的默認顏色 m_crMain=RGB(0,200,200); m_crOther=RGB(0,200,200);}CClockSecHand::~CClockSecHand(){}voidCClockSecHand::Draw(CDC*pDC){ intnTime=m_tmCur.GetSecond(); CPointptStart=m_rcRegion.CenterPoint(); CPointptEnd=ptStart; intnRadius=m_nRadius-10; ptEnd.Offset((int)(nRadius*sin(2*PI*nTime/60)), (int)(-nRadius*cos(2*PI*nTime/60))); CPenpenMain(PS_SOLID,1,m_crMain); CPen*pOldPen=pDC->SelectObject(&penMain); pDC->MoveTo(ptStart); pDC->LineTo(ptEnd); pDC->SelectObject(pOldPen);}30精選課件到目前為止,時鐘的各個部件都已經(jīng)設計完畢,現(xiàn)在該把它們組裝起來了。剛才建立的四個類CClockBackground、CClockHourHand、CClockMinHand、CClockSecHand要為CClockEx服務,正如CClockElement為它們服務一樣,不過服務的方式發(fā)生了變化,剛才是以繼承的方式使用,現(xiàn)在需要將上面四個類實例化供CClockEx使用。因此,首先應該在類CClockEx為上四個類分別建立對象。在CClockEx的頭文件中恰當位置加入以下代碼:#include"ClockBackground.h"#include"ClockHourHand.h"#include"ClockMinHand.h"#include"ClockSecHand.h"classCClockEx:publicCStatic{private: CClockBackground m_clockBK; //時鐘背景 CClockHourHand m_clockHour; //時指針 CClockMinHand m_clockMin; //分指針 CClockSecHand m_clockSec; //秒指針31精選課件為了存儲繪圖區(qū)域的大小,需要在CClockEx中加入一個變量m_rcClient:CRect m_rcClient; //客戶區(qū)域在PreSubclassWindow函數(shù)中進行時鐘的初始化工作。首先得為各個部件設定區(qū)域大小,然后啟動定時刷新的定時器(100毫秒的定時器已經(jīng)足夠)。由于每個部件都有自己的默認顏色配置,因此這里暫且先使用默認配置,當然也可以自定義顏色: GetClientRect(m_rcClient);//獲取當前客戶區(qū)域 m_clockBK.SetRegion(m_rcClient); m_clockHour.SetRegion(m_rcClient); m_clockMin.SetRegion(m_rcClient); m_clockSec.SetRegion(m_rcClient); SetTimer(1,100,NULL); //每100毫秒刷新一次32精選課件當控件大小發(fā)生變化時,控件狀態(tài)要能夠自動更新:voidCClockEx::OnSize(UINTnType,intcx,intcy){ CStatic::OnSize(nType,cx,cy);

GetClientRect(m_rcClient); m_clockBK.SetRegion(m_rcClient); m_clockHour.SetRegion(m_rcClient); m_clockMin.SetRegion(m_rcClient); m_clockSec.SetRegion(m_rcClient);}每個定時器時間觸發(fā)時,需要刷新控件以保證時鐘的走動:voidCClockEx::OnTimer(UINTnIDEvent){ Invalidate(FALSE);

CStatic::OnTimer(nIDEvent);}33精選課件下面實現(xiàn)時鐘的繪制,由于控件在不斷刷新,按一般方式繪圖,屏幕會不斷閃爍,因此此處使用雙緩沖繪圖——就是在內(nèi)存中繪圖,繪制完畢時在Copy到屏幕上,這樣可以有效的防止屏幕閃爍:voidCClockEx::OnPaint(){ CPaintDCdc(this);//devicecontextforpainting //實現(xiàn)雙緩沖繪圖——防止屏幕閃爍 CDC dcMem; dcMem.CreateCompatibleDC(&dc); CBitmap bmp; bmp.CreateCompatibleBitmap(&dc,m_rcClient.Width(),m_rcClient.Height()); dcMem.SelectObject(&bmp); DrawClock(&dcMem); //繪制時鐘 dc.BitBlt(0,0,m_rcClient.Width(),m_rcClient.Height(),&dcMem,0,0,SRCCOPY);}34精選課件為了程序結構更清晰,我們將繪圖函數(shù)放在一個單獨的函數(shù)DrawClock中,下面室DrawClock的函數(shù)實現(xiàn):voidCClockEx::DrawClock(CDC*pDC){ CTimetmCur=CTime::GetCurrentTime(); m_clockBK.SetTime(tmCur); m_clockHour.SetTime(tmCur); m_clockMin.SetTime(tmCur); m_clockSec.SetTime(tmCur); m_clockBK.Draw(pDC); m_clockMin.Draw(pDC); m_clockHour.Draw(pDC); m_clockSec.Draw(pDC);}35精選課件下面是完整的CClockEx源碼:#if!defined(AFX_CLOCKEX_H__EB35C434_A727_43BE_B10E_121F6307EA73__INCLUDED_)#defineAFX_CLOCKEX_H__EB35C434_A727_43BE_B10E_121F6307EA73__INCLUDED_#if_MSC_VER>1000#pragmaonce#endif//_MSC_VER>1000//ClockEx.h:headerfile/////////////////////////////////////////////////////////////////////////////////CClockExwindow#include"ClockBackground.h"#include"ClockHourHand.h"#include"ClockMinHand.h"#include"ClockSecHand.h"classCClockEx:publicCStatic{private: CRect m_rcClient; //客戶區(qū)域 CClockBackground m_clockBK; //時鐘背景 CClockHourHand m_clockHour; //時指針 CClockMinHand m_clockMin; //分指針 CClockSecHand m_clockSec; //秒指針 voidDrawClock(CDC*pDC);//Constructionpublic: CClockEx();36精選課件下面是完整的CClockEx源碼(續(xù)上頁)://Attributespublic://Operationspublic://Overrides //ClassWizardgeneratedvirtualfunctionoverrides //{{AFX_VIRTUAL(CClockEx) protected: virtualvoidPreSubclassWindow(); //}}AFX_VIRTUAL//Implementationpublic: virtual~CClockEx(); //Generatedmessagemapfunctionsprotected: //{{AFX_MSG(CClockEx) afx_msgvoidOnPaint(); afx_msgvoidOnSize(UINTnType,intcx,intcy); afx_msgvoidOnTimer(UINTnIDEvent); //}}AFX_MSG DECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}//MicrosoftVisualC++willinsertadditionaldeclarationsimmediatelybeforethepreviousline.#endif//!defined(AFX_CLOCKEX_H__EB35C434_A727_43BE_B10E_121F6307EA73__INCLUDED_)37精選課件下面是完整的CClockEx源碼(續(xù)上頁)://ClockEx.cpp:implementationfile#include"stdafx.h"#include"ClockProject.h"#include"ClockEx.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif////////////////////////////////////////////////////////////////////////CClockExCClockEx::CClockEx(){}CClockEx::~CClockEx(){}BEGIN_MESSAGE_MAP(CClockEx,CStatic) //{{AFX_MSG_MAP(CClockEx) ON_WM_SIZE() ON_WM_PAINT() ON_WM_TIMER() //}}AFX_MSG_MAPEND_MESSAGE_MAP()38精選課件下面是完整的CClockEx源碼(續(xù)上頁)://////////////////////////////////////////////////////////////////////////CClockExmessagehandlersvoidCClockEx::PreSubclassWindow(){ //獲取當前客戶區(qū)域 GetClientRect(m_rcClient); m_clockBK.SetRegion(m_rcClient); m_clockHour.SetRegion(m_rcClient); m_clockMin.SetRegion(m_rcClient); m_clockSec.SetRegion(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論