WinAPI窗口无法显示问题求助(VS2022数字转二进制程序)
问题描述
我用Visual Studio 2022开发了一个基于WinAPI的C++程序,功能是将输入数字转换为二进制格式,但运行项目时窗口始终无法显示。我尝试修改窗口样式、调整窗口刷新位置等操作均未解决问题,附上程序代码如下:
#include "App.h" CApp::CApp() { using std::wstring; using std::string; try { this->init_native_window_obj(); this->create_native_controls(); } catch (const std::exception& e) { string expt_data = e.what(); MessageBox(nullptr, wstring(begin(expt_data), end(expt_data)).c_str(), L"Помилка", MB_ICONERROR | MB_OK); ExitProcess(EXIT_FAILURE); } } void CApp::init_native_window_obj() { using std::runtime_error; using namespace std::string_literals; WNDCLASSEX _wc{ sizeof(WNDCLASSEX) }; _wc.cbClsExtra = 0; _wc.cbWndExtra = 0; _wc.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); _wc.hCursor = LoadCursor(nullptr, IDC_ARROW); _wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION); _wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION); _wc.hInstance = GetModuleHandle(nullptr); _wc.lpfnWndProc = CApp::application_proc; _wc.lpszClassName = this->m_szClassName.c_str(); _wc.lpszMenuName = nullptr; _wc.style = CS_HREDRAW | CS_VREDRAW; if (!RegisterClassEx(&_wc)) throw runtime_error("Error, can't register main window class!"s); RECT _windowRC{ 0, 0, this->m_AppWidth, this->m_AppHeight }; AdjustWindowRect(&_windowRC, WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZE, false); if (this->m_hWnd = CreateWindowEx( 0, this->m_szClassName.c_str(), this->m_szAppName.c_str(), WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZE, (GetSystemMetrics(SM_CXSCREEN) - _windowRC.right) / 2, (GetSystemMetrics(SM_CYSCREEN) - _windowRC.bottom) / 2, _windowRC.right, _windowRC.bottom, nullptr, nullptr, nullptr, this ), !this->m_hWnd) throw runtime_error("Error, can't create main window"); } void CApp::create_native_controls() { using std::runtime_error; using namespace::std::string_literals; if (this->m_hWndButton = CreateWindowEx( 0, L"BUTTON", L"Перевести", WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 56, 108, 238, 37, this->m_hWnd, reinterpret_cast<HMENU>(CApp::CTL_ID::CALCBUTTON_ID), nullptr, nullptr ), !this->m_hWndButton) throw runtime_error("Error, can't create button!"s); if (this->m_hWndEdit = CreateWindowEx( WS_EX_CLIENTEDGE, L"EDIT", L"256", WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, 56, 66, 238, 24, this->m_hWnd, reinterpret_cast<HMENU>(CApp::CTL_ID::RESULTEDIT_ID), nullptr, nullptr ), !this->m_hWndEdit) throw runtime_error("Error, can't create edit!"s); HFONT hFont = CreateFont(18, 0, 0, 0, FW_REGULAR, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH, L"Roboto"); SendMessage(this->m_hWndEdit, WM_SETFONT, reinterpret_cast<WPARAM>(hFont), TRUE); SendMessage(this->m_hWndButton, WM_SETFONT, reinterpret_cast<WPARAM>(hFont), TRUE); } int CApp::Run() { MSG _msg{}; ShowWindow(this->m_hWnd, SW_SHOWDEFAULT); UpdateWindow(this->m_hWnd); while (GetMessage(&_msg, nullptr, 0, 0)) { TranslateMessage(&_msg); DispatchMessage(&_msg); } return static_cast<int>(_msg.wParam); } LRESULT CApp::application_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CApp* pApp; if (uMsg == WM_NCCREATE) { pApp = static_cast<CApp*>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams); SetLastError(0); if (!SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pApp))) { if (GetLastError() != 0) { return false; } } } else { pApp = reinterpret_cast<CApp*>(GetWindowLongPtr(hWnd, GWLP_USERDATA)); } if (pApp) { pApp->m_hWnd = hWnd; return pApp->window_proc(hWnd, uMsg, wParam, lParam); } return DefWindowProc(hWnd, uMsg, wParam, lParam); } LRESULT CApp::window_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: { PostQuitMessage(EXIT_SUCCESS); } return 0; case WM_COMMAND: { switch (static_cast<CApp::CTL_ID>(LOWORD(wParam))) { case CApp::CTL_ID::CALCBUTTON_ID: { try { std::wstring text{}; text.resize(MAX_PATH); GetWindowText(this->m_hWndEdit, &text[0], MAX_PATH); text.erase(remove(begin(text), end(text), 0), end(text)); if (text.empty()) { MessageBox(this->m_hWnd, L"Введіть число!", L"Інформація", MB_ICONINFORMATION | MB_OK); break; } std::string binary = std::bitset<16>(std::stoi(text)).to_string(); text = std::wstring(begin(binary), end(binary)); SetWindowText(this->m_hWndEdit, text.c_str()); } catch(...) { MessageBox(this->m_hWnd, L"error", MB_ICONINFORMATION | MB_OK); } } break; } } return 0; } } CApp::~CApp() {}
问题分析与解决
核心问题
窗口过程未处理默认消息
你的window_proc函数仅处理了WM_DESTROY和WM_COMMAND消息,其余所有消息都没有返回值,也未调用DefWindowProc处理。WinAPI窗口依赖DefWindowProc处理绘制、尺寸调整等基础消息,缺失这一步会导致窗口无法正常渲染显示。窗口样式错误
CreateWindowEx中使用了WS_MAXIMIZE,这是窗口显示状态标志,不属于窗口样式范畴,应该改用WS_MAXIMIZEBOX(仅添加最大化按钮),否则会导致窗口创建逻辑异常。成员变量未初始化
代码中用到的m_szClassName、m_szAppName、m_AppWidth、m_AppHeight等成员变量没有初始化代码。如果这些变量为空或0,会导致窗口类注册失败,或者窗口尺寸为0,自然无法看到窗口。
修复方案
1. 修复窗口过程函数
在window_proc的switch末尾添加默认分支,将未处理的消息交给DefWindowProc处理:
LRESULT CApp::window_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: { PostQuitMessage(EXIT_SUCCESS); } return 0; case WM_COMMAND: { switch (static_cast<CApp::CTL_ID>(LOWORD(wParam))) { case CApp::CTL_ID::CALCBUTTON_ID: { // 保留原有按钮逻辑 } break; } } return 0; // 处理所有未覆盖的消息 default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } }
2. 修正窗口样式
修改CreateWindowEx和AdjustWindowRect中的样式参数,移除WS_MAXIMIZE:
// init_native_window_obj函数中 RECT _windowRC{ 0, 0, this->m_AppWidth, this->m_AppHeight }; AdjustWindowRect(&_windowRC, WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, false); this->m_hWnd = CreateWindowEx( 0, this->m_szClassName.c_str(), this->m_szAppName.c_str(), WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, (GetSystemMetrics(SM_CXSCREEN) - _windowRC.right) / 2, (GetSystemMetrics(SM_CYSCREEN) - _windowRC.bottom) / 2, _windowRC.right, _windowRC.bottom, nullptr, nullptr, nullptr, this );
3. 初始化成员变量
在CApp类定义中初始化必要的成员变量:
class CApp { private: // 初始化窗口类名、标题、宽高 const std::wstring m_szClassName = L"BinaryConverterWindowClass"; const std::wstring m_szAppName = L"数字转二进制工具"; const int m_AppWidth = 350; const int m_AppHeight = 200; // 其他成员变量... public: // 类的构造、析构、成员函数... };
验证步骤
- 确保所有成员变量已正确初始化
- 替换修复后的代码片段
- 重新编译运行程序,窗口应该能正常显示并响应操作
内容的提问来源于stack exchange,提问作者butter3
相关产品推荐
相关产品推荐

