Home > Blockchain >  Window theme changes unintentionally
Window theme changes unintentionally

Time:08-26

When I first run the program, the window's theme is Windows 11 (as intended):

image

However, after a few frame updates, the theme changes to a previous version of Windows, and the title text also disappears:

image

This is my Framework class:

#include "Framework.h"

LRESULT CALLBACK Framework::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    Framework* pThis = nullptr;
    if (msg == WM_CREATE)
    {
        CREATESTRUCT* pcs = reinterpret_cast<CREATESTRUCT*>(lParam);
        pThis = reinterpret_cast<Framework*>(pcs->lpCreateParams);
        SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
    }
    else
    {
        pThis = reinterpret_cast<Framework*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
    }

    if (pThis)
        return pThis->OnProcessMessage(hwnd, msg, wParam, lParam);
    else
        return DefWindowProc(hwnd, msg, wParam, lParam);
}

LRESULT Framework::OnProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if(mRenderer)
        return mRenderer->OnProcessMessage(hwnd, msg, wParam, lParam);

    return NULL;
}

void Framework::Run()
{
    RECT r;
    GetClientRect(mWinHandle, &r);
    mWidth = r.right - r.left;
    mHeight = r.bottom - r.top;

    std::atexit(ReportLiveObjects);
    ShowWindow(mWinHandle, SW_SHOWNORMAL);

    mRenderer = make_shared<DX12Renderer>();
    mRenderer->Init(mWinHandle, mWidth, mHeight);
    mRenderer->BuildObjects();

    MsgLoop();

    DestroyWindow(mWinHandle);
}

void Framework::Init(const string& winTitle, uint32_t width, uint32_t height)
{
    const WCHAR* className = L"Main Window";

    // Register the window class
    WNDCLASSEX wc = {};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = GetModuleHandle(NULL);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW   1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = className;
    wc.hIconSm = LoadIcon(wc.hInstance, IDI_APPLICATION);

    if (RegisterClassEx(&wc) == 0)
    {
        return;
    }

    // Window size we have is for client area, calculate actual window size
    RECT r{ 0, 0, (LONG)width, (LONG)height };

    int windowWidth = r.right - r.left;
    int windowHeight = r.bottom - r.top;

    // create the window
    wstring wTitle = stringTowstring(winTitle);
    mWinHandle = CreateWindow(className, wTitle.c_str(),
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        windowWidth, windowHeight, NULL, NULL,
        GetModuleHandle(NULL), this);

    if (mWinHandle == nullptr)
    {
        return;
    }
}

void Framework::MsgLoop()
{
    MSG msg{};

    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            mRenderer->Update();
            mRenderer->Draw();
        }
    }
}

And this is my WinMain() function:

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int mCmdShow)
{
    #if defined(DEBUG) || defined(_DEBUG)
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    #endif
        try
        {
            Framework app;
            app.Init("Chulsu Renderer");
            app.Run();
        }
        catch (std::exception& ex)
        {
            MessageBoxA(nullptr, ex.what(), "ERROR", MB_OK);
            return -1;
        }
    return 0;
}

Lastly, message input processing functions:

LRESULT DX12Renderer::OnProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_ACTIVATE:
        break;

    case WM_SIZE:
        mSwapChainSize.x = LOWORD(lParam);
        mSwapChainSize.y = HIWORD(lParam);
        if (wParam == SIZE_MAXIMIZED)
        {
            OnResize();
        }
        else if (wParam == SIZE_RESTORED)
        {
            if (mDevice) {
                OnResize();
            }
        }
        break;

    case WM_ENTERSIZEMOVE:
        break;

    case WM_EXITSIZEMOVE: 
        OnResize();
        break;

    case WM_GETMINMAXINFO:
        reinterpret_cast<MINMAXINFO*>(lParam)->ptMinTrackSize = { 200, 200 };
        break;

    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
        OnProcessMouseDown(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
        break;

    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
        OnProcessMouseUp(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
        break;

    case WM_MOUSEMOVE:
        OnProcessMouseMove(wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
        break;

    case WM_KEYDOWN:
    case WM_KEYUP:
        if (wParam == VK_ESCAPE)
        {
            PostQuitMessage(0);
            return 0;
        }
        OnProcessKeyInput(msg, wParam, lParam);
        break;

    case WM_MENUCHAR:
        
        return MAKELRESULT(0, MNC_CLOSE);

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

void DX12Renderer::OnResize()
{
}

void DX12Renderer::OnProcessMouseDown(WPARAM buttonState, int x, int y)
{
}

void DX12Renderer::OnProcessMouseUp(WPARAM buttonState, int x, int y)
{
}

void DX12Renderer::OnProcessMouseMove(WPARAM buttonState, int x, int y)
{
}

void DX12Renderer::OnProcessKeyInput(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
}

void DX12Renderer::Update()
{
}

If you need full codes, here's a GitHub page:

https://github.com/kcjsend2/Chulsu

It's a DirectX12 Win32 application, but I think the DirectX12 layer probably has nothing to do with this problem.

UPDATE:

Seriously, this problem is really odd.

When I replace Framework::OnProcessMessage() like this:

LRESULT Framework::OnProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_KEYDOWN:
        case WM_KEYUP:
            if (wParam == VK_ESCAPE) {
                PostQuitMessage(0);
                return 0;
            }
            break;
    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

Then it works well.

But no matter what's in the function, if I return mRenderer->OnProcessMessage(), it just makes the bug above.

CodePudding user response:

LRESULT Framework::OnProcessMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (mRenderer)
        return mRenderer->OnProcessMessage(hwnd, msg, wParam, lParam);

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

problem was because of OnProcessMessage returns few NULLs when Renderer is not initialized.

change it to return DefWindowProc, it fixed problem.

  • Related