严肃学习本套开源项目课程:https://github.com/DG-AF/DX12-Quick-Tutorial.git
001-InitWindow
DX12 快速教程(1) —— 做窗口_dx12开发-CSDN博客
引入 Windows 窗口编程、DX12 核心、COM 组件相关的头文件,并通过#pragma comment链接必要的系统库;
静态封装与入口设计
通过 static Run 函数统一管理引擎的生命周期。这种设计将“实例化、初始化、循环运行”封装在一个黑盒内,使 WinMain 主函数保持极其简洁,仅作为程序触发点。
窗口属性(宽高、句柄 HWND)作为私有成员,体现了“数据与行为绑定”的封装思路,为后续 DX12 渲染器获取绘图目标提供了明确的上下文。
窗口生命周期的三部曲
Windows 窗口程序的构建遵循一个标准的线性逻辑:
注册 (Register): 使用 WNDCLASS 告知操作系统:我们要创建一个什么样的窗口,并绑定最关键的回调函数 (Callback)。
实例化 (Create & Show): 此时操作系统分配内存,生成窗口句柄 m_hwnd。注意代码中显式调用 ShowWindow,这是因为样式设置(WS_SYSMENU 等)锁定了默认显示行为,需手动唤醒。
消息循环 (Message Loop): 程序不再是线性执行完即结束,而是进入一个无限死循环。
Peek vs Get: 代码使用了 PeekMessage(非阻塞)而非 GetMessage(阻塞)。这是典型的游戏引擎设计思路:即使没有操作系统消息,循环也应继续运行(用于后续逐帧渲染渲染器内容)。
回调与异步通信机制
这是 Win32 开发中最核心的设计模式:
控制权解耦: 程序员编写 CallBackFunc,但从不主动调用它。它由 DispatchMessage 触发,由操作系统在特定事件(如点击关闭、调整大小)发生时回拨。
静态约束: 关键设计点在于 CallBackFunc 必须是 static 的。这是因为 Win32 API 是 C 风格的,无法直接处理 C++ 的 this 指针。
状态转换: WM_DESTROY $\rightarrow$ PostQuitMessage(0) $\rightarrow$ WM_QUIT。
这是一个典型的状态链:用户点击按钮 $\rightarrow$ 发出销毁信号 $\rightarrow$ 信号转为退出消息 $\rightarrow$ 循环检测到 WM_QUIT 后终止。
Q:为什么需要句柄?
A:Windows 是多任务操作系统,同时会运行成百上千个窗口、进程、设备。如果直接操作内存地址,会有两个致命问题:
- 内存地址不稳定:系统可能随时调整对象的实际内存位置(比如内存分页、碎片整理)。
- 安全风险:程序直接访问内存会导致越权操作、系统崩溃。
所以 Windows 设计了 “句柄机制”,系统在内部维护一个 “句柄 - 对象” 的映射表,给程序返回一个句柄。


