在画图过程中比如说要删除一条直线
一般采用反色来处理,即SetROP2
但是,如果直线下面还有其它图形,就会把直线与其它图形相交的部分也擦拭掉了。
大家有什么好的处理方法,谢谢!
一般采用反色来处理,即SetROP2
但是,如果直线下面还有其它图形,就会把直线与其它图形相交的部分也擦拭掉了。
大家有什么好的处理方法,谢谢!
解决方案 »
- Ctoolbar中的问题
- ===人民币5000元求程序源码:截获打印内容程序===
- 在单文本程序中,如何使按对话框上的一个按钮后,在文本中TEXTOUT
- 关于CListCtrl::HitTest()的问题,在线等。
- 各位 怎样做一个windows media player的关联
- 关于DirectShow/
- 谁能给我详细解释一下设备坐标、逻辑坐标以及物理坐标的相关知识
- MFC/c 根据快捷方式路径怎么获取目标路径
- 请教主线程函数执行时,子线程得不到控制权
- 怎样学好vc?
- 为什么我的CStatusBar始终是灰色的,但是VC自己的num就可以变成正常状态?
- 求教:不同程序间回调函数编写定义和使用问题
例如画橡皮筋直线,根据onmousemove直接:
CClientDC dc( this );
dc.setrop2(notxorpen);
//刷除上次
dc.moveto..
dc.lineto..
//重绘新线
dc.moveto..
dc.lineto..
dc.setrop2(oldrop).
当结束绘图时(onlbuttonup)才直接绘到底图上刷新.
CClientDC dc( this );
dc.setrop2(notxorpen);
//刷除上次
dc.moveto..
dc.lineto..这也会影响到底图的可能我没有明白你的意思,能不能再给些提示,谢谢!
汗,我知道了,你并没有画在一幅内存BMP上,而是直接在客户区作图.
那么,当你重绘时,你就需要重绘所有画过的DD,因此非常耗时,而且有可能在刷除时受影响。那么为何不画在BMP上呢?画在bmp上就没那么多烦恼了。
如果要动态移动这条直线,我就不知道怎么处理,我知道橡它类似橡皮筋的原理,可是不知道怎么处理。
CRect rect;
GetClientRect(&rect);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap memBmp;
memBmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
memDC.SelectObject(&memBmp);
memDC.FillSolidRect(0,0,rect.Width(),rect.Height(),RGB(255,255,255)); memDC.Rectangle(CRect(50,50,200,200));//矩形 memDC.MoveTo(70,40);
memDC.LineTo(70,250); //直线
pDC->BitBlt(50,50,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);//拷贝到客户区
首先要有变量记录开始点(CPoint ptStart),然后还有个变量记录当前点(CPoint ptCur),最终点就是鼠标抬起时的那点了(CPoint ptEnd),当然还需要有个变量来控制开始画橡皮筋(BOOL bStartDraw)...最后,要有个BOOL变量来控制画还是不画(DrawXiangPi)。
整个过程就是要得到开始和最终点来画一条直线。那么当鼠标按下时:void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
if( DrawXiangPi ){ // 如果要画橡皮就开始,否则啥都不做(这个BOOL变量当然是菜单或者命令更改)
ptStart = ptCur = point; // 记录开始点
bStartDraw = TRUE;// 开始画
SetCapture(); // 捕捉鼠标
}
CScrollView::OnLButtonDown(nFlags, point);
}当鼠标按下移动时就画橡皮:void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
if( bStartDraw ){ // 如果开始了
// 直接画在客户区
CClientDC dc(this);
int nROP = dc.SetROP2(R2_NOTXORPEN);
dc.MoveTo( ptStart );
dc.LineTo( ptCur ); // 画旧的,等于刷除上一条
ptCur = point; // re
dc.MoveTo( ptStart );
dc.LineTo( ptCur ); // 画新的。
dc.SetROP2( nROP );
}
CScrollView::OnMouseMove(nFlags, point);
}最后,当鼠标抬起时,就得到连个点,可以画在底图上了:void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
if( bStartDraw ){
CClientDC dc( this );
int nROP = dc.SetROP2(R2_NOTXORPEN);
dc.MoveTo( ptStart );
dc.LineTo( ptCur ); // 画旧的,等于刷除上一条
dc.SetROP2(nROP); bStartDraw = FALSE; // 画完
::ReleaseCapture(); // 释放鼠标
ptEnd = point; // 现在,你已经得到两个点了:起始点和最终点来画一条直线了。
// 可以调用你那堆东西:memdc.MoveTo(ptStart);memdc.LineTo(ptEnd);
dosomethink(here); // 可以把你上面那堆搞成个函数: dosomethink( CPoint ptStart, CPoint ptEnd ); // Invalidate(); // 刷新or not..看你的代码而定了.
}
CScrollView::OnLButtonUp(nFlags, point);
}以上大概就是画橡皮筋直线的办法.画矩形也是差不多的.
当然,那不是摘录下来的代码,是偶随手写的,有错不出奇..hoho.
gl.
{
if( bStartDraw ){ // 如果开始了
// 直接画在客户区
CClientDC dc(this);
int nROP = dc.SetROP2(R2_NOTXORPEN);
dc.MoveTo( ptStart );
dc.LineTo( ptCur ); // 画旧的,等于刷除上一条//这里就会把底层的图形破坏了
ptCur = point; // re
dc.MoveTo( ptStart );
dc.LineTo( ptCur ); // 画新的。
dc.SetROP2( nROP );
}
CScrollView::OnMouseMove(nFlags, point);
}
void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
if( bStartDraw ){
CClientDC dc( this );
int nROP = dc.SetROP2(R2_NOTXORPEN);
dc.MoveTo( ptStart );
dc.LineTo( ptCur ); // 画旧的,等于刷除上一条
dc.SetROP2(nROP); bStartDraw = FALSE; // 画完
::ReleaseCapture(); // 释放鼠标
ptEnd = point; // 现在,你已经得到两个点了:起始点和最终点来画一条直线了。
// 可以调用你那堆东西:
Draw(); //其实在这里又重新把以前有的图形重新画了
}
CScrollView::OnLButtonUp(nFlags, point);
}
CScrollView::Draw()
{
CDC* pDC=GetDC();
CRect rect;
GetClientRect(&rect);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap memBmp;
memBmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
memDC.SelectObject(&memBmp);
memDC.FillSolidRect(0,0,rect.Width(),rect.Height(),RGB(255,255,255)); memDC.Rectangle(CRect(50,50,200,200));//矩形 memDC.MoveTo(ptStart);
memDC.LineTo(ptEnd); //直线
pDC->BitBlt(50,50,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);//拷贝到客户区
}
我对您思路的理解是:
在动态画出跟随鼠标移动的直线后,重新刷新了底层图形,不然按照以上的代码应该实现不了我要的功能
橡皮筋应该可以画出来,我的苦恼是,在画出橡皮筋的同时,由于使用了SetROP2(R2_NOTXORPEN),使得直线移动过的区域有些点被擦拭掉了。呵呵!谢谢您的耐心指教!
当画一个图形例如点时,那么就画在这个BMP上..
当画了一百个图形时,根本就不需要重绘那已经画了的100个图形,因为已经都画在了那幅BMP上了,只需刷新帖图,那么实际上OnDraw()就只需要一句:
void CMyView::OnDraw( CDC *pDC )
{
if( m_pMemDC != NULL ){
pDC->BitBlt(xxxxxxxxx, m_pMemDC,XXXXXX);
}
}
ok,然后回到上面的画直线..由于直接画在客户区,根本不接触到BMP上,所以不会对已画的有任何影响,当结束时,才直接画在内存BMP上..然后Invalidate()..或许偶的表达能力有限,这里有个连接:http://d.download.csdn.net/down/181825/zhaobei1986
里面有周长发的ImageBoard的代码,绝对可以满足你的要求了..