windows画图工具中的画直线是怎么实现的?

just_a_beginning 2009-07-26 04:23:43
我用SDK编了个,但画了一条直线,画第二条的时候,要是碰到第一条线的话,会被摸去的!
网上查了下,发现这样一种方法,但还有问题,希望高人指点。

static POINTS begin, end;


switch (message)
{
case WM_LBUTTONDOWN:
begin = end = MAKEPOINTS(lParam);
break;
case WM_MOUSEMOVE:
if(wParam & MK_LBUTTON)
{
hdc = GetDC(hWnd);
HPEN hPen = CreatePen(PS_SOLID, 0, RGB(255, 0, 0));
SelectObject(hdc, hPen);
SetROP2(hdc, R2_NOT);

MoveToEx(hdc, begin.x, begin.y, NULL);
LineTo(hdc, end.x, end.y);

end = MAKEPOINTS(lParam);
MoveToEx(hdc, begin.x, begin.y, NULL);
LineTo(hdc, end.x, end.y);

ReleaseDC(hWnd, hdc);
}
break;
。。。。
颜色还是黑色的,我明明设了红色的啊!
怎么样才能达到和windows画图工具中一样的效果啊,这样实现颜色改不了啊!!
...全文
2709 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sandy_zc_1 2009-07-27
  • 打赏
  • 举报
回复
囧,我引用错了。12楼是回复9楼的内容。
sandy_zc_1 2009-07-27
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 just_a_beginning 的回复:]
to 7楼:

你写的,和我1楼给出的有同样的问题,不信你弄个红色画笔选进DC试试
[/Quote]

你要把显示逻辑和绘制逻辑分开。
比如你的绘图工作区有一个DC,你要在上面用MSPaint那种方式画一条直线,那么你应该创建一个临时DC,拷贝进你绘图工作区的内容,然后往上面画,然后把结果呈现给用户。在MouseMove的时候你就不断地刷新临时DC里面的内容,直到用户放开鼠标,你再将这个最终结果拷贝回你的工作区DC。

虽然效率看起来低点,但是实际上对于用户的操作而言,这种耗时是微不足道的。如果你实在需要提高效率,可以采用脏矩形更新画面的局部。

再具体点就是这样:
1、将你真正需要画的目标DC上的内容使用BitBlt复制一份作为备份。(称之为DC2)
2、在DC上画线。
3、如果用户移动鼠标导致需要更新线的位置,则将备份的DC2上的内容用BitBlt复制回DC(即刷新回原状态),然后再在新的位置重新画线。
4、如果用户没有松开鼠标,则重复3,否则表明画线完毕,销毁或更新DC2。

在这个模型上稍加改进便可实现绘图的Undo、Redo操作。
giskook 2009-07-27
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 just_a_beginning 的回复:]
to 7楼:

你写的,和我1楼给出的有同样的问题,不信你弄个红色画笔选进DC试试
[/Quote]无意中把这事解决了,郁闷,呵呵。把SetROP2( htempDC, R2_NOT ); 换成SetROP2( htempDC, R2_NOT | R2_NOTXORPEN );包你没问题!
just_a_beginning 2009-07-27
  • 打赏
  • 举报
回复
to 7楼:

你写的,和我1楼给出的有同样的问题,不信你弄个红色画笔选进DC试试
just_a_beginning 2009-07-27
  • 打赏
  • 举报
回复
to 6楼 sandy_zc_1:

你能说详细点吗,我不明白啊,最好给点代码,谢谢啊!
giskook 2009-07-26
  • 打赏
  • 举报
回复
上面是实现画橡皮线。要画不同的颜色,那当然要有不同的画笔了。将画笔选入DC。PS:上述代码中line是
vector<Point> line
giskook 2009-07-26
  • 打赏
  • 举报
回复
case WM_LBUTTONDOWN:
{
POINT currentpoint;
currentpoint.x = GET_X_LPARAM( lParam );
currentpoint.y = GET_Y_LPARAM( lParam );
line.push_back( currentpoint );
oldpoint.x = line.rbegin()->x;
oldpoint.y = line.rbegin()->y;
}
break;
case WM_MOUSEMOVE:
{
POINT newpoint;
HDC htempDC;
htempDC = GetDC( hWnd );
newpoint.x = GET_X_LPARAM( lParam );
newpoint.y = GET_Y_LPARAM( lParam );
SetROP2( htempDC, R2_NOT );
if( !line.empty() )
{
//加上这个判断会很慢
// if( newpoint.x != oldpoint.x && newpoint.y != oldpoint.y )
{
MoveToEx( htempDC, line.rbegin()->x, line.rbegin()->y, NULL );
LineTo( htempDC, oldpoint.x, oldpoint.y );
MoveToEx( htempDC, line.rbegin()->x, line.rbegin()->y, NULL );
LineTo( htempDC, newpoint.x, newpoint.y );
oldpoint.x = newpoint.x;
oldpoint.y = newpoint.y;
}
}
ReleaseDC( hWnd, htempDC );
}
break;
sandy_zc_1 2009-07-26
  • 打赏
  • 举报
回复
MSPaint用的就是简单的LineTo。只是需要保存背景数据用于重绘。每次刷新的时候需要重绘整个图。
效率问题一般不用担心,BitBlt效率还是非常高的。如果你实在纠结于效率可以上脏矩形。
just_a_beginning 2009-07-26
  • 打赏
  • 举报
回复
也许是我表达的不清楚。
这不是我想要的效果啊。也先不考虑WM_PAINT消息。
我想问的是:
1,画的线可以按我指定的颜色画
2,线在画的过程中应该这样,我按下鼠标左键,然后鼠标拖到哪线就画到哪,在移动过程中就1条存在,就是
擦除重绘的一个过程。
3,第二条线经过第一条线时,不会把第一条线擦除。

我上面的程序,做到了2,3条啊,我看了windows自带的画图工具,它的画线工具很完美啊,就是要那种效果的饿。
just_a_beginning 2009-07-26
  • 打赏
  • 举报
回复
这样很没效率啊,而且画的过程中,还是会出现问题的啊
jtx100456 2009-07-26
  • 打赏
  • 举报
回复
那我觉得你可以这样,每画好一条直线,也就是OnLButtonUp()时使用Invalidate(0)重画窗口。但是前提是你要创建个CList类或者CArray类来保存每条画好的直线,然后再修改下OnDraw,把集合类中存着的直线一条条画出来
just_a_beginning 2009-07-26
  • 打赏
  • 举报
回复
那应该怎么样实现啊,这样在画的时候只能是黑色啊!画图工具中设成红色,画的时候就是红色啊!!
怎么实现呢??
jtx100456 2009-07-26
  • 打赏
  • 举报
回复
你设置的光栅操作是R2_NOT,绘图颜色就是屏幕颜色的反色
你之前估计是用了R2_NOTXORPEN,这样的话,被同一重复画的地方就会消失
实现Windows应用程序,功能类似Windows的“工具,其,“类型”分组框包含五个按钮:1) “笔”功能类似“”软件的“铅笔”,用户可以随意的绘制图形;2) “直线”功能类似“”软件的“直线”,用户可以绘制直线;3) “矩形”功能类似“”软件的“矩形”,用户可以绘制矩形;4) “椭圆”功能类似“”软件的“椭圆”,用户可以绘制椭圆;5) “多边形”功能类似“”软件的“多边形”,用户可以绘制多边形;(更多详细功能请参阅Windows”软件)其,“清空”按钮可以清空绘图区域的用户输入,“退出”按钮可以退出此应用程序。其,包含的菜单如下:1) “文件”菜单,“新建”子菜单可以清空整个绘图区域,“打开”和“保存”功能为选做,功能分别为可以打开一个图形文件和保存绘图区域的图形信息,如果有此两项功能,“新建”子菜单的功能需要做简单改动,可以创建一块二进制的绘图区域。2) “格式”菜单,“颜色”子菜单可以更改绘制的颜色,“线条”子菜单可以更改绘制的线条粗细程度,“背景”子菜单可以定义绘图区域的背景颜色。3) “帮助”菜单,“帮助精灵”可以提供简单的交互,比如当用户点击它的时候,它会说话,其他功能可以自由扩充。“关于本软件”提供本软件的基本说明,比如作者、日期等。

19,468

社区成员

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

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