MFC橡皮筋划线问题
voidCMyHomeworkView::OnMouseMove(UINTnFlags,CPointpoint){//TODO:Addyourmessagehandler...
void CMyHomeworkView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
dc.SetROP2(R2_NOT);
if (nFlags == MK_LBUTTON )
{
// dc.MoveTo(23,150);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptOld);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
m_ptOld=point;
}
CView::OnMouseMove(nFlags, point);
}
为什么dc.MoveTo(m_ptOrigin);是正确的橡皮筋划线,但是改成具体的坐标 dc.MoveTo(23,150);后就是那种扇形的,如图 展开
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
dc.SetROP2(R2_NOT);
if (nFlags == MK_LBUTTON )
{
// dc.MoveTo(23,150);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptOld);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
m_ptOld=point;
}
CView::OnMouseMove(nFlags, point);
}
为什么dc.MoveTo(m_ptOrigin);是正确的橡皮筋划线,但是改成具体的坐标 dc.MoveTo(23,150);后就是那种扇形的,如图 展开
1个回答
展开全部
MFC下绘制直线,使用橡皮筋技术,可以使直线效果跟随鼠标移动
//OnLButtionDown
m_ptOrigin = m_ptEnd = point;
//OnMouseMove
CClientDC dc(this);
if (nFlags == MK_LBUTTON )
{
dc.SetROP2(R2_NOT);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
m_ptEnd = point;
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
}
但是这个只能实现黑色直线的绘制,我们想要画其他颜色的线,并且希望使用不同类型的线和线宽,因此要建一个画笔,指定想要的画笔的类型,如实线、虚线、点线,指定线宽和画笔颜色。
void CGraphic1View::OnMouseMove(UINT nFlags, CPoint point)
{
if(MK_LBUTTON == nFlags)
{
CClientDC dc(this);
int oldmode=dc.SetROP2(R2_NOTXORPEN);
CPen pen(m_nLineStyle, m_nLineWidth, m_clr), *oldpen;
oldpen = dc.SelectObject(&pen);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
m_ptEnd=point;
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
dc.SelectObject(oldpen);
dc.SetROP2(oldmode);
ReleaseDC(&dc);
}
CScrollView::OnMouseMove(nFlags, point);
}
其中
CPen pen(m_nLineStyle, m_nLineWidth, m_clr), *oldpen;
m_nLineStyle是线型,m_nLineWidth是线宽,m_clr是画笔颜色,也可以指定如下:
CPen pen(0, 0, RGB(255, 0, 0)), *oldpen;
下面说一下,橡皮筋效果是如何实现的。当我们按下鼠标左键后,有m_ptOrigin = m_ptEnd = point;
这时鼠标移动就会发送WM_MOUSEMOVE消息,调用OnMouseMove进行处理,我们就在这个响应函数中实现橡皮筋的效果。if(MK_LBUTTON == nFlags)判断是否左键按下的鼠标移动。SetROP2函数主要用于设定当前前景色的混合模式。参数取值R2_NOT就是取反的意思,即前景色为背景色的反色,经常用R2_NOT来画橡皮线,因为两次取反可以还原背景色,但是只能话黑色的线。
而R2_NOTXORPEN画出来的颜色与R2_XORPEN相反,R2_XORPEN是屏幕颜色和画笔颜色的异或。OnMouseMove第一次被调用时,还没画线,所以屏幕的颜色是白色的,R2_XORPEN是当前画笔的颜色取反,那么R2_NOTXORPEN就是当前画笔颜色了。就是说第一次画的线是画笔的颜色。
第二次调用OnMouseMove时,m_ptOrigin和m_ptEnd两个点还没变,所以可以用这两个点再画线,将第一次画的线覆盖掉,变成画布的颜色,然后在新的point点和m_ptOrigin之间重新画线,颜色为画笔颜色。在旧的直线上面画线,因为线本来有颜色,所以R2_XORPEN(屏幕的颜色==画笔颜色)就会变成黑色(1 xor 1=0,0 xor 0=0),取反,即R2_NOTXORPEN为白色,就是画布的颜色,看起来就像消失了一样,其实只不过是线变成白色了(如果画笔不是白色,比如使用你系统设置了护眼配色,客户区变成不伤眼的浅绿色,这样显示出来的颜色还是白色,而不是客户区的颜色)。旧的直线删除了,就可以在新的点point上再次画线了。
扩展:如果想实现矩形、椭圆的橡皮筋效果将语句
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
换成:
dc.Rectangle(CRect(this->m_ptOrigin, m_ptEnd));
或者
dc.Ellipse(CRect(this->m_ptOrigin, m_ptEnd));
就可以了。
//OnLButtionDown
m_ptOrigin = m_ptEnd = point;
//OnMouseMove
CClientDC dc(this);
if (nFlags == MK_LBUTTON )
{
dc.SetROP2(R2_NOT);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
m_ptEnd = point;
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
}
但是这个只能实现黑色直线的绘制,我们想要画其他颜色的线,并且希望使用不同类型的线和线宽,因此要建一个画笔,指定想要的画笔的类型,如实线、虚线、点线,指定线宽和画笔颜色。
void CGraphic1View::OnMouseMove(UINT nFlags, CPoint point)
{
if(MK_LBUTTON == nFlags)
{
CClientDC dc(this);
int oldmode=dc.SetROP2(R2_NOTXORPEN);
CPen pen(m_nLineStyle, m_nLineWidth, m_clr), *oldpen;
oldpen = dc.SelectObject(&pen);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
m_ptEnd=point;
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
dc.SelectObject(oldpen);
dc.SetROP2(oldmode);
ReleaseDC(&dc);
}
CScrollView::OnMouseMove(nFlags, point);
}
其中
CPen pen(m_nLineStyle, m_nLineWidth, m_clr), *oldpen;
m_nLineStyle是线型,m_nLineWidth是线宽,m_clr是画笔颜色,也可以指定如下:
CPen pen(0, 0, RGB(255, 0, 0)), *oldpen;
下面说一下,橡皮筋效果是如何实现的。当我们按下鼠标左键后,有m_ptOrigin = m_ptEnd = point;
这时鼠标移动就会发送WM_MOUSEMOVE消息,调用OnMouseMove进行处理,我们就在这个响应函数中实现橡皮筋的效果。if(MK_LBUTTON == nFlags)判断是否左键按下的鼠标移动。SetROP2函数主要用于设定当前前景色的混合模式。参数取值R2_NOT就是取反的意思,即前景色为背景色的反色,经常用R2_NOT来画橡皮线,因为两次取反可以还原背景色,但是只能话黑色的线。
而R2_NOTXORPEN画出来的颜色与R2_XORPEN相反,R2_XORPEN是屏幕颜色和画笔颜色的异或。OnMouseMove第一次被调用时,还没画线,所以屏幕的颜色是白色的,R2_XORPEN是当前画笔的颜色取反,那么R2_NOTXORPEN就是当前画笔颜色了。就是说第一次画的线是画笔的颜色。
第二次调用OnMouseMove时,m_ptOrigin和m_ptEnd两个点还没变,所以可以用这两个点再画线,将第一次画的线覆盖掉,变成画布的颜色,然后在新的point点和m_ptOrigin之间重新画线,颜色为画笔颜色。在旧的直线上面画线,因为线本来有颜色,所以R2_XORPEN(屏幕的颜色==画笔颜色)就会变成黑色(1 xor 1=0,0 xor 0=0),取反,即R2_NOTXORPEN为白色,就是画布的颜色,看起来就像消失了一样,其实只不过是线变成白色了(如果画笔不是白色,比如使用你系统设置了护眼配色,客户区变成不伤眼的浅绿色,这样显示出来的颜色还是白色,而不是客户区的颜色)。旧的直线删除了,就可以在新的点point上再次画线了。
扩展:如果想实现矩形、椭圆的橡皮筋效果将语句
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
换成:
dc.Rectangle(CRect(this->m_ptOrigin, m_ptEnd));
或者
dc.Ellipse(CRect(this->m_ptOrigin, m_ptEnd));
就可以了。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询