MFC橡皮筋矩形框技术

    在网上看过很多用在MFC对话框的界面上用鼠标画矩形框的例子,感觉有点乱,同时又达到我想要的效果,
经过不断的尝试以及改进,才终于达到我想要的效果。
    这部分程序主要实现在对话框界面上的picture控件内用鼠标拖动画矩形框并显示,框大小随意,且每次
只显示一个矩形框,同时获取矩形框中的图片内容,以下是相关程序代码。
void CCV10Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{       
    bool IsInRct = false;
    CRect Trect;          //定义橡皮筋框的矩形
    CRect Prect;         //图片矩形框
    CRect AbsRect;
    int i = 0;

    if (point.x<pt_rect.left || point.x>pt_rect.right || point.y<pt_rect.top || point.y>pt_rect.bottom)
        return;

    if (m_rctCurTracker.HitTest(point)<0)       //判断鼠标点击位置是否在已画的矩形框内
    {
        IsInRct = false;
    }
    else
    {
        IsInRct = true;
    }
    if (!IsInRct)   //没在矩形框内则鼠标重新画矩形
    {
        CRectTracker tempRectTracker;   
        tempRectTracker.TrackRubberBand(this, point);
        tempRectTracker.m_rect.NormalizeRect();

        Trect = tempRectTracker.m_rect;   //得到画好的橡皮筋框

        //调整所画矩形框的大小
        Trect.top = (Trect.top<pt_rect.top ? pt_rect.top : Trect.top);              //将鼠标所画矩形框的边界限制在图片控件领域内
        Trect.left = (Trect.left<pt_rect.left ? pt_rect.left : Trect.left);
        Trect.bottom = (Trect.bottom>pt_rect.bottom ? pt_rect.bottom : Trect.bottom);
        Trect.right = (Trect.right>pt_rect.right ? pt_rect.right : Trect.right);

        tempRectTracker.m_rect.SetRect(Trect.left, Trect.top, Trect.right, Trect.bottom); //重置所画矩形框的边界位置

        if (Trect.Height()*Trect.Width() < 100)             //抛弃鼠标画的过小的矩形
            return;

        m_rctCurTracker.m_rect = tempRectTracker.m_rect;
        CClientDC dc(this);
        m_rctCurTracker.Draw(&dc);
        //注意!!在这里一定要调用绘制边框的程序,否则单凭onpaint中绘制,不能显示出来                 
    }
    else
    {
        CClientDC dc(this); 

        m_rctCurTracker.Draw(&dc);
        m_rctCurTracker.Track(this, point);

        Trect = m_rctCurTracker.m_rect;   //得到画好的橡皮筋框

        //调整矩形框的位置
        if (Trect.top<pt_rect.top)
        {//超出图片框顶部的位置
            Trect.bottom = pt_rect.top - Trect.top + Trect.bottom;
            Trect.top = pt_rect.top;
        }
        if (Trect.bottom>pt_rect.bottom)
        {//超出底部的位置
            Trect.top = pt_rect.bottom - Trect.bottom + Trect.top;
            Trect.bottom = pt_rect.bottom;
        }
        if (Trect.right>pt_rect.right)
        {//超出右边
            Trect.left = pt_rect.right - Trect.right + Trect.left;
            Trect.right = pt_rect.right;
        }
        if (Trect.left<pt_rect.left)
        {//超出左边
            Trect.right = pt_rect.left - Trect.left + Trect.right;
            Trect.left = pt_rect.left;
        }
        //设置矩形框大小
        m_rctCurTracker.m_rect.SetRect(Trect.left, Trect.top, Trect.right, Trect.bottom);
        m_rctCurTracker.m_rect.NormalizeRect();

        m_rctCurTracker.GetTrueRect(&rc_showRect);//得到矩形区域的大小  ,经过recttracker后获取其 rect区域,再将其画在窗体上,此后的操作与操作rect无异。
        rc_showRect.SetRect(rc_showRect.left - pt_rect.left, rc_showRect.top - pt_rect.top, rc_showRect.right - pt_rect.left, rc_showRect.bottom - pt_rect.top);

        //CRect rc_clientRect, CRect pt_rect
        //获取矩形框中的图片内容并保存,m_subImgRect类型为Rect,m_RDrawedNum为int,注意防止边界泄漏
        double widthRatio = double(image.cols) / rc_clientRect.Width();
        double heightRatio = double(image.rows) / rc_clientRect.Height();
        m_subImgRect[m_RDrawedNum].x = int((rc_showRect.left + 1) * widthRatio);
        m_subImgRect[m_RDrawedNum].y = int((rc_showRect.top + 1)* heightRatio);
        m_subImgRect[m_RDrawedNum].width = int((rc_showRect.Width() - 2)* widthRatio);
        m_subImgRect[m_RDrawedNum].height = int((rc_showRect.Height() - 2)* heightRatio);

        subImg = image(m_subImgRect[m_RDrawedNum]);

        CRgn rgn1;
        rgn1.CreateRectRgnIndirect(rc_clientRect);
        InvalidateRgn(&rgn1, FALSE);    //调用onpaint函数重绘窗口,但是保留原来的背景图
    }
    CDialogEx::OnLButtonDown(nFlags, point);
}


void CCV10Dlg::OnPaint()
{
    CPaintDC dc(this); // 用于绘制的设备上下文
    if (IsIconic())
    {       
        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // 使图标在工作区矩形中居中
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // 绘制图标
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {   
        //用户自定义窗体绘图 代码 添加区
        CDialogEx::OnPaint();

        //让图片自适应控件大小显示
        IplImage img = image;   //Mat image;
        cimg.CopyOf(&img);      //CvvImage cimg;
        m_picShow.GetClientRect(&rc_clientRect);
        cimg.DrawToHDC(hDC, &rc_clientRect);  

        if (bl_createColorModel == true)
        {           
            CDC *pDC1 = GetDlgItem(IDC_PICTURE)->GetDC();
            CBrush* pOldBrush = (CBrush*)pDC1->SelectStockObject(NULL_BRUSH);
            CPen* pen = new CPen(PS_SOLID, 1, RGB(0, 255, 0));
            CPen* oldPen = pDC1->SelectObject(pen);
            pDC1->Rectangle(rc_showRect);
            pDC1->SelectObject(pOldBrush);
            pDC1->SelectObject(oldPen);
            delete pen;
        }           
    }
}
    以上代码包含图片在picture控件中如何显示的问题,矩形框在控件上如何显示的问题,以及
如何提取鼠标所画矩形框中内容的问题,希望对大家有用,有问题可以多多提意见。
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值