C++窗口标题显示乱码问题求助(Visual Studio环境)
C++ Win32窗口标题乱码问题解决
问题描述
在Visual Studio中开发基础C++ Win32项目,调用Win32 API创建窗口时,设置标题为"Yes"出现乱码,仅单字符标题显示正常,IDE无报错。
问题代码
#include <windows.h> bool running = true; void* buffer_memory; BITMAPINFO buffer_bitmap_info; LRESULT CALLBACK window_callback(HWND hwnd, UINT uMSG, WPARAM wParam, LPARAM lParam) { LRESULT result = 0; switch (uMSG) { case WM_CLOSE: case WM_DESTROY: { running = false; } break; case WM_SIZE: { RECT rect; GetClientRect(hwnd, &rect); int buffer_width = rect.right - rect.left; int buffer_height = rect.bottom - rect.top; int buffer_size = buffer_width * buffer_height * sizeof(unsigned int); if (buffer_memory) VirtualFree(buffer_memory, 0, MEM_RELEASE); buffer_memory = VirtualAlloc(0, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); buffer_bitmap_info.bmiHeader.biSize = sizeof(buffer_bitmap_info.bmiHeader); buffer_bitmap_info.bmiHeader.biWidth = buffer_width; buffer_bitmap_info.bmiHeader.biHeight = -buffer_height; buffer_bitmap_info.bmiHeader.biPlanes = 1; buffer_bitmap_info.bmiHeader.biBitCount = 32; buffer_bitmap_info.bmiHeader.biCompression = BI_RGB; } break; default: { result = DefWindowProc(hwnd, uMSG, wParam, lParam); } } return result; } int main() { return WinMain(GetModuleHandle(NULL), NULL, GetCommandLineA(), SW_SHOW); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { // Create Window Class WNDCLASSA window_class = {}; window_class.style = CS_HREDRAW | CS_VREDRAW; window_class.lpszClassName = "Game_Window_Class"; window_class.lpfnWndProc = window_callback; // Register Class RegisterClassA(&window_class); // Create Window CreateWindowA(window_class.lpszClassName, "Yes", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 1920, 1080, 0, 0, hInstance, 0); while (running) { // Input MSG message; while (PeekMessageA(&message, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&message); DispatchMessageA(&message); } // Simulate // Render } return 0; }
问题原因
Visual Studio默认项目字符集为Unicode字符集,此时Win32 API的通用宏会自动映射到宽字符版本,但代码中显式使用了ANSI版本的API(CreateWindowA、RegisterClassA等),同时字符串字面量未做编码匹配处理,导致编码不兼容出现乱码。单字符标题正常是因为ASCII单字符在多数编码中兼容。
解决方法
提供两种可行方案,任选其一即可:
方案1:切换项目字符集为多字节字符集
- 在Visual Studio中右键项目 → 属性
- 进入"配置属性" → "常规"
- 将"字符集"设置为"使用多字节字符集"
- 重新编译运行,此时ANSI版本API与字符集匹配,乱码问题解决
方案2:改用Unicode版本API
修改代码,统一使用宽字符版本的Win32 API和字符串:
#include <windows.h> bool running = true; void* buffer_memory; BITMAPINFO buffer_bitmap_info; LRESULT CALLBACK window_callback(HWND hwnd, UINT uMSG, WPARAM wParam, LPARAM lParam) { LRESULT result = 0; switch (uMSG) { case WM_CLOSE: case WM_DESTROY: { running = false; } break; case WM_SIZE: { RECT rect; GetClientRect(hwnd, &rect); int buffer_width = rect.right - rect.left; int buffer_height = rect.bottom - rect.top; int buffer_size = buffer_width * buffer_height * sizeof(unsigned int); if (buffer_memory) VirtualFree(buffer_memory, 0, MEM_RELEASE); buffer_memory = VirtualAlloc(0, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); buffer_bitmap_info.bmiHeader.biSize = sizeof(buffer_bitmap_info.bmiHeader); buffer_bitmap_info.bmiHeader.biWidth = buffer_width; buffer_bitmap_info.bmiHeader.biHeight = -buffer_height; buffer_bitmap_info.bmiHeader.biPlanes = 1; buffer_bitmap_info.bmiHeader.biBitCount = 32; buffer_bitmap_info.bmiHeader.biCompression = BI_RGB; } break; default: { result = DefWindowProc(hwnd, uMSG, wParam, lParam); } } return result; } int main() { return WinMain(GetModuleHandle(NULL), NULL, GetCommandLineW(), SW_SHOW); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) { // Create Window Class WNDCLASSW window_class = {}; window_class.style = CS_HREDRAW | CS_VREDRAW; window_class.lpszClassName = L"Game_Window_Class"; window_class.lpfnWndProc = window_callback; // Register Class RegisterClassW(&window_class); // Create Window CreateWindowW(window_class.lpszClassName, L"Yes", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 1920, 1080, 0, 0, hInstance, 0); while (running) { // Input MSG message; while (PeekMessageW(&message, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&message); DispatchMessage(&message); } // Simulate // Render } return 0; }
修改点说明:
- 将
WNDCLASSA改为WNDCLASSW,RegisterClassA改为RegisterClassW - 将
CreateWindowA改为CreateWindowW,字符串字面量前加L前缀(如L"Yes") WinMain的参数LPSTR改为LPWSTR,GetCommandLineA改为GetCommandLineWPeekMessageA改为PeekMessageW
补充说明
如果希望代码兼容两种字符集,可以使用Win32的通用宏(如WNDCLASS、RegisterClass、CreateWindow),字符串使用TEXT("Yes")或_T("Yes"),此时会根据项目字符集自动切换ANSI/Unicode版本。
内容的提问来源于stack exchange,提问作者cf404
相关产品推荐
相关产品推荐

