上一節(jié)中雞啄米講了CDC類及其屏幕繪圖函數(shù),本節(jié)的主要內容是GDI對象之畫筆CPen。
???????GDI對象
???????在MFC中,CGdiObject類是GDI對象的基類,通過查閱MSDN我們可以看到,CGdiObject類有六個直接的派生類,GDI對象主要也是這六個,分別是:CBitmap、CBrush、CFont、CPalette、CPen和CRgn。
???????在這六個GDI對象中,最常用的莫過于畫筆和畫刷了,即CPen類和CBrush類。本文就主要講解畫筆的使用。
???????畫筆的應用實例
?????? 雞啄米在這里直接通過一個波形圖的實例,來詳細講解畫筆的使用方法。
?????? 首先介紹此實例要實現(xiàn)的功能:在對話框上有一個Picture控件,將此控件的背景填充為黑色;啟動一個定時器,每次定時器到時,所有波形數(shù)據(jù)都前移一個單位,并獲取一個80以內的隨機數(shù)作為波形的最后一個數(shù)據(jù),然后以綠色畫筆在繪圖控件上繪制波形。這樣就實現(xiàn)了波形的繪制及動態(tài)變化。
???????下面是具體實施步驟:
?????? 1、創(chuàng)建一個基于對話框的MFC工程,名字設為“Example50”。
?????? 2、在自動生成的對話框模板IDD_EXAMPLE50_DIALOG中,刪除“TODO: Place dialog controls here.”靜態(tài)文本框,添加一個Picture控件,ID設為IDC_WAVE_DRAW。?
?????? 3、為Picture控件IDC_WAVE_DRAW添加CStatic變量,名稱設為m_picDraw。
?????? 4、在文件Example50Dlg.h文件中CExample50Dlg類聲明的上面添加宏定義:
C++代碼
#define?POINT_COUNT?100?? ???????此符號常量的意義是波形的點數(shù),這里用define將其定義為符號常量是為了方便以后可能的修改,假如我們以后想將點數(shù)改為200,則只改此宏定義就可以了:#define POINT_COUNT 200,而如果沒有使用符號常量,在程序中直接使用了100,那么就需要將所有使用100的位置找出來,并替換為200,這樣不僅麻煩也很容易出錯,所以最好是將其定義為符號常量。
?????? 5、在CExample50Dlg.h文件中為CExample50Dlg類添加成員數(shù)組:
C++代碼
int???m_nzValues[POINT_COUNT];?? ???????此數(shù)組用于存放波形數(shù)據(jù)。
?????? 6、在CExample50Dlg類的構造函數(shù)中為數(shù)組m_nzValues的元素賦初值:
C++代碼
CExample50Dlg::CExample50Dlg(CWnd*?pParent?????:?CDialogEx(CExample50Dlg::IDD,?pParent) ??{ ??????m_hIcon?=?AfxGetApp()->LoadIcon(IDR_MAINFRAME); ????????????memset(m_nzValues,?0,?sizeof(int)?*?POINT_COUNT); ??}?? ???????7、在CExample50Dlg對話框的初始化成員函數(shù)CExample50Dlg::OnInitDialog()中,構造隨機數(shù)生成器,并啟動定時器。CExample50Dlg::OnInitDialog()修改如下:
C++代碼
BOOL?CExample50Dlg::OnInitDialog() ??{ ??????CDialogEx::OnInitDialog(); ??????????????????ASSERT((IDM_ABOUTBOX?&?0xFFF0)?==?IDM_ABOUTBOX); ??????ASSERT(IDM_ABOUTBOX?<?0xF000); ????????CMenu*?pSysMenu?=?GetSystemMenu(FALSE); ??????if?(pSysMenu?!=?NULL) ??????{ ??????????BOOL?bNameValid; ??????????CString?strAboutMenu; ??????????bNameValid?=?strAboutMenu.LoadString(IDS_ABOUTBOX); ??????????ASSERT(bNameValid); ??????????if?(!strAboutMenu.IsEmpty()) ??????????{ ??????????????pSysMenu->AppendMenu(MF_SEPARATOR); ??????????????pSysMenu->AppendMenu(MF_STRING,?IDM_ABOUTBOX,?strAboutMenu); ??????????} ??????} ????????????????SetIcon(m_hIcon,?TRUE);?????????????SetIcon(m_hIcon,?FALSE);????????????????????????srand((unsigned)time(NULL)); ????????????SetTimer(1,?200,?NULL); ????????return?TRUE;??}?? ?????? 8、為CExample50Dlg類添加波形繪制的成員函數(shù)CExample50Dlg::DrawWave(CDC *pDC, CRect &rectPicture),參數(shù)分別為設備上下文指針和繪圖的矩形區(qū)域。
C++代碼
void?CExample50Dlg::DrawWave(CDC?*pDC,?CRect?&rectPicture) ??{ ??????float?fDeltaX;?????????float?fDeltaY;?????????int?nX;??????????int?nY;??????????CPen?newPen;???????????CPen?*pOldPen;?????????CBrush?newBrush;???????CBrush?*pOldBrush;???????????fDeltaX?=?(float)rectPicture.Width()?/?(POINT_COUNT?-?1); ??????fDeltaY?=?(float)rectPicture.Height()?/?80; ????????????newBrush.CreateSolidBrush(RGB(0,0,0)); ??????????pOldBrush?=?pDC->SelectObject(&newBrush); ??????????pDC->Rectangle(rectPicture); ??????????pDC->SelectObject(pOldBrush); ??????????newBrush.DeleteObject(); ????????????newPen.CreatePen(PS_SOLID,?1,?RGB(0,255,0)); ??????????pOldPen?=?pDC->SelectObject(&newPen); ????????????pDC->MoveTo(rectPicture.left,?rectPicture.bottom); ??????????for?(int?i=0;?i<POINT_COUNT;?i++) ??????{ ??????????nX?=?rectPicture.left?+?(int)(i?*?fDeltaX); ??????????nY?=?rectPicture.bottom?-?(int)(m_nzValues[i]?*?fDeltaY); ??????????pDC->LineTo(nX,?nY); ??????} ????????????pDC->SelectObject(pOldPen); ??????????newPen.DeleteObject(); ??}?? ?????? 9、有了定時器和繪圖成員函數(shù),我們就可以在WM_TIMER消息的響應函數(shù)中添加對波形數(shù)據(jù)的定時處理和對波形的定時繪制了。定時器及WM_TIMER消息處理函數(shù)的添加方法如果忘記了,可以再到VS2010/MFC編程入門之四十四(MFC常用類:定時器Timer)溫習下。
?????? WM_TIMER消息的處理函數(shù)修改如下:
C++代碼
void?CExample50Dlg::OnTimer(UINT_PTR?nIDEvent) ??{ ??????????CRect?rectPicture; ????????????for?(int?i=0;?i<POINT_COUNT-1;?i++) ??????{ ??????????m_nzValues[i]?=?m_nzValues[i+1]; ??????} ??????????m_nzValues[POINT_COUNT-1]?=?rand()?%?80; ????????????????m_picDraw.GetClientRect(&rectPicture); ????????????DrawWave(m_picDraw.GetDC(),?rectPicture); ????????CDialogEx::OnTimer(nIDEvent); ??}?? ?????? 10、在對話框銷毀時,定時器應關閉。所以為CExample50Dlg類添加WM_DESTROY消息的處理函數(shù),并修改如下:
C++代碼
void?CExample50Dlg::OnDestroy() ??{ ??????CDialogEx::OnDestroy(); ??????????????????KillTimer(1); ??}?? ???????11、一切準備就緒,編譯運行。最終的效果如下圖:
?????? 關于畫筆,雞啄米就講到這里了,下一節(jié)將為大家簡單講講畫刷的使用。謝謝大家的關注!
轉自:http://www.jizhuomi.com/software/181.html
轉載于:https://www.cnblogs.com/gd-luojialin/p/9650099.html
總結
以上是生活随笔為你收集整理的VS2010/MFC编程入门之五十(图形图像:GDI对象之画笔CPen)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。