【问题标题】:Why is my simple C++ Windows.h window so laggy?为什么我的简单 C++ Windows.h 窗口如此滞后?
【发布时间】:2022-01-15 14:22:01
【问题描述】:

我正在探索用 C++ 创建 Windows 应用程序的选项,今天我尝试了“Windows.h”。在我尝试将文本渲染到窗口之前,它工作得很好(除了大量的样板代码)。编译时间猛增到 20 秒左右,而且窗口非常滞后。有谁知道为什么这样一个基本的程序会这么慢?

Window.cpp:

#include "Window.h"
#include <vector>
#include <iostream>

LPCWSTR title = L"hello";
HWND textfield;

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CLOSE:
        DestroyWindow(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
        break;
    }
    
    textfield = CreateWindowW(L"STATIC", L"Text is here", 
        WS_VISIBLE | WS_CHILD | WS_BORDER, 20, 20, 300, 25, hWnd, NULL, NULL, NULL);

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

Window::Window()
    : m_hInstance(GetModuleHandle(nullptr))
{
    const wchar_t* CLASS_NAME = L"Kai Window Class";

    WNDCLASS wndClass = {};
    wndClass.lpszClassName = CLASS_NAME;
    wndClass.hInstance = m_hInstance;
    wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.lpfnWndProc = WindowProc;

    RegisterClass(&wndClass);

    DWORD style = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;

    std::vector<int> AspectRatio = {1920, 1080};

    RECT rect;
    rect.left = AspectRatio.at(0)/2;
    rect.top = AspectRatio.at(1)/2;
    rect.right = AspectRatio.at(0);
    rect.bottom = AspectRatio.at(1);

    AdjustWindowRect(&rect, style, false);

    m_hWnd = CreateWindowEx(
        0,
        CLASS_NAME,
        title,
        style,
        rect.left,
        rect.top,
        rect.right - rect.left,
        rect.bottom - rect.top,
        NULL,
        NULL,
        m_hInstance,
        NULL
    );

    ShowWindow(m_hWnd, SW_SHOW);
}

Window::~Window()
{
    const wchar_t* CLASS_NAME = L"Kai Window Class";

    UnregisterClass(CLASS_NAME, m_hInstance);
}

bool Window::ProcessMessages()
{
    MSG msg = {};

    while (PeekMessage(&msg, nullptr, 0u, 0u, PM_REMOVE))
    {
        if (msg.message == WM_QUIT)
        {
            return false;
        }

        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return true;
}

窗口.h:

#pragma once

#include <Windows.h>
#include <Vector>

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

class Window
{
public:
    Window();
    Window(const Window&) = delete;
    Window& operator = (const Window&) = delete;
    ~Window();

    bool ProcessMessages();

private:
    HINSTANCE m_hInstance;
    HWND m_hWnd;
};

Main.cpp:

#include <iostream>
#include "Window.h"

int main()
{
    std::cout << "Creating Window...\n";

    Window* pWindow = new Window();


    bool running = true;
    while (running)
    {
        if (!pWindow->ProcessMessages())
        {
            std::cout << "Closing Window...\n";
            running = false;
        }

        // Render

        Sleep(10);
    }

    delete pWindow;

    return 0;
}

【问题讨论】:

  • @drescherjm - 我带走了睡眠(10);虽然不幸的是,问题仍然存在。 . .
  • @JohnnyMopp 我会检查一下。谢谢!
  • 在每条窗口消息上调用CreateWindow 无济于事,但我不能说它是否会导致明显的延迟。您可以在创建父窗口时创建一次子控件,或者在 WM_PAINT 中绘制文本,而不是使用控件,如果这样更可取。
  • 关于编译时间长。 Windows.h 是一个 huge 标头,编译器需要很长时间才能解析。你应该把它放在一个预编译的头文件中。

标签: c++ windows graphics


【解决方案1】:

这很慢,因为每次你的窗口字段消息时你都在创建一个窗口

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CLOSE:
        DestroyWindow(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
        break;
    }
    
    ///////////// This should not be here .....
    textfield = CreateWindowW(L"STATIC", L"Text is here", 
        WS_VISIBLE | WS_CHILD | WS_BORDER, 20, 20, 300, 25, hWnd, NULL, NULL, NULL);
    /////////////

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

您希望创建一次标签,而不是每次调用窗口过程。一个好地方是WM_CREATE 处理程序,即

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        textfield = CreateWindowW(L"STATIC", L"Text is here", WS_VISIBLE | WS_CHILD | WS_BORDER, 20, 20, 300, 25, hWnd, NULL, NULL, NULL);
        return 0;
    case WM_CLOSE:
        DestroyWindow(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
        break;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多