帮助双缓冲
我创建了一个效果很好的动画,但它会闪烁。我需要双缓冲方面的帮助,因为我对此一无所知。
这是我的 onPaint() 中的代码:
VOID onPaint(HDC hdc)
{
Graphics graphics(hdc);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawEllipse(&pen, sf , 0, 10, 10);
}
它工作正常,但有闪烁。我尝试了这段代码,但它不起作用:
VOID onPaint(HDC hdc,HWND hWnd)
{
HDC hDC=GetDC(hWnd);;
HDC memDC = CreateCompatibleDC(hDC);
HBITMAP hMemBmp = CreateCompatibleBitmap(hDC,10,10);
HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC,hMemBmp);
BitBlt(hDC, 0, 0, 10, 10, memDC, 0, 0, SRCCOPY);
Graphics graphics(memDC);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawEllipse(&pen, sf , 0, 10, 10);
// Always select the old bitmap back into the device context
SelectObject(memDC, hOldBmp);
DeleteObject(hMemBmp);
DeleteDC(memDC);
}
I have created an animation which works fine, but it flicks. I need help with double-buffering since I don't know anything about it.
This is the code in my onPaint():
VOID onPaint(HDC hdc)
{
Graphics graphics(hdc);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawEllipse(&pen, sf , 0, 10, 10);
}
It works fine but with flicker. I tried this code but it didn't work:
VOID onPaint(HDC hdc,HWND hWnd)
{
HDC hDC=GetDC(hWnd);;
HDC memDC = CreateCompatibleDC(hDC);
HBITMAP hMemBmp = CreateCompatibleBitmap(hDC,10,10);
HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC,hMemBmp);
BitBlt(hDC, 0, 0, 10, 10, memDC, 0, 0, SRCCOPY);
Graphics graphics(memDC);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawEllipse(&pen, sf , 0, 10, 10);
// Always select the old bitmap back into the device context
SelectObject(memDC, hOldBmp);
DeleteObject(hMemBmp);
DeleteDC(memDC);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看来您只是过早地将屏外 DC 复制到显示器上。尝试将对 BitBlt 的调用向下移动四行,使其成为开始清理之前的最后一行,如下所示:
此代码的另一件事是,您已传递常量“10”作为关闭的宽度和高度-屏幕位图,以及将其用作执行复制的 BitBlt() 的宽度和高度参数。正在更新的窗口客户区可能比这个大得多。 “黑色方块”是将 10x10 屏幕外地图传输到窗口客户区域的结果。您可以尝试使用另一个 GDI 函数来获取屏幕上位图的尺寸,而不是在那里硬编码 10,或者至少可以 #define 宽度和高度值,并在参数中使用它们。
杀死你的另一件事可能是“graphics.DrawEllipse(&pen, sf, 0, 10, 10)”行中的“sf”——因为你创建了一个非常小的 10x10 地图,如果 ' sf' 是 0..10 之外的任何值,DrawEllipse() 调用会将椭圆完全放置在屏幕外地图中的可用像素之外。
因此,最重要的是,您可能希望使离屏地图的大小与窗口客户区域的大小相同,并确保向下移动 BitBlt() 调用,以便它在离屏地图上的所有绘图操作之后发生。
It looks like you're just prematurely copying the offscreen DC to the display. Try moving the call to BitBlt down four lines, to make it the last line before you start the clean-up, like so:
Another thing about this code, you've passed the constant '10' as the width and height of your off-screen bitmap, as well as using it for the width and height params to the BitBlt() that does the copy. Chances are the window client area being updated is very much larger than that. The 'black square' is a consequence of blitting the 10x10 off-screen map onto the window client area. Instead of hard-coding 10 there, you might try using another GDI function to obtain the dimensions of the on-screen bitmap, or at the very least you could #define width and height values, and use these in the params.
The other thing killing you is probably the 'sf' in the line "graphics.DrawEllipse(&pen, sf , 0, 10, 10)" -- since you've created an incredibly tiny 10x10 map, if the value of 'sf' is anything outside of 0..10, the DrawEllipse() call will place the ellipse entirely outside of the available pixels in your offscreen map.
So, bottom line, you probably want to make the offscreen map the same size as the window client area, and be sure to move the BitBlt() call down so that it happens after all the drawing ops on the off-screen map.