Johan
Johan

Reputation: 317

GDIplus flickering

I'm trying to draw with GDIplus on an transparent window and experiencing a lot of flickering. I've read plenty of threads that suggest implementing double-buffering or rendering to offscreen surface would help, which I've done but to no avail.

Any idea what I've done wrong and how to fix it? Thanks.

#include <Windows.h>
#include <stdio.h>
#include <time.h>
#include <GdiPlus.h>

#pragma comment(lib, "GdiPlus.lib")

HWND hWnd = NULL;
WNDCLASSEX wcex;
HDC hdc = NULL;
PAINTSTRUCT ps;
HGDIOBJ hfDefault;
MSG msg;
COLORREF transKey = RGB(37,14,103);
ULONG_PTR m_gdiplusToken;

char window_title[9] = "testings";
char window_class[9] = "testings";

int window_width = GetSystemMetrics(SM_CXSCREEN);
int window_height = GetSystemMetrics(SM_CYSCREEN);

DWORD MainThread(LPVOID lpArgs)
{
    while(1)
    {
        RECT rc = {0,0,window_width,window_height};
        InvalidateRect(hWnd, &rc, false);
        UpdateWindow(hWnd);
        Sleep(50);
    }
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if(msg == WM_CREATE)
    {
        hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);

        Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

        SetLayeredWindowAttributes(hWnd, transKey, 128, LWA_COLORKEY);
    }
    else if(msg == WM_PAINT)
    {
        hdc = BeginPaint(hWnd, &ps);

        Gdiplus::Graphics g(hdc);

        g.Clear(Gdiplus::Color(37,14,103));

        Gdiplus::Bitmap* curBitmap = new Gdiplus::Bitmap(window_width, window_height);
        Gdiplus::Graphics* g1 = g.FromImage(curBitmap);

        static int x=1,y=1;
        // x += 3;
        y += 2;

        Gdiplus::Pen pen(Gdiplus::Color(255, 255, 0, 255));

        g1->DrawLine(&pen, x, y, window_width/2, window_height/2);

        g.DrawImage(curBitmap, 0, 0);

        EndPaint(hWnd, &ps);
    }
    else if(msg == WM_CLOSE)
    {
        DestroyWindow(hWnd);
    }
    else if(msg == WM_DESTROY)
    {
        PostQuitMessage(0);
    }
    else
    {
        return DefWindowProc(hWnd, msg, wParam, lParam);
    }

    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HBRUSH hbrBackground = CreateSolidBrush(transKey);

    wcex.cbSize        = sizeof(WNDCLASSEX);
    wcex.style         = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc   = WndProc;
    wcex.cbClsExtra    = 0;
    wcex.cbWndExtra    = 0;
    wcex.hInstance     = hInstance;
    wcex.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = hbrBackground;
    wcex.lpszMenuName  = NULL;
    wcex.lpszClassName = window_class;
    wcex.hIconSm       = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    if(!RegisterClassEx(&wcex))
        return 1;

    hWnd = CreateWindowEx(
        WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
        window_class,
        window_title,
        WS_POPUP,
        0,
        0,
        window_width,
        window_height,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if(!hWnd)
        return 1;

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)MainThread, NULL, NULL, NULL);

    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    Gdiplus::GdiplusShutdown(m_gdiplusToken);
    return msg.wParam;
}

Upvotes: 0

Views: 1461

Answers (1)

Mark Ransom
Mark Ransom

Reputation: 308520

You have the WS_EX_TRANSPARENT attribute on your window, which causes the window underneath it to repaint every time your window is invalidated. Try removing it.

The meaning of WS_EX_TRANSPARENT is to tell Windows that you won't be drawing on the full window surface (i.e. leaving parts of it transparent), so it needs to make sure everything underneath is rendered first so it can show through.

Upvotes: 1

Related Questions