第一行Win32窗口代码需用WinMain入口、包含windows.h、链接user32.lib和gdi32.lib,并先用MessageBoxW(L"Hello",L"Test",MB_OK)验证环境;否则因Unicode未处理或库未链接将黑屏、返回NULL或乱码。

Windows API 不是 C++ 标准库的一部分,直接调用前必须显式包含头文件、链接对应库,并处理 Unicode 编码差异——否则 MessageBox 会黑屏、CreateWindowEx 返回 NULL、字符串参数全乱码。
怎么写第一行 Win32 窗口代码(不崩、能编、有响应)
Win32 程序入口不是 main(),而是 WinMain();不加 #include <windows.h></windows.h> 就连 HWND 类型都报错;不链接 user32.lib 和 gdi32.lib,链接器直接报 unresolved external symbol。
实操建议:
- 用
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)替代main - 在源文件顶部加
#include <windows.h></windows.h>(它已包含windowsx.h和常用子头) - MSVC 下项目属性 → 链接器 → 输入 → 附加依赖项里加上
user32.lib;gdi32.lib - 如果用 MinGW,编译时加
-luser32 -lgdi32 - 别急着写窗口过程函数——先用
MessageBox(NULL, L"Hello", L"Test", MB_OK);验证环境(注意L""前缀)
为什么 MessageBoxA 没反应,而 MessageBoxW 显示乱码
Windows API 有 ANSI 和 Wide 版本之分:MessageBoxA 接收 char*,MessageBoxW 接收 wchar_t*。但 VS 新建 Win32 项目默认定义了 UNICODE 和 _UNICODE 宏,导致 MessageBox 实际展开为 MessageBoxW。传入普通字符串字面量(如 "Hello")就会把 ASCII 字节当 UTF-16 解析,显示为方块或乱码。
立即学习“C++免费学习笔记(深入)”;
实操建议:
- 统一用宽字符:字符串前加
L,如L"确定要退出吗?" - 或临时取消宏定义:在
#include <windows.h></windows.h>前加#undef UNICODE和#undef _UNICODE(不推荐长期用) - 需要兼容窄字符时,显式调用
MessageBoxA并确保传char*,但 Windows 10+ 已基本弃用 ANSI 版本 - 读取命令行参数要用
GetCommandLineW()+CommandLineToArgvW(),而非argv
CreateWindowEx 返回 NULL 怎么查
返回 NULL 只说明创建失败,但不告诉你原因。常见真凶是:窗口类没注册、回调函数没设 CALLBACK 调用约定、父窗口句柄错传、样式冲突(比如同时用了 WS_CHILD 和 WS_POPUP)。
实操建议:
- 调用
CreateWindowEx后立刻跟DWORD err = GetLastError();,再用FormatMessage查错误描述 - 确保
RegisterClassEx成功返回非零值,且WNDCLASSEX.hInstance设对(通常是hInstance参数) - 窗口过程函数声明必须带
CALLBACK(即LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM)),否则栈被破坏 - 检查
lpClassName是否和注册时的字符串完全一致(区分大小写、无空格) - 调试时先用
WS_OVERLAPPEDWINDOW,别一上来就组合一堆自定义样式
真正卡住人的地方,往往不是函数不会写,而是错误没暴露出来——GetLastError() 必须紧跟失败 API 调用,隔一行就可能被其他系统调用覆盖;宽字符和 ANSI 的混用不会编译报错,但运行时弹窗内容全是问号或空白。这些细节不手动验证一遍,光看文档根本绕不过去。










