GDI +在C ++中的双缓冲 [英] GDI+ double buffering in C++

查看:168
本文介绍了GDI +在C ++中的双缓冲的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有写过任何GDI一段时间现在(而不是与GDI +),我只是一个有趣的项目,但在我的生活,我不知道如何双缓冲GDI +

  void DrawStuff(HWND hWnd){
HDC hdc;
HDC hdcBuffer;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd,& ps); $ b $ h hdcBuffer = CreateCompatibleDC(hdc);
图形图形(hdc);
graphics.Clear(Color :: Black);

//绘图的东西,即兔子:

图像兔子(Lbunny.gif);
graphics.DrawImage(& bunny,0,0,bunny.GetWidth(),bunny.GetHeight());

BitBlt(hdc,0,0,WIDTH,HEIGHT,hdcBuffer,0,0,SRCCOPY);
EndPaint(hWnd,& ps);
}

上述作品(一切都完美呈现),但它闪烁。如果我改变图形图形(hdc); 图形图形(hdcBuffer); ,我什么也看不到我的消息管道设置正确(WM_PAINT调用DrawStuff),并且我强制一个WM_PAINT消息每个程序循环通过调用 RedrawWindow(window,NULL,NULL,RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);



I可能是错误的方式做这个,任何想法?

code> 解决方案

CreateCompatibleDC(hdc)创建具有1x1像素单色位图作为其绘图表面的DC。您还需要 CreateCompatibleBitmap 并将该位图选择到hdcBuffer中,如果您需要一个大于该值的绘图表面。



编辑:



当您执行此操作时,WM_ERASEBKGND会导致闪烁。

  hdc = BeginPaint(hWnd,& ps); 

在调用BeginPaint的过程中,Windows会向您的WndProc发送 WM_ERASEBKGND 消息,如果它认为后台需要重绘,如果你不处理该消息,那么DefWindowProc通过使用类刷子填充绘制矩形来处理它,因此为了避免闪烁,应该处理它并返回TRUE。

  case WM_ERASEBKGND:
return TRUE; //告诉Windows我们处理它。 (但实际上不绘制任何东西)

Windows认为您的背景应该被删除,因为你告诉它它应该,这是 RDW_ERASE 意味着,所以你应该可以离开你的 RedrawWindow 调用


I haven't written anything with GDI for a while now (and never with GDI+), and I'm just working on a fun project, but for the life of me, I can't figure out how to double buffer GDI+

void DrawStuff(HWND hWnd) {
    HDC          hdc;
    HDC          hdcBuffer;
    PAINTSTRUCT  ps;
    hdc = BeginPaint(hWnd, &ps);
    hdcBuffer = CreateCompatibleDC(hdc);
    Graphics graphics(hdc);
    graphics.Clear(Color::Black);

    // drawing stuff, i.e. bunnies:

    Image bunny(L"bunny.gif");
    graphics.DrawImage(&bunny, 0, 0, bunny.GetWidth(), bunny.GetHeight());  

    BitBlt(hdc, 0,0, WIDTH , HEIGHT, hdcBuffer, 0,0, SRCCOPY);
    EndPaint(hWnd, &ps);
}

The above works (everything renders perfectly), but it flickers. If I change Graphics graphics(hdc); to Graphics graphics(hdcBuffer);, I see nothing (although I should be bitblt'ing the buffer->hWnd hdc at the bottom).

My message pipeline is set up properly (WM_PAINT calls DrawStuff), and I'm forcing a WM_PAINT message every program loop by calling RedrawWindow(window, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);

I'm probably going about the wrong way to do this, any ideas? The MSDN documentation is cryptic at best.

解决方案

CreateCompatibleDC(hdc) creates a DC with a 1x1 pixel monochrome bitmap as its drawing surface. You need to also CreateCompatibleBitmap and select that bitmap into the hdcBuffer if you want a drawing surface larger than that.

Edit:

the flickering is being caused by WM_ERASEBKGND, when you do this

hdc = BeginPaint(hWnd, &ps);

Inside the call to BeginPaint, Windows sends your WndProc a WM_ERASEBKGND message if it thinks the background needs to be redrawn, if you don't handle that message, then DefWindowProc handles it by filling the paint rectangle with your class brush, so to avoid the flickering, you should handle it and return TRUE.

case WM_ERASEBKGND:
   return TRUE; // tell Windows that we handled it. (but don't actually draw anything)

Windows thinks your background should be erased because you tell it that it should, that's what RDW_ERASE means, so you should probably leave that out of your RedrawWindow call

这篇关于GDI +在C ++中的双缓冲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆