1. 程式人生 > 實用技巧 >MFC 對話方塊圖片上,滑鼠拖動畫矩形框

MFC 對話方塊圖片上,滑鼠拖動畫矩形框

參考

https://blog.csdn.net/chenjie863/article/details/17531339 未實驗

https://blog.csdn.net/bsnry/article/details/8484047

https://blog.csdn.net/xvdongming/article/details/2625951?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

https://blog.csdn.net/weixin_30748995/article/details/97226762?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

https://blog.csdn.net/liu__ke/article/details/9236273?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

https://blog.csdn.net/weixinhum/article/details/28880721?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.nonecase

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); }