帮助双缓冲

Ram*_*lol 2 c++ gdi doublebuffered

我已经创建了一个可以正常工作的动画,但是它很轻松.我需要双缓冲的帮助,因为我对它一无所知.

这是我onPaint()中的代码:

VOID onPaint(HDC hdc)
{
    Graphics graphics(hdc);
    Pen      pen(Color(255, 0, 0, 255));
    graphics.DrawEllipse(&pen, sf , 0, 10, 10);
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但闪烁.我试过这段代码,但它不起作用:

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);
}
Run Code Online (Sandbox Code Playgroud)

Jus*_*eff 9

看起来你只是过早地将屏幕外DC复制到显示器上.尝试将调用移动到BitBlt四行,使其成为开始清理之前的最后一行,如下所示:

VOID onPaint(HDC hdc,HWND hWnd)
{
    // this line looks a little odd :
    HDC hDC = GetDC(hWnd);
    // .. usually the hdc parameter passed to onPaint would already refer to
    // the on-screen DC that windows wants updated. Also worth noting is that
    // when you use GetDC(), you should have a matching ReleaseDC()
    // As a quick test, you might just replace the above line with
    //     HDC hDC = hdc;

    HDC memDC = CreateCompatibleDC(hDC);
    HBITMAP hMemBmp = CreateCompatibleBitmap(hDC,10,10);
    HBITMAP hOldBmp =  (HBITMAP)SelectObject(memDC,hMemBmp);

    // draw to the off-screen map ..
    Graphics graphics(memDC);
    Pen      pen(Color(255, 0, 0, 255));
    graphics.DrawEllipse(&pen, sf , 0, 10, 10);

    // now that you've drawn on the offscreen map, go ahead
    // and put it on screen.
    BitBlt(hDC, 0, 0, 10, 10, memDC, 0, 0, SRCCOPY);

    // Always select the old bitmap back into the device context
    SelectObject(memDC, hOldBmp);
    DeleteObject(hMemBmp);
    DeleteDC(memDC);
}
Run Code Online (Sandbox Code Playgroud)

关于这段代码的另一件事,你已经将常量'10'作为屏幕外位图的宽度和高度传递,并将其用于执行复制的BitBlt()的宽度和高度参数.机会是正在更新的窗口客户端区域比这大得多."黑色方块"是将10x10离屏地图映射到窗口客户区域的结果.您可以尝试使用另一个GDI函数来获取屏幕上位图的尺寸,或者至少可以#define宽度和高度值,而不是在那里使用硬编码10,并在参数中使用它们.

杀死你的另一件事可能就是"graphics.DrawEllipse(&pen,sf,0,10,10)"中的"sf" - 因为你创造了一个非常小的10x10地图,如果'sf'的值如果是0..10之外的任何内容,DrawEllipse()调用将把椭圆完全放在屏幕外地图中可用像素之外.

因此,在底线,您可能希望使屏幕外地图与窗口客户端区域的大小相同,并确保将BitBlt()调用向下移动,以便在屏幕外地图上的所有绘图操作之后发生.