C++:为什么这个窗口标题会被截断?

Wan*_*gZm 13 c++ winapi

Visual C++ 2012 RC,Win7

简体中文

项目属性>使用多字节字符集

当我运行这个程序时,窗口的标题显示单个字母"S",而不是整个单词"Sample".

#pragma comment(linker, "/SubSystem:Windows")

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int) {
    WNDCLASSW wc = { 0 };

    wc.style            = CS_VREDRAW | CS_HREDRAW;
    wc.hInstance        = hInstance;
    wc.hIcon            = LoadIcon(nullptr, IDI_APPLICATION);
    wc.hCursor          = LoadCursor(nullptr, IDC_ARROW);
    wc.hbrBackground    = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
    wc.lpszClassName    = L"MyWindowClass";

    wc.lpfnWndProc = [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
        if (uMsg - WM_DESTROY)
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
        else {
            PostQuitMessage(0);
            return HRESULT();
        }
    };

    RegisterClassW(&wc);

    CreateWindowExW(0, L"MyWindowClass", L"Sample",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, SW_SHOW, CW_USEDEFAULT, 0,
        nullptr, nullptr, hInstance, nullptr);

    for (MSG msg; GetMessage(&msg, nullptr, 0, 0); DispatchMessage(&msg));
}
Run Code Online (Sandbox Code Playgroud)

如果我使用Unicode(项目属性),保持源代码不变,窗口标题显示"Sample",看起来正确.

如果我使用多字节,在源代码中我使用WNDCLASS = {...,"MyWindowClass"}和RegisterClassA,保持CreateWindowExW不变,窗口标题显示单词"Sample",看起来正确.

如果我使用多字节,在源代码中我使用CreateWindowExA("MyWindowClass","Sample"),保持WNDCLASSW和RegisterClassW不变,窗口标题显示字母"S".

是什么让它显示单一的"S",我做错了什么?

附加

如果我保持全部不变,即使用多字节,使用上面显示的代码,窗口标题显示字母"S".

(如果你运行这个程序并在窗口标题上看到"Sample"而不是"S",那么它更可能是chc版本的vc ++ 2012(或OS)上的一个特定问题.

ten*_*our 22

您的代码中的问题是您正在使用DefWindowProc而不是DefWindowProcW.更改它将修复代码.

理想情况下,您应该将项目设置更改为使用Unicode,而不是多字节字符集.这将简化一切,您可以像使用宏一样使用宏CreateWindowEx,RegisterClassEx而不是显式使用Unicode/ANSI版本.

正如其他人所说,这是字符集之间的不匹配.

理想情况下,您应该在所有相互交互的API调用之间匹配字符集.所以,如果你使用CreateWindowExW,你也应该使用RegisterClassExW,DefWindowProcW,DispatchMessageW...


Wer*_*nze 6

这是一个非常好的,学到了一些新东西!

你需要改变

return DefWindowProc(hWnd, uMsg, wParam, lParam);  
Run Code Online (Sandbox Code Playgroud)

if(IsWindowUnicode(hWnd))  
  return DefWindowProcW(hWnd, uMsg, wParam, lParam);  
else  
  return DefWindowProcA(hWnd, uMsg, wParam, lParam);
Run Code Online (Sandbox Code Playgroud)

或者甚至更好:坚持一种字符编码。充其量只是使用RegisterClass,CreateWindowEx等等,让编译器采用正确的 Unicode 或 ANSI 函数。