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

 

posted on 2020-07-25 13:12  Maddock  阅读(1298)  评论(0编辑  收藏  举报

导航