请问:为什么SetROP2(R2_XORPEN)无效?

fangxu1999 2009-10-31 06:44:38
我想在屏幕上画一些五角星,通过鼠标拖动来实现,可是无法清除绘制过程中定位的痕迹,请问哪里出错了啊,谢谢。
头文件中的数据:

private:
CArray<CPoint, CPoint&> starsCenter;
CArray<int, int&> starsRadius;

CPoint center;
int radius;

void drawStar(CDC * pDC, const CPoint & pt, int r, bool erase = false);
public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);



实现文件中:

void CStarView::OnDraw(CDC* pDC)
{
CStarDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: 在此处为本机数据添加绘制代码
pDC->SelectStockObject(NULL_BRUSH);
for (int i=0; i<starsCenter.GetSize(); i++)
{
drawStar(pDC, starsCenter[i], starsRadius[i]);
}
}

void CStarView::OnLButtonDown(UINT nFlags, CPoint point)
{
center = point;
radius = 0;

CClientDC dc(this);
dc.SetPixel(center, RGB(0, 0, 0));

SetCapture();

CView::OnLButtonDown(nFlags, point);
}

void CStarView::drawStar(CDC * pDC, const CPoint & pt, int r, bool erase)
{
using namespace std;

CRect rc;
GetClientRect(&rc);

int mm = pDC->SetMapMode(MM_ANISOTROPIC);
CSize wext = pDC->SetWindowExt(rc.Size());
CSize ext = pDC->SetViewportExt(rc.Width(), -rc.Height());
CPoint org = pDC->SetViewportOrg(pt);

int rop = 0;
if (erase)
{
rop = pDC->SetROP2(R2_XORPEN);
}

CPoint vertex[5];

const double PI = 3.1415927;
double angle = 2*PI/5;

vertex[0].SetPoint(0, r);
vertex[1].SetPoint(r*sin(angle), r*cos(angle));
vertex[2].SetPoint(r*sin(angle/2), -r*cos(angle/2));
vertex[3].SetPoint(-vertex[2].x, vertex[2].y);
vertex[4].SetPoint(-vertex[1].x, vertex[1].y);

pDC->MoveTo(vertex[0]);
pDC->LineTo(vertex[2]);
pDC->LineTo(vertex[4]);
pDC->LineTo(vertex[1]);
pDC->LineTo(vertex[3]);
pDC->LineTo(vertex[0]);

if (erase)
{
pDC->SetROP2(rop);
}

pDC->SetViewportOrg(org);
pDC->SetViewportExt(ext);
pDC->SetWindowExt(wext);
pDC->SetMapMode(mm);
}

void CStarView::OnLButtonUp(UINT nFlags, CPoint point)
{
if (GetCapture() == this)
{
CClientDC dc(this);
dc.SelectStockObject(NULL_BRUSH);

CRect rt(center, CSize(0, 0));
rt.InflateRect(radius, radius+1);

dc.SetROP2(R2_XORPEN);
dc.Ellipse(rt);

starsCenter.Add(center);
starsRadius.Add(radius);

ReleaseCapture();
}

CView::OnLButtonUp(nFlags, point);
}

void CStarView::OnMouseMove(UINT nFlags, CPoint point)
{
if (GetCapture() == this)
{
CClientDC dc(this);
dc.SelectStockObject(NULL_BRUSH);
drawStar(&dc, center, radius, true);

CRect rt(center, CSize(0, 0));
rt.InflateRect(radius, radius+1);
int rop = dc.SetROP2(R2_XORPEN);
dc.Ellipse(rt);
dc.SetROP2(rop);

radius = sqrt(double((point.x - center.x)*(point.x - center.x) + (point.y - center.y)*(point.y - center.y)));

drawStar(&dc, center, radius);

rt = CRect(center, CSize(0, 0));
rt.InflateRect(radius, radius+1);
dc.Ellipse(rt);
}

CView::OnMouseMove(nFlags, point);
}
...全文
191 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
fangxu1999 2009-11-17
  • 打赏
  • 举报
回复
谢谢大家了。好像没有办法解决,我用双缓冲做了。鼠标移动后,立即UpdateWindow
rayw0ng 2009-11-01
  • 打赏
  • 举报
回复
不知道画线和擦除都用 R2_NOTXORPEN 能不能避免这种情况,因为你画的线有相交的情况。
fangxu1999 2009-10-31
  • 打赏
  • 举报
回复
确实重新调用OnDraw函数一次就没有了。现在问题是绘制过程中,在WM_MOUSEMOVE响应函数中实现的绘制工作。也试图异或擦除痕迹,可是还有一些斑斑点点,不知道该怎么解决了。
panpengpeng 2009-10-31
  • 打赏
  • 举报
回复
最小化重新显示一下残留是不是就没有了,如果是就是刷新的问题吧
fangxu1999 2009-10-31
  • 打赏
  • 举报
回复
谢谢,确实应该是 R2_NOTXORPEN。RRGGBB自己直接异或将产生000000,为纯黑色。再取反就是纯白色了。

可是即使是这样设置,屏幕上仍然存在残留的少部分痕迹,特别是五角星边的顶点处,好像是WM_MOUSEMOVE中没有完全将擦除痕迹。

请问有没有办法彻底解决残留痕迹的问题啊?不用通过OnDraw函数的调用,能够实时响应鼠标拖动过程中实现完全擦除痕迹?谢谢
fandh 2009-10-31
  • 打赏
  • 举报
回复
SetROP2(R2_NOTXORPEN);
rayw0ng 2009-10-31
  • 打赏
  • 举报
回复
擦除应该用 R2_NOTXORPEN 吧。

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧