M
M
Maxim Solovyov2020-10-24 11:28:13
C++ / C#
Maxim Solovyov, 2020-10-24 11:28:13

How to implement double buffering in C++ winapi?

The essence of the question is that I want to implement window redrawing without flickering, for about a week I have been going around and around, looked at several books, but still I can’t figure out how to clear the old image output to the window without causing a window update with a full redraw.

</#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;
  }
}>

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Armenian Radio, 2020-10-24
@gbg

Better just take OpenGL, learn a relatively normal tool.
And so you need to create a Bitmap, get a context from it and draw into it.
And then, using bitblt, transfer the drawing from the bitmap to the window.
Here is the manual

T
twobomb, 2020-10-24
@twobomb

Once at the university I made a puzzle on vinapi using gdi + , I also had such a problem, but I somehow solved it. True, when I launched my puzzle on a university computer, there were probably 10 fps, and in the end I rewrote everything in reality, well, it doesn’t matter.
In general, maybe take a look , well, Google to the rescue

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question