C ++ win32项目双缓冲

时间:2011-03-14 11:11:14

标签: winapi double-buffering

我有一个win32应用程序,我想通过拖动鼠标绘制一条线。我也使用双缓冲,但问题是它在鼠标的路径中绘制了多行。这是我的绘图代码:

hdc = BeginPaint(hWnd, &ps);
hdcBack = CreateCompatibleDC(hdc); 
GetClientRect(hWnd, &windowRect); 
backBuffer = CreateCompatibleBitmap(hdc, windowRect.right, windowRect.bottom);
SelectObject(hdcBack, backBuffer); 
FloodFill(hdcBack, 0, 0, RGB(255, 255, 255)); 
BitBlt(hdcBack,0,0,windowRect.right,windowRect.bottom,hdc,0,0,SRCCOPY);
color = RGB(rand() % 255, rand() % 255, rand() % 255); 
hBrush = CreateSolidBrush(color); 
SelectObject (hdcBack, hBrush); 

MoveToEx(hdcBack,x1,y1,NULL); //x1,y1,x2,y2 are the initial click point and the current position of the mouse when keeping the left button down and dragging
LineTo(hdcBack,x2,y2);
BitBlt(hdc, 0, 0, windowRect.right, windowRect.bottom, hdcBack, 0, 0, SRCCOPY);

DeleteObject(hBrush); 
DeleteDC(hdcBack);
DeleteObject(backBuffer);
EndPaint(hWnd, &ps);

我还尝试在绘制线条之前不将背景复制到缓冲区中,并且正确绘制线条但是当我绘制新线条时,先前绘制的线条消失。 那么我如何使用双缓冲绘制多条线并保留先前绘制的线?

2 个答案:

答案 0 :(得分:1)

如果我理解正确的要求,问题是设计中固有的。

第一个BitBlt()之前的内容复制到缓冲区,然后绘制线条,然后将更改应用到屏幕,从而得到您描述的确切结果。这样你只需要添加图形而不是替换,你会看到几行而不是一行。

如果要显示被鼠标拖动的行,则需要首先使用您想到的任何背景(称为常量数据)填充后缓冲区,并且每次鼠标移动时,在其上绘制相关的图形(称之为更改数据)。无论如何,我认为评论第一个BitBlt()应该可以解决问题。

此外,在调用使用 pen 的行函数之前,您选择了画笔。在致电FloodFill()之前,不应该打电话吗?

编辑:

使用第三个缓冲区按照我对您的评论中的建议保存最新数据。在“鼠标悬停”处理程序中,最后在那个缓冲区上绘制新行 所以你在鼠标移动处理程序和on-paint处理程序中从读取,并在用户最终确定如何在鼠标向上处理程序中他希望画出他的画线。

答案 1 :(得分:0)

不使用后备缓冲区设计此方法的一种方法是保留每次绘制的动态线条列表。

你的消息proc看起来像这样:

  • WM_LBUTTONDOWN上,在列表中添加一个新行,并将当前位置作为开头。
  • WM_MOUSEMOVE上(左键向下),将列表中最新一行的结束位置更改为当前鼠标位置。

在每次重绘时,您只需遍历列表并绘制每一行。