計算機圖形學課程】二.MFC鼠標響應函數模擬畫圖軟件

      網友投稿 1335 2022-05-28

      上一篇文章我們講述MFC繪制圖形的基本函數,包括繪制直線、繪制矩形、繪制橢圓及繪制文字,同時通過繞圓旋轉和矩形平移簡單的理解了圖形學知識。這篇文章我將介紹鼠標響應和鍵盤響應,通過這些事件讓學生實現一個類似畫圖的簡單軟件,同時充分發揮學生想象,自己創作東西。

      前文:

      【計算機圖形學課程】一.MFC基本繪圖函數使用方法

      一. MFC工程創建及鼠標響應

      新建一個MFC 單文檔的應用程序"MousePic"。

      然后,選擇"View(視圖)"->"建立類向導",快鍵鍵是Ctrl+W。這是MFC非常重要的一個知識點,對話框或單文檔設置按鈕操作、響應函數都是通過該操作實現。

      【計算機圖形學課程】二.MFC鼠標響應函數模擬畫圖軟件

      鼠標常見消息響應:

      WM_LBUTTONDBCLK 雙擊鼠標左鍵

      WM_LBUTTONDOWN 按下鼠標左鍵

      WM_LBUTTONUP 釋放鼠標左鍵

      WM_MOUSEMOVE 在客戶區移動鼠標

      WM_RBUTTONDBCLK 雙擊鼠標右鍵

      WM_RBUTTONDOWN 按下鼠標右鍵

      WM_RBUTTONUP 釋放鼠標右鍵

      二. MFC實現鼠標響應操作

      1.鼠標左鍵按下

      雙擊函數會定位到"MousePicView.cpp"文件,現在可以對OnLButtonDown()函數進行編輯。其中CPoint point參數記錄當前鼠標左鍵按下的位置,nFlags表示掩碼。

      然后添加代碼如下:

      //定義一個點類型的變量,用來保存當用戶點擊界面時點擊的位置 CPoint m_point; //鼠標左鍵按下 void CMousePicView::OnLButtonDown(UINT nFlags, CPoint point) { //把當前點擊的點的位置賦給點m_point m_point = point; CView::OnLButtonDown(nFlags, point); }

      2.鼠標左鍵釋放

      通過同樣的方法在"類向導"中實現鼠標左鍵釋放函數,如下圖所示。

      添加代碼主要是鼠標釋放(彈起):

      //鼠標釋放:記錄當前坐標 void CMousePicView::OnLButtonUp(UINT nFlags, CPoint point) { //繪制圖形 CDC *p = GetDC(); p->MoveTo(m_point); //鼠標移動到左鍵按下點 p->LineTo(point); //繪制一條直線 終點為鼠標釋放點 CView::OnLButtonUp(nFlags, point); }

      此時鼠標繪制圖形如下所示,但是存在兩個問題:繪制過程中不可見、繪制結果只是直線。

      所以,需要借助鼠標移動函數實現,在鼠標移動過程中就進行繪制,同時引入bool類型的變量,判斷鼠標按下或釋放,按下的時候進行繪制操作。

      3.鼠標左鍵移動

      通過同樣的方法在"類向導"中實現鼠標左鍵釋放函數。

      完整代碼如下所示:

      //定義一個點類型的變量,用來保存當用戶點擊界面時點擊的位置 CPoint m_point; //定義布爾型變量 m_click=true表示鼠標點擊 false表示鼠標釋放 bool m_click; //鼠標左鍵按下 void CMousePicView::OnLButtonDown(UINT nFlags, CPoint point) { //把當前點擊的點的位置賦給點m_point m_point = point; m_click = true; CView::OnLButtonDown(nFlags, point); } //鼠標釋放:記錄當前坐標 void CMousePicView::OnLButtonUp(UINT nFlags, CPoint point) { //繪制圖形 /* CDC *p = GetDC(); p->MoveTo(m_point); //鼠標移動到左鍵按下點 p->LineTo(point); //繪制一條直線 終點為鼠標釋放點 */ m_click = false; CView::OnLButtonUp(nFlags, point); } //鼠標移動繪制圖形 void CMousePicView::OnMouseMove(UINT nFlags, CPoint point) { //定義畫筆并選擇 CDC *p=GetDC(); CPen pen(PS_SOLID, 4, RGB(255,0,0)); p->SelectObject(pen); //鼠標按下進行繪制 if(m_click==true) { p->MoveTo(m_point); p->LineTo(point); m_point = point; } CView::OnMouseMove(nFlags, point); }

      繪制結果如下所示,相當于一個簡單的畫圖軟件。

      4.補充知識

      如果在OnMouseMove()鼠標移動函數if判斷中缺少代碼m_point = point,它會出現意想不到的效果,因為你需要每次繪制,鼠標移動當前點坐標point都需要賦值給下次繪制的起始坐標,供p->MoveTo(m_point)使用。

      同時,你可以繪制圓形、矩形等相關形狀,不僅僅限定于直線。

      //鼠標移動繪制圖形 void CMousePicView::OnMouseMove(UINT nFlags, CPoint point) { //定義畫筆并選擇 CDC *p=GetDC(); CPen pen(PS_SOLID, 1, RGB(255,0,0)); p->SelectObject(pen); //鼠標按下進行繪制 if(m_click==true) { p->MoveTo(m_point); //p->LineTo(point); p->Rectangle(point.x, point.y,point.x+20, point.y+30); m_point = point; } CView::OnMouseMove(nFlags, point); }

      輸出如下所示:

      繪制中,定義了畫筆Pen,正確的方法需要在繪制完成后,進行釋放該畫筆。核心代碼如下:

      //定義畫筆繪制矩形 CPen MyPen, *OldPen; MyPen.CreatePen(PS_DASH, 2, RGB(0,0,255)); //虛線 粗2 藍色 OldPen = pDC->SelectObject(&MyPen); //舊畫筆賦值 //繪制圖形 //清除 pDC->SelectObject(OldPen); MyPen.DeleteObject();

      三. MFC鍵盤響應函數

      1.基礎知識

      Windows對每個按鍵定義了與設備無關的編碼,這種編碼叫做虛擬碼。有了這個虛擬碼,Windwos程序員可以使用該虛擬碼進行編程。其中鍵盤上部分按鍵的虛擬碼如下圖所示:

      Windows按鍵消息常見如下:

      WM_CHAR 敲擊鍵盤上的字符鍵時,產生該消息

      WM_KEYDOWN 任意鍵(包括字符鍵)被按下時都產生該消息,如果被按下的是字符鍵,在產生消息的同時還產生字符消息

      WM_KEYUP 任意角(包括字符鍵)被釋放都產生該消息

      WM_SYSKEYDOWN F10被按下或者Alt與另一個鍵被同時按下

      WM_SYSKEYUP F10被釋放或者Alt與另一個鍵被同時釋放

      2.按鍵響應操作

      同樣,通過類向導建立按鍵按下函數。

      //鼠標按鍵 void CMousePicView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CDC *p = GetDC(); p->MoveTo(m_point); //鍵盤按下 m_point.x += 40; //水平平移40 p->Rectangle(m_point.x, m_point.y, m_point.x+20, m_point.y+30); CView::OnKeyDown(nChar, nRepCnt, nFlags); }

      需要將UINT nChar轉換為Char字符型,然后進行盤,WASD進行上下左右移動繪制橢圓。

      //鼠標按鍵 void CMousePicView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CDC *p = GetDC(); char cChar; //當前被按下的字符 cChar = char(nChar); //將按下的鍵轉換為字符 //定義畫筆 CPen MyPen, *OldPen; MyPen.CreatePen(PS_DASH, 2, RGB(0,0,255)); //虛線 粗2 藍色 OldPen = p->SelectObject(&MyPen); //舊畫筆賦值 //畫刷 CBrush MyBrush, *OldBrush; MyBrush.CreateSolidBrush(RGB(0,255,0)); OldBrush = p->SelectObject(&MyBrush); if (cChar == 'D') { p->MoveTo(m_point); //D鍵按下 m_point.x += 40; //水平向右平移40 p->Ellipse(m_point.x, m_point.y, m_point.x+20, m_point.y+40); } if (cChar == 'A') { p->MoveTo(m_point); //A鍵按下 m_point.x -= 40; //水平向左平移40 p->Ellipse(m_point.x, m_point.y, m_point.x+20, m_point.y+40); } if (cChar == 'S') { p->MoveTo(m_point); //S鍵按下 m_point.y += 50; //豎直向下平移50 p->Ellipse(m_point.x, m_point.y, m_point.x+20, m_point.y+40); } if (cChar == 'W') { p->MoveTo(m_point); //W鍵按下 m_point.y -= 50; //豎直向上平移50 p->Ellipse(m_point.x, m_point.y, m_point.x+20, m_point.y+40); } //清除 p->SelectObject(OldPen); MyPen.DeleteObject(); p->SelectObject(OldBrush); MyBrush.DeleteObject(); CView::OnKeyDown(nChar, nRepCnt, nFlags); }

      繪制如下圖所示:

      4.按鍵光標選擇

      //鼠標按鍵 void CMousePicView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { //光標操作 char cChar; //當前被按下的字符 HCURSOR hCursor = 0; //顯示光標句柄 HCURSOR hPrevCursor = 0; //以前的光標句柄 cChar = char(nChar); //將按下的鍵轉換為字符 if (cChar == 'A'){ //加載箭頭光標 hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW); } if (cChar == 'B'){ //加載箭頭光標 hCursor = AfxGetApp()->LoadStandardCursor(IDC_IBEAM); } if (cChar == 'C'){ //加載箭頭光標 hCursor = AfxGetApp()->LoadStandardCursor(IDC_WAIT); } if (cChar == 'X'){ hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW); hPrevCursor = SetCursor(hCursor); if (hPrevCursor) DestroyCursor(hPrevCursor); } else{ if (hCursor){ hPrevCursor = SetCursor(hCursor); if (hPrevCursor) DestroyCursor(hPrevCursor); } } CView::OnKeyDown(nChar, nRepCnt, nFlags); }

      四. MFC鼠標繪制-學生作業展示

      最后展示學生做的成果,雖然代碼非常簡單,原理也很簡單,但是學生做得真的挺好的,原來編程還可以這樣上啊,一方面提升學生的學習興趣,另一方面增加他們的編程能力。

      還是那句話,非常佩服學生的創造力及想象力吧!而且編程課原來可以這么進行,提升學生的編程能力的同時也培養了學生的興趣。希望文章對你有所幫助~

      感恩能與大家在華為云遇見!

      希望能與大家一起在華為云社區共同成長。原文地址:https://blog.csdn.net/Eastmount/article/details/53192634

      (By:Eastmount 2021-12-16 夜于武漢)

      C++ 圖像處理

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:駕馭千級節點——揭秘PUMA大規模集群能力(四) ---- 云上測試及結論
      下一篇:熊貓燒香應急處理方法
      相關文章
      国产成人亚洲精品91专区高清| 亚洲熟妇色自偷自拍另类| 日韩亚洲产在线观看| 亚洲中字慕日产2021| 亚洲成av人片在线看片| 亚洲精品亚洲人成在线观看麻豆| 久久精品亚洲一区二区| 久久精品国产亚洲av成人| 亚洲Av无码精品色午夜 | 亚洲国产一二三精品无码| 国产亚洲老熟女视频| 国产成人亚洲精品91专区手机| 亚洲AV无码成H人在线观看| 处破女第一次亚洲18分钟| 激情婷婷成人亚洲综合| 午夜亚洲av永久无码精品| 亚洲国产日韩在线观频| 亚洲精品网站在线观看不卡无广告 | 亚洲综合中文字幕无线码| 久久亚洲国产成人影院| 亚洲国产精品美女久久久久| 小说专区亚洲春色校园| 偷自拍亚洲视频在线观看99| 亚洲不卡无码av中文字幕| 中文字幕在亚洲第一在线 | 在线观看免费亚洲| 亚洲熟女一区二区三区| 久久影视综合亚洲| 亚洲日韩v无码中文字幕| 亚洲妇熟XXXX妇色黄| 久久亚洲日韩精品一区二区三区 | 亚洲综合久久一本伊伊区| 亚洲精品国产国语| 亚洲av日韩综合一区二区三区 | 苍井空亚洲精品AA片在线播放| 亚洲国产成人久久综合区| 国产亚洲老熟女视频| 亚洲人成依人成综合网| 亚洲一级毛片中文字幕| 亚洲国产精品久久久久秋霞小| 亚洲色欲久久久久综合网|