推荐在包含windows.h前定义WIN32_LEAN_AND_MEAN宏,以跳过Shell、COM、RPC等非核心模块,避免头文件冗余和重定义冲突;若仅用GDI可加NOGDI,混用STL时需配合NOMINMAX防止min/max宏污染。

直接包含 windows.h 就能用,但得注意预处理器宏
Win32 API 不是独立库,而是 Windows SDK 提供的一组 C 风格函数声明和结构体定义,头文件入口就是 windows.h。但直接 #include <windows.h> 很可能编译失败或行为异常——因为默认会拉入大量不必要头文件,还可能和你的宏冲突。
推荐做法是显式控制头文件加载范围:
- 在包含
windows.h前定义WIN32_LEAN_AND_MEAN,跳过 Shell、COM、RPC 等非核心模块 - 如果只用 GDI,可再加
NOGDI;只用基本线程/内存操作,可加WIN32_NO_STATUS - 避免在全局头里无条件包含
windows.h,尤其和 STL 头混用时容易触发min/max宏污染(可用#define NOMINMAX抑制)
MessageBox 是最安全的入门验证函数
它不依赖额外初始化、不涉及句柄生命周期、参数简单,适合快速确认环境是否就绪。调用前确保链接了 user32.lib(MSVC 默认已链,MinGW 需显式加 -luser32)。
典型写法:
立即学习“C++免费学习笔记(深入)”;
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
int main() {
MessageBox(NULL, "Hello from Win32!", "Test", MB_OK);
return 0;
}
注意:NULL 作为父窗口句柄是合法的;字符串字面量默认是窄字符,若项目启用了 Unicode,则需用 TEXT("...") 或 L"...",否则可能显示乱码或截断。
字符串参数必须匹配 Unicode / ANSI 编译模式
Win32 API 实际有两套函数:带 A 后缀的是 ANSI 版(如 CreateWindowA),带 W 后缀的是宽字符版(如 CreateWindowW)。 CreateWindow 这类无后缀名只是宏,在 UNICODE 宏定义时展开为 W 版,否则为 A 版。
- VS 项目默认启用
UNICODE和_UNICODE,此时所有字符串参数必须是LPCWSTR(即const wchar_t*) - 用
TEXT("xxx")或_T("xxx")可自动适配,但前提是确保TCHAR相关宏一致启用 - 混用窄字符串和 Unicode 模式会导致编译错误(类型不匹配)或运行时静默失败(如窗口标题为空)
句柄(HANDLE、HWND 等)不是裸指针,别用 delete 或 free
Win32 中几乎所有资源都通过句柄抽象,它们是操作系统内部索引,不是堆内存地址。常见错误包括:
- 对
CreateFile返回的HANDLE调用delete—— 正确做法是CloseHandle - 把
GetDC返回的HDC当普通指针传给delete[]—— 应该用ReleaseDC - 误以为
HWND可以reinterpret_cast<void*>后释放 —— 它甚至不保证是有效地址,仅作标识用
所有句柄都必须用对应 API 销毁:CloseHandle、DestroyWindow、GlobalFree、HeapFree(取决于创建方式),且多数函数失败时返回 NULL 或 INVALID_HANDLE_VALUE,调用前务必检查。
Win32 API 的坑不在调用语法,而在隐式契约:线程模型、字符编码、资源所有权、错误码语义(GetLastError() 不是总被设置,有些函数用返回值直接表意)。哪怕一个 MessageBox 调用,背后也绑定了当前线程的模态消息循环和默认字符集。


















