標籤:target dbr 轉換 and move sys 藍色 介紹 應用
上一篇文章我們講述MFC繪製圖形的基本函數,包括繪製直線、繪製矩形、繪製橢圓及繪製文字,同時通過繞圓旋轉和矩形平移簡單的理解了圖形學知識。這篇文章我將介紹滑鼠響應和鍵盤響應,通過這些事件讓學生實現一個類似畫圖的簡單軟體,同時充分發揮學生想象,自己創作東西。
前文:
【電腦圖形學課程】一.MFC基本繪圖函數使用方法
一. MFC工程建立及滑鼠響應
建立一個MFC 單文檔的應用程式"MousePic"。
然後,選擇"View(視圖)"->"建立類嚮導",快鍵鍵是Ctrl+W。這是MFC非常重要的一個知識點,對話方塊或單文檔設定按鈕操作、響應函數都是通過該操作實現。
在MFC ClassWizard中選擇建立工程的"CMousePicView"類名,然後再"Message"中選擇"WM_LBUTTONDOWN",滑鼠左鍵按下響應操作。同時,雙擊它添加函數OnLButtonDown()。
滑鼠常見訊息響應:
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_pointm_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_pointm_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.按鍵響應操作
同樣,通過類嚮導建立按鍵按下函數。
然後添加如下代碼,按下任意一個鍵,繪製的矩形向右平移40距離。
//滑鼠按鍵void CMousePicView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {// TODO: Add your message handler code here and/or call defaultCDC *p = GetDC();p->MoveTo(m_point); //鍵盤按下m_point.x += 40; //水平平移40p->Rectangle(m_point.x, m_point.y, m_point.x+20, m_point.y+30);CView::OnKeyDown(nChar, nRepCnt, nFlags);}
繪製圖形如下所示:
3.響應不同鍵盤的操作
需要將UINT nChar轉換為Char字元型,然後進行盤,WASD進行上下左右移動繪製橢圓。
//滑鼠按鍵void CMousePicView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {// TODO: Add your message handler code here and/or call defaultCDC *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; //水平向右平移40p->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; //水平向左平移40p->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; //豎直向下平移50p->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; //豎直向上平移50p->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滑鼠繪製-學生作業展示
最後展示學生做的成果,雖然代碼非常簡單,原理也很簡單,但是學生做得真的挺好的,原來編程還可以這樣上啊,一方面提升學生的學習興趣,另一方面增加他們的編程能力。
還是那句話,非常佩服學生的創造力及想象力吧!而且編程課原來可以這麼進行,提升學生的編程能力的同時也培養了學生的興趣。希望文章對你有所協助~
(By:Eastmount 2016-11-20 半夜2點半 http://blog.csdn.net/eastmount/ )
【電腦圖形學課程】二.MFC滑鼠響應函數類比畫圖軟體