Normally, even when using double buffering, when resizing a window, it seems that it's inevitable that the flickering will happen.
Step 1, the original window.
Step 2, the window is resized, but the extra area hasn't been painted.
Step 3, the window is resized, and the extra area has been painted.
Is it possible somehow to hide setp 2? Can I suspend the resizing process until the painting action is done?
Here's an example:
#include <Windows.h>
#include <windowsx.h>
#include <Uxtheme.h>
#pragma comment(lib, "Uxtheme.lib")
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL MainWindow_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct);
void MainWindow_OnDestroy(HWND hWnd);
void MainWindow_OnSize(HWND hWnd, UINT state, int cx, int cy);
void MainWindow_OnPaint(HWND hWnd);
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex = { 0 };
HWND hWnd;
MSG msg;
BOOL ret;
wcex.cbSize = sizeof(wcex);
wcex.lpfnWndProc = WindowProc;
wcex.hInstance = hInstance;
wcex.hIcon = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
wcex.hCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
wcex.lpszClassName = TEXT("MainWindow");
wcex.hIconSm = wcex.hIcon;
if (!RegisterClassEx(&wcex))
{
return 1;
}
hWnd = CreateWindow(wcex.lpszClassName, TEXT("CWin32"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);
if (!hWnd)
{
return 1;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (ret == -1)
{
return 1;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
HANDLE_MSG(hWnd, WM_CREATE, MainWindow_OnCreate);
HANDLE_MSG(hWnd, WM_DESTROY, MainWindow_OnDestroy);
HANDLE_MSG(hWnd, WM_SIZE, MainWindow_OnSize);
HANDLE_MSG(hWnd, WM_PAINT, MainWindow_OnPaint);
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
BOOL MainWindow_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
BufferedPaintInit();
return TRUE;
}
void MainWindow_OnDestroy(HWND hWnd)
{
BufferedPaintUnInit();
PostQuitMessage(0);
}
void MainWindow_OnSize(HWND hWnd, UINT state, int cx, int cy)
{
InvalidateRect(hWnd, NULL, FALSE);
}
void MainWindow_OnPaint(HWND hWnd)
{
PAINTSTRUCT ps;
HPAINTBUFFER hpb;
HDC hdc;
BeginPaint(hWnd, &ps);
hpb = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &hdc);
FillRect(hdc, &ps.rcPaint, GetStockBrush(DKGRAY_BRUSH));
Sleep(320); // This simulates some slow drawing actions.
EndBufferedPaint(hpb, TRUE);
EndPaint(hWnd, &ps);
}
Is it possible to eliminate the flickering?
I've already set the hbrBackground to NULL
, that was a mistake. – HubeWM_ERASEBACKGROUND
. – Expiratory