【问题标题】:C++ win32 project double bufferingC++ win32项目双缓冲
【发布时间】:2011-07-14 22:37:40
【问题描述】:

我有一个 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);

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

【问题讨论】:

    标签: winapi double-buffering


    【解决方案1】:

    如果我正确理解需求,问题就在设计中。

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

    如果你想显示一条被鼠标拖动的线,你需要先用你想到的任何背景填充后台缓冲区(称之为constant-data),然后每次鼠标移动都在其上绘制相关图形(称为更改数据)。无论如何,我相信首先评论BitBlt() 应该可以解决问题。

    此外,您在调用使用 pen 的线条函数之前选择了 画笔。那个电话不应该在打电话给FloodFill()之前来吗?

    编辑:

    按照我对您的评论中的建议,使用第三个缓冲区来保存最新数据。在您的“mouse-up”处理程序中,最后在 that 缓冲区上绘制新线。
    因此,您在鼠标移动处理程序和绘制处理程序中从该缓冲区读取,并在鼠标向上处理程序中写入到它,当用户最终确定如何他想画他的线。

    【讨论】:

    • 很抱歉我的问题有点不清楚。如果我评论第一个 BitBlt 它可以画一条线。但我想画多条线。但是当我开始画下一条线时,前一条就消失了。我希望它留下来。不知何故,我想保存背景,但只有在完全绘制一条线时。刷子是为了另一个目的。我应该删除它,但它不会影响我的代码。
    • 在这种情况下,您将需要另一个缓冲区,该缓冲区将超出鼠标移动处理程序的范围并包含最近的 应用 更改,并从中复制数据而不是hdc,在绘制拖线之前。我希望这能解决这个问题。
    【解决方案2】:

    在不使用后备缓冲区的情况下进行设计的一种方法是保留您每次绘制的线条的动态列表。

    您的消息过程可能如下所示:

    • WM_LBUTTONDOWN 上,以当前位置为起点向列表中添加新行。
    • WM_MOUSEMOVE(左键按下)上,将列表中最后一行的结束位置更改为当前鼠标位置。

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

    【讨论】:

    • 是的,这是正确的,但我不能使用这样的列表。要求是以某种方式使用第三个缓冲区并在那里保存背景,但仅在某些时候,我试图弄清楚何时。
    • 好的,那么你可以使用相同的原理,每次释放鼠标时将前缓冲区BitBlt到后缓冲区。然后在绘制的时候,先BitBlt backbuffer到front buffer,然后在最前面绘制当前行。
    猜你喜欢
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 2011-10-16
    • 2021-04-28
    • 2012-02-11
    • 2023-02-04
    • 2011-12-08
    相关资源
    最近更新 更多