GDI + двойная буферизация в C++

Я ничего не записал с GDI некоторое время теперь (и никогда с GDI +), и я просто работаю над забавным проектом, но ни за что в жизни, я не могу выяснить как к двойному буферу 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);
}

Вышеупомянутые работы (все представляет отлично), но это мерцает. Если я изменяюсь Graphics graphics(hdc); кому: Graphics graphics(hdcBuffer);, Я ничего не вижу (хотя я должен быть bitblt'ing буфер-> hWnd hdc внизу).

Мой конвейер сообщения настраивается правильно (WM_PAINT называет DrawStuff), и я вызываю сообщение WM_PAINT каждый программный цикл путем вызова RedrawWindow(window, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);

Я, вероятно, иду о неправильном способе сделать это, какие-либо идеи? Документация MSDN является загадочной в лучшем случае

8
задан John Knoeller 19 March 2010 в 00:23
поделиться

2 ответа

CreateCompatibleDC (hdc) создает DC с монохромным растровым изображением размером 1x1 пиксель в качестве поверхности рисования. Вам также необходимо CreateCompatibleBitmap и выбрать это растровое изображение в hdcBuffer, если вы хотите, чтобы поверхность рисования была больше, чем это.

Изменить:

мерцание вызвано WM_ERASEBKGND, когда вы это делаете

hdc = BeginPaint(hWnd, &ps);

Внутри вызова BeginPaint, Windows отправляет вашему WndProc сообщение WM_ERASEBKGND , если он считает, что фон должен быть перерисовано, если вы не обрабатываете это сообщение, DefWindowProc обрабатывает его, заполняя прямоугольник рисования кистью вашего класса, поэтому, чтобы избежать мерцания, вы должны обработать его и вернуть TRUE.

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

Windows считает, что ваш фон должен быть удален, потому что вы говорите ему, что это должно быть, это то, что означает RDW_ERASE , поэтому вам, вероятно, следует исключить это из своего вызова RedrawWindow

{ {1}}
8
ответ дан 5 December 2019 в 14:02
поделиться

Вы обрабатываете WM_ERASEBKGND? Я полагаю, что он вызывается непосредственно перед WM_PAINT и обычно размывает цвет фона окна, чего вы, вероятно, не хотите.

2
ответ дан 5 December 2019 в 14:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: