0

透明なウィンドウで GDIplus を使用して描画しようとすると、多くのちらつきが発生します。ダブルバッファリングまたはオフスクリーン サーフェスへのレンダリングの実装が役立つことを示唆する多くのスレッドを読みましたが、これは実行しましたが、役に立ちませんでした。

私が間違っていたことと、それを修正する方法について何か考えはありますか? ありがとう。

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

1 に答える 1

1

ウィンドウに属性がありWS_EX_TRANSPARENT、ウィンドウが無効になるたびにその下のウィンドウが再描画されます。削除してみてください。

の意味はWS_EX_TRANSPARENT、ウィンドウ サーフェス全体に描画しないこと (つまり、一部を透明のままにすること) を Windows に伝えることです。

于 2013-01-04T19:04:11.200 に答える