所谓的动态画线,画矩形,画椭圆的本质就是在于消隐问题的解决以及对Windows消息循环机制的理解,消隐问题:
因为MFC中有一个函数SetROP2,通过将该函数的参数设置为R2—NOT(当前绘制的像素值设为屏幕像素值的反色,“屏幕”二字是指你所绘制的图形所占据的那一部分屏幕区域,即直线所占的屏幕区域就是直线所在的那一段线的区域),利用这一点通过在同一区域重复画两次便可以将该区域的形状消隐。
首先:建立一个单文档程序,名称为Demo
然后:在视图类的声明文件里面加入数据成员
class
CDemoView :
public
CView
{
//········
protected
:
int
m_Dragging;
HCURSOR
m_HCross;
CPoint m_PointOld;
CPoint m_PointOrigin;
//········
};
接着:在视图类的构造函数里面
CDemoView::CDemoView()
{
// TODO: add construction code here
m_Dragging=0;
m_HCross=AfxGetApp()->LoadStandardCursor(IDC_CROSS);
//载入标准的十字光标
}
接着:为视图类添加鼠标左键,鼠标移动,鼠标左键释放消息
void
CDemoView::OnLButtonDown(
UINT
nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
::SetCursor(m_HCross);
//这一句能防止左键单击的时候,保持鼠标样式不变
m_PointOrigin=point;
m_PointOld=point;
SetCapture();
//捕获鼠标,充分控制鼠标
m_Dragging=1;
RECT Rect;
GetClientRect(&Rect);
//取得窗口当前显示坐标
ClientToScreen(&Rect);
//转换为屏幕坐标
::ClipCursor(&Rect);
//限定光标在指定矩形了吗
CView::OnLButtonDown(nFlags, point);
}
void
CDemoView::OnMouseMove(
UINT
nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
::SetCursor(m_HCross);
if
(m_Dragging)
{
CClientDC ClientDC(
this
);
ClientDC.SetROP2(R2_NOT);
//逆转当前屏幕颜色来画线的绘图方式
ClientDC.MoveTo(m_PointOrigin);
//
ClientDC.LineTo(m_PointOld);
//擦去上一次的线
ClientDC.MoveTo(m_PointOrigin);
ClientDC.LineTo(point);
//绘制这一次的临时线
m_PointOld=point;
}
CView::OnMouseMove(nFlags, point);
}
void
CDemoView::OnLButtonUp(
UINT
nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if
(m_Dragging)
{
m_Dragging=0;
::ReleaseCapture();
//结束捕获鼠标
::ClipCursor(NULL);
//解锁鼠标
CClientDC ClientDC(
this
);
ClientDC.SetROP2(R2_NOT);
ClientDC.MoveTo(m_PointOrigin);
ClientDC.LineTo(m_PointOld);
//擦去上一次的临时线
ClientDC.SetROP2(R2_COPYPEN);
//缺省绘图模式,像素为画笔颜色
ClientDC.MoveTo(m_PointOrigin);
ClientDC.LineTo(point);
//绘制固定线
}
CView::OnLButtonUp(nFlags, point);
}