Как реализовать двойную буферизацию на C++ winapi?

Суть вопроса в том, что хочу реализовать перерисовку окна без мерцания, уже около недели хожу вокруг, да около, несколько книг посмотрел, но все равно не могу понять, как очистить старый вывод картинки в окно, не вызывая обновление окна с полной перерисовкой.
</#include <windows.h>
#include <tchar.h>
#include <xstring>
#include "resource.h"
#pragma comment(lib, "msimg32.lib")
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
TCHAR WinName[] = _T("Main Frame");
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR cmd, int mode) {
	WNDCLASS wc;
	wc.hInstance = hInstance;
	wc.lpszClassName = WinName;
	wc.lpfnWndProc = WndProc;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.lpszMenuName = NULL;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	hInst = hInstance;
	if (!RegisterClass(&wc))return 0;
	
	HWND hWnd = CreateWindow(WinName, _T("Моя программа"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
		360, 360, NULL, NULL, hInstance, NULL);
	ShowWindow(hWnd, mode);
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return 0;
}
typedef std::basic_string<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR>>String;
int xy, sy;
int r, g, b, maxX, maxY;
static HDC memBit;
HBRUSH hBrush;
RECT rt;
HBITMAP hBitmap;
SYSTEMTIME tm;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
	PAINTSTRUCT ps;
	HDC hds;
	switch (message) {
	case WM_CREATE:
		SetTimer(hWnd,1, 200, NULL);
		maxX = GetSystemMetrics(SM_CXSCREEN);
		maxY = GetSystemMetrics(SM_CYSCREEN);
		hds = GetDC(hWnd);
		memBit = CreateCompatibleDC(hds);
		hBitmap = CreateCompatibleBitmap(hds, maxX, maxY);
		SelectObject(memBit, hBitmap);
		PatBlt(memBit, 0, 0, maxX, maxY, WHITENESS);
		ReleaseDC(hWnd, hds);
		GetSystemTime(&tm);
		srand(tm.wMilliseconds);
		break;
	case WM_SIZE:
		xy = LOWORD(lParam);
		sy = HIWORD(lParam);
		break;
	case WM_TIMER:
		rt.right = (rt.left = rand() * xy / RAND_MAX) + rand()*xy / RAND_MAX / 2;
		rt.top = (rt.bottom = rand() * sy / RAND_MAX) - rand() * sy / RAND_MAX / 2;
		r = rand() * 225 / RAND_MAX;
		g= rand() * 225 / RAND_MAX;
		b= rand() * 225 / RAND_MAX;
		hBrush = CreateSolidBrush(RGB(r, g, b));
		FillRect(memBit, &rt, hBrush);
		DeleteObject(hBrush);
		InvalidateRect(hWnd, NULL, 0);
		break;
	case WM_PAINT:
		hds = BeginPaint(hWnd, &ps);
		BitBlt(hds, 0, 0, xy, sy, memBit, 0, 0, SRCCOPY);
		
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return(DefWindowProc(hWnd, message, wParam, lParam));
		break;
	}
}>
  • Вопрос задан
  • 150 просмотров
Пригласить эксперта
Ответы на вопрос 2
gbg
@gbg
Баянист. Тамада. Услуги.
Лучше просто возьмите OpenGL, выучите относительно нормальный инструмент.

А так вам нужно создать Bitmap, получить от него контекст и в него рисовать.
А потом при помощи bitblt переносить нарисованное из битмапа в окошко.

Вот мануал
Ответ написан
twobomb
@twobomb
Когда-то в универе делал пазл на винапи с использованием gdi+ , тоже была такая проблема, но я ее как-то решил. Правда когда я запустил свой пазл на универском компе там было 10 фпс навер и в итоге я переписал все на яву ну то не важно.
В общем может это гляньте, ну и гугл в помощь
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы