日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VS2010/MFC编程入门之五十(图形图像:GDI对象之画笔CPen)

發(fā)布時間:2024/10/12 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VS2010/MFC编程入门之五十(图形图像:GDI对象之画笔CPen) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

上一節(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?/*=NULL*/) ??
  • ????:?CDialogEx(CExample50Dlg::IDD,?pParent) ??
  • { ??
  • ????m_hIcon?=?AfxGetApp()->LoadIcon(IDR_MAINFRAME); ??
  • ??
  • ????//?將數(shù)組m_nzValues的元素都初始化為0???
  • ????memset(m_nzValues,?0,?sizeof(int)?*?POINT_COUNT); ??
  • }??
  • ???????7、在CExample50Dlg對話框的初始化成員函數(shù)CExample50Dlg::OnInitDialog()中,構造隨機數(shù)生成器,并啟動定時器。CExample50Dlg::OnInitDialog()修改如下:

    C++代碼
  • BOOL?CExample50Dlg::OnInitDialog() ??
  • { ??
  • ????CDialogEx::OnInitDialog(); ??
  • ??
  • ????//?Add?"About..."?menu?item?to?system?menu.???
  • ??
  • ????//?IDM_ABOUTBOX?must?be?in?the?system?command?range.???
  • ????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); ??
  • ????????} ??
  • ????} ??
  • ??
  • ????//?Set?the?icon?for?this?dialog.??The?framework?does?this?automatically???
  • ????//??when?the?application's?main?window?is?not?a?dialog???
  • ????SetIcon(m_hIcon,?TRUE);?????????//?Set?big?icon???
  • ????SetIcon(m_hIcon,?FALSE);????????//?Set?small?icon???
  • ??
  • ????//?TODO:?Add?extra?initialization?here???
  • ??
  • ????//?以時間為種子來構造隨機數(shù)生成器???
  • ????srand((unsigned)time(NULL)); ??
  • ??
  • ????//?啟動定時器,ID為1,定時時間為200ms???
  • ????SetTimer(1,?200,?NULL); ??
  • ??
  • ????return?TRUE;??//?return?TRUE??unless?you?set?the?focus?to?a?control???
  • }??
  • ?????? 8、為CExample50Dlg類添加波形繪制的成員函數(shù)CExample50Dlg::DrawWave(CDC *pDC, CRect &rectPicture),參數(shù)分別為設備上下文指針和繪圖的矩形區(qū)域。

    C++代碼
  • void?CExample50Dlg::DrawWave(CDC?*pDC,?CRect?&rectPicture) ??
  • { ??
  • ????float?fDeltaX;?????//?x軸相鄰兩個繪圖點的坐標距離???
  • ????float?fDeltaY;?????//?y軸每個邏輯單位對應的坐標值???
  • ????int?nX;??????//?在連線時用于存儲繪圖點的橫坐標???
  • ????int?nY;??????//?在連線時用于存儲繪圖點的縱坐標???
  • ????CPen?newPen;???????//?用于創(chuàng)建新畫筆???
  • ????CPen?*pOldPen;?????//?用于存放舊畫筆???
  • ????CBrush?newBrush;???//?用于創(chuàng)建新畫刷???
  • ????CBrush?*pOldBrush;?//?用于存放舊畫刷???
  • ??
  • ????//?計算fDeltaX和fDeltaY???
  • ????fDeltaX?=?(float)rectPicture.Width()?/?(POINT_COUNT?-?1); ??
  • ????fDeltaY?=?(float)rectPicture.Height()?/?80; ??
  • ??
  • ????//?創(chuàng)建黑色新畫刷???
  • ????newBrush.CreateSolidBrush(RGB(0,0,0)); ??
  • ????//?選擇新畫刷,并將舊畫刷的指針保存到pOldBrush???
  • ????pOldBrush?=?pDC->SelectObject(&newBrush); ??
  • ????//?以黑色畫刷為繪圖控件填充黑色,形成黑色背景???
  • ????pDC->Rectangle(rectPicture); ??
  • ????//?恢復舊畫刷???
  • ????pDC->SelectObject(pOldBrush); ??
  • ????//?刪除新畫刷???
  • ????newBrush.DeleteObject(); ??
  • ??
  • ????//?創(chuàng)建實心畫筆,粗度為1,顏色為綠色???
  • ????newPen.CreatePen(PS_SOLID,?1,?RGB(0,255,0)); ??
  • ????//?選擇新畫筆,并將舊畫筆的指針保存到pOldPen???
  • ????pOldPen?=?pDC->SelectObject(&newPen); ??
  • ??
  • ????//?將當前點移動到繪圖控件窗口的左下角,以此為波形的起始點???
  • ????pDC->MoveTo(rectPicture.left,?rectPicture.bottom); ??
  • ????//?計算m_nzValues數(shù)組中每個點對應的坐標位置,并依次連接,最終形成曲線???
  • ????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) ??
  • { ??
  • ????//?TODO:?Add?your?message?handler?code?here?and/or?call?default???
  • ????CRect?rectPicture; ??
  • ??
  • ????//?將數(shù)組中的所有元素前移一個單位,第一個元素丟棄???
  • ????for?(int?i=0;?i<POINT_COUNT-1;?i++) ??
  • ????{ ??
  • ????????m_nzValues[i]?=?m_nzValues[i+1]; ??
  • ????} ??
  • ????//?為最后一個元素賦一個80以內的隨機數(shù)值(整型)???
  • ????m_nzValues[POINT_COUNT-1]?=?rand()?%?80; ??
  • ??
  • ????//?獲取繪圖控件的客戶區(qū)坐標???
  • ????//?(客戶區(qū)坐標以窗口的左上角為原點,這區(qū)別于以屏幕左上角為原點的屏幕坐標)???
  • ????m_picDraw.GetClientRect(&rectPicture); ??
  • ??
  • ????//?繪制波形圖???
  • ????DrawWave(m_picDraw.GetDC(),?rectPicture); ??
  • ??
  • ????CDialogEx::OnTimer(nIDEvent); ??
  • }??
  • ?????? 10、在對話框銷毀時,定時器應關閉。所以為CExample50Dlg類添加WM_DESTROY消息的處理函數(shù),并修改如下:

    C++代碼
  • void?CExample50Dlg::OnDestroy() ??
  • { ??
  • ????CDialogEx::OnDestroy(); ??
  • ??
  • ????//?TODO:?Add?your?message?handler?code?here???
  • ??
  • ????//?關閉定時器???
  • ????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)站內容還不錯,歡迎將生活随笔推薦給好友。