-
-
[原创] 兼容全系统的DWM绘制
-
发表于:
2026-8-30 15:23
1151
-
目前仅在 Windows 11 25H2 系统 使用NVIDIA显卡驱动 物理机环境下测试有效
源码在文章最后
位于 dwmcore.dll 的 COverlayContext::Present
函数原型 (win11 24h2 以前的旧版本)
在win11 24h2更新后变为 (win11 24h2 及以上版本)
其中的 a2 参数指向一个 IOverlaySwapChain 类对象
不同系统需要使用不同的Hook回调
不同系统的函数头部特征均有变化,可以使用winbindex获取不同系统的 dwmcore.dll 文件
Winbindex - The Windows Binaries Index
其中 win11 22h2 和 win11 23h2 函数特征相同
在 win11 24h2 及以前的系统,可通过偏移值直接获取到 IDXGISwapChain 类对象,然后通过 IDXGISwapChain->GetBuffer 获取后备缓冲区
在win11 25h2 及以后的系统重构了 COverlayContext 的内存布局
调用 IOverlaySwapChain 虚函数表索引24的 CLegacySwapChain::GetPhysicalBackBuffer 获取 CLegacySwapChainBuffer
再调用 CLegacySwapChainBuffer 虚函数表索引19的 CLegacySwapChainBuffer::GetD3D11Resource 获取D3D11Resource
将指针类型从 IUnknown* 转换为强类型的 ID3D11Texture2D*,并内部调用 AddRef 增加一次引用计数。
最后得到后备缓冲区
注意:需要手动设置ImGui 当前渲染目标(后备缓冲区)的尺寸
DWM 没有窗口句柄,ImGui 无法自动获取客户区尺寸。如果不手动设置,DisplaySize 会保持为 0,导致 ImGui 无法计算布局,所有绘制命令都不会生成
win11 25h2 物理机

然后我们进入游戏,设置全屏模式或窗口化全屏模式,我们的绘制又又又失效了。原因是启用了Independent Flip(独立翻转)。画面直接交给显示器,不再经过DWM进程了。
Independent Flip(独立翻转)
WDDM 1.3+ 引入的 DXGI 翻转模型高级输出模式,游戏 / 应用帧直接交给显示硬件扫描输出,完全绕过 DWM 用户态合成
Composed Flip(合成翻转)
Windows DXGI 翻转呈现模型(Flip Model)下的一种窗口化呈现状态,应用交换链缓冲区与 DWM(桌面窗口管理器)共享、并由 DWM 完成桌面画面合成后再输出
WDDM 3.2
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
最后于 2026-8-30 15:26
被mb_pelomxiq编辑
,原因: