win32中画完直线后如何将它删除

bill_chuang 2009-09-28 07:26:50
我在用win32做画图程序时,碰到一个问题,不知怎么解决:
我想画一条直线,先在起点点一下,然后用鼠标动态跟踪当前移动的点,并在当前点与起点之间画直线,如果当前点移到另一点,则前一条直线要被刷掉,重新画一条直线起点到当前点的直线,直到在终点处点击鼠标直线才能定下来。
如果仅仅画一条直线的话,那每次点变动后用InvalidateRect将窗口刷新一下,然后重画就可以了,最终可以确定一条直线。但是如果要多次画线的话,就不能这么整屏的刷新。
以下是我的程序一部分响应鼠标移动事件、单击事件和画面刷新事件的代码:
case WM_MOUSEMOVE:
if(bPressed) //bPressed初始化为0,如果是是非零,那么起始点已经确定
{
iCurrentPos.x=LOWORD(lParam);//记录下当前鼠标位置的点坐标
iCurrentPos.y=HIWORD(lParam);
SendMessage(hwnd,WM_PAINT,(WPARAM)MENU_LINE,(LPARAM)&iCurrentPos);//发送一个绘制消息
}
return 0;

case WM_LBUTTONDOWN: //鼠标单击事件
if(!bPressed)//如果bPressed=0,那么按下的那点事直线的起始点
{
bPressed=1;
line.beg.x=LOWORD(lParam);//记录下直线的起始点
line.beg.y=HIWORD(lParam);
SendMessage(hwnd,WM_PAINT,MENU_LINE,(LPARAM)&line.beg);
}
else
{
line.end.x=LOWORD(lParam);//如果bPressed非零,则第二次按下的位置就是直线的终点
line.end.y=HIWORD(lParam);
SendMessage(hwnd,WM_PAINT,MENU_LINE,(LPARAM)&line.end);//发送一个绘制消息,wParam参数为直线菜单项的ID号,用来区别绘制的是什么图形的,lParam参数为当前点
bPressed=0;
}

return 0;
case WM_PAINT:

InvalidateRect(hwnd,NULL,TRUE);//每得到一个刷新消息就把整屏刷新,将前一次的直线抹掉
hdc=BeginPaint(hwnd,&ps);

if(wParam == MENU_LINE)
{
iCurrentPos=*(POINT*)lParam;
DrawLine(hdc,line.beg,iCurrentPos);//绘制从起始点到鼠标当前位置之间的直线
}

所以我想请教一下哪位高手指点下如何实现多图形对象的绘制,又能够动态跟踪移动点
在此先谢过了
...全文
472 点赞 收藏 5
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
bill_chuang 2009-09-30
我是用保存之前线段来做的,但是只要鼠标一动,窗口就会刷新,这样屏幕就会不断的闪,不是太好看
回复
zhangyzupc1991 2009-09-29
提供一下思路,
多次画线时,记录需要保存的线段,然后刷新的时候只需要画出你保存的线段就可以了。
或者,进行线段的擦除,不过后者效率会低一点。
回复
灌水九段 2009-09-29
case mousemove:
pDC->SetROP2(R2_XORPEN);
pDC->drawline(xStart,yStart,getCurrentX(),getCurrentY());
回复
loop_k 2009-09-29
class CDrawView : public CView {
//……
protected:
BOOL m_bLButtonDown, m_bErase; // 判断是否按下左鼠标键
//和是否需要擦除图形的类变量
CPoint p0, pm; // 记录直线起点和动态终点的类变量
CPen * pGrayPen, * pLinePen; // 定义灰色和直线笔
//……
}
// 构造函数
CDrawView::CDrawView() {
m_bLButtonDown = FALSE; // 设左鼠标键按下为假
m_bErase = FALSE; // 设需要擦除为假
pGrayPen = new CPen(PS_SOLID, 0, RGB(128, 128, 128));// 创建灰色笔
pLinePen = new CPen(PS_SOLID, 0, RGB(255, 0, 0));// 创建红色的直线笔
}
// 鼠标消息响应函数
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) {
m_bLButtonDown = TRUE; // 设左鼠标键按下为真
SetCapture(); // 设置鼠标捕获
// SetCursor(LoadCursor(NULL, IDC_CROSS)); // 设置鼠标为十字
p0 = point; // 保存矩形左上角
pm = p0; // 让矩形右下角等于左上角
CView::OnLButtonDown(nFlags, point);
}
void CDrawView::OnMouseMove(UINT nFlags, CPoint point) {
SetCursor(LoadCursor(NULL, IDC_CROSS)); // 设置鼠标为十字
if (m_bLButtonDown) { // 左鼠标键按下为真
CDC* pDC = GetDC(); // 获取设备上下文
pDC->SelectObject(pGrayPen);// 选取灰色笔
pDC->SetROP2(R2_XORPEN);// 设置为异或绘图方式
if (m_bErase) { // 需要擦除为真
pDC->MoveTo(p0); pDC->LineTo(pm); // 擦除原直线
}
else // 需要擦除为假
m_bErase = TRUE; // 设需要擦除为真
pDC->MoveTo(p0); pDC->LineTo(point); // 绘制新直线
pm = point; // 记录老终点
ReleaseDC(pDC); // 释放设备上下文
}
CView::OnMouseMove(nFlags, point);
}
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) {
ReleaseCapture(); // 释放鼠标捕获
if (m_bLButtonDown) { // 左鼠标键按下为真
CDC* pDC = GetDC(); // 获取设备上下文
pDC->SelectObject(pGrayPen);// 选取灰色笔
pDC->SetROP2(R2_XORPEN); // 设置为异或绘图方式
pDC->MoveTo(p0); pDC->LineTo(pm); // 擦除原直线
pDC->SelectObject(pLinePen); // 选择直线笔
pDC->SetROP2(R2_COPYPEN);// 设置为覆盖绘图方式
pDC->MoveTo(p0); pDC->LineTo(point); // 绘制最终的直线
m_bLButtonDown = FALSE; // 重设左鼠标键按下为假
m_bErase = FALSE; // 重需要擦除为假
ReleaseDC(pDC); // 释放设备上下文
}
CView::OnLButtonUp(nFlags, point);
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/loop_k/archive/2009/08/24/4480034.aspx
回复
rxf_mpg 2009-09-29
使用2元像素运算即可
SetRop2(R2_NOT);
绘制两次即可去掉上次画的直线,R2_NOT将目标像素取反,当然这样你就不能控制其显示颜色
回复
相关推荐
发帖
图形处理/算法
创建于2007-09-28

1.9w+

社区成员

VC/MFC 图形处理/算法
申请成为版主
帖子事件
创建了帖子
2009-09-28 07:26
社区公告
暂无公告