MFC 對話方塊圖片上,滑鼠拖動畫矩形框
參考
https://blog.csdn.net/chenjie863/article/details/17531339 未實驗
https://blog.csdn.net/bsnry/article/details/8484047
https://blog.csdn.net/Yuer_Arya/article/details/82052451
在我們在使用微軟的繪圖程式時。當要畫一條直線,先用滑鼠確定起始位置,然後滑鼠在螢幕上來回移動時,我們會發現,這條直線就像橡皮筋一樣,隨著滑鼠在螢幕中的位置,長短和終點都隨之變化。我們在編制自己的程式時,有時也需實現類似的功能,本文將通過簡單的程式設計例項,並說明實現原理。
一。實現原理:
利用了WINDOWS繪圖模式中的“異或”的繪圖特性。即在螢幕上用異或的模式畫圖形,然後再用異或的模式,在相同的位置重新畫一次此圖形,則就會在螢幕上擦出掉上一次所繪製的內容。
具體在程式中,
1。當按下滑鼠左鍵時,用異或的繪圖模式在螢幕上畫圖形。
2。當滑鼠移動後,先用異或的繪圖模式擦掉上次繪製的圖形。然後在新的位置繪製圖形。
3。當滑鼠左鍵被抬起時。在最終的位置用正常的顏色重新繪製圖形。結束。
要解決這個問題,需要先了解SetROP2函式的兩個引數R2_NOT與R2_NOTXORPEN的使用效果,以下為該兩種繪畫模式舉例:
- R2_NOTXORPEN繪畫模式
你用紅色畫筆在黑色背景上畫一條直線,顯示紅色,但你再用這隻筆在剛畫的直線上重畫一遍,就相當於把開始畫的紅線擦除掉了,劃線的地方顯示為背景色。 - R2_NOT繪畫模式
同樣有在同一個地方畫兩次相當於什麼都沒畫的功能,不過R2_NOT繪畫模式第一次畫的時候顯示顏色並不是你選定的畫筆顏色,而是預設的顏色。
當了解以上兩種繪畫模式後,我們就可以實現拖動滑鼠時平滑繪製出動態的矩形框,假設在滑鼠移動過程中經過點A, 以點A為末點繪製一個矩形框,接著滑鼠移動到下一個點B時,在點B繪製矩形前,再次以點A繪製一次矩形,利用R2_NOT的模式特定,再次繪畫末點A後,原來的矩形會被擦除(在同一個地方畫兩次相當於什麼都沒畫的功能),最後在以點B作為末點,繪製矩形
CPoint m_chRegionLeftTopPoint;//開始點
CPoint m_chRegionRightBottomPoint;//結束點
BOOL m_fLButtonDownNotUp = FALSE;//滑鼠是否按下
void CmfcimageDlg::OnLButtonDown(UINT nFlags, CPoint point) { CRect m_picRect; GetDlgItem(IDC_PIC_SHOW)->GetWindowRect(m_picRect);//獲得螢幕座標 ScreenToClient(&m_picRect);//轉到客戶區相對座標 //記錄起始點座標 m_fLButtonDownNotUp = true; if ((point.x < m_picRect.right) && (point.x > m_picRect.left) && (point.y < m_picRect.bottom) && (point.y > m_picRect.top)) { m_chRegionLeftTopPoint = point; m_chRegionRightBottomPoint = point; } CDialogEx::OnLButtonDown(nFlags, point); } void CmfcimageDlg::OnMouseMove(UINT nFlags, CPoint point) { CRect m_picRect; GetDlgItem(IDC_PIC_SHOW)->GetWindowRect(m_picRect);//獲得螢幕座標 ScreenToClient(&m_picRect);//轉到客戶區相對座標 if ((point.x < m_picRect.right) && (point.x > m_picRect.left) && (point.y < m_picRect.bottom) && (point.y > m_picRect.top)) { if (m_fLButtonDownNotUp) { /* 當了解以上兩種繪畫模式後,我們就可以實現拖動滑鼠時平滑繪製出動態的矩形框, 1 假設在滑鼠移動過程中經過點A, 以點A為末點繪製一個矩形框, 2 接著滑鼠移動到下一個點B時,在點B繪製矩形前,再次以點A繪製一次矩形, 3 利用R2_NOT的模式特定,再次繪畫末點A後,原來的矩形會被擦除(在同一個地方畫兩次相當於什麼都沒畫的功能), 4 最後在以點B作為末點,繪製矩形! */ CDC* pDC = GetDlgItem(IDC_PIC_SHOW)->GetDC(); CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH); CPen* pen = new CPen(PS_SOLID, 1, RGB(0, 255, 0)); CPen* oldPen = pDC->SelectObject(pen); pDC->SelectObject(pOldBrush); pDC->SetROP2(R2_NOTXORPEN); pDC->Rectangle(CRect(m_chRegionLeftTopPoint, m_chRegionRightBottomPoint));//第二次畫出A點,那麼上次畫的框會消失 m_chRegionRightBottomPoint = point; pDC->Rectangle(CRect(m_chRegionLeftTopPoint, m_chRegionRightBottomPoint));//畫出B點 pDC->SelectObject(oldPen); delete pen; } } CDialogEx::OnMouseMove(nFlags, point); } void CmfcimageDlg::OnLButtonUp(UINT nFlags, CPoint point) { CRect m_picRect; GetDlgItem(IDC_PIC_SHOW)->GetWindowRect(m_picRect);//獲得螢幕座標 ScreenToClient(&m_picRect);//轉到客戶區相對座標 // if ((point.x < m_picRect.right) && (point.x > m_picRect.left) && (point.y < m_picRect.bottom) && (point.y > m_picRect.top)) { if (m_fLButtonDownNotUp) { m_chRegionRightBottomPoint = point; //繪製矩形 CDC* pDC = GetDlgItem(IDC_PIC_SHOW)->GetDC(); CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH); CPen* pen = new CPen(PS_SOLID, 1, RGB(0, 255, 0)); CPen* oldPen = pDC->SelectObject(pen); pDC->Rectangle(CRect(m_chRegionLeftTopPoint, m_chRegionRightBottomPoint)); pDC->SelectObject(pOldBrush); pDC->SelectObject(oldPen); delete pen;
} } m_fLButtonDownNotUp = false; CDialogEx::OnLButtonUp(nFlags, point); }