2

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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 3
    Some basic troubleshooting should be followed here to isolate the area of the program causing this. For instance, if you comment out the "Update" and "Draw" lines in your message pump, and interact with your program the same way, does the issue occur? If not, then you know where to start narrowing it down. If so, then that stuff is unrelated and you can eliminate it from consideration. Continue like this with all areas of your program. The result will be a minimal code example on which to base your question. Or you may discover a bug in your code that caused it. – paddy Aug 23 '22 at 05:18

1 Answers1

0
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.