缓存HDC内容用于后续Direct2D绘制.

思路:把HDC里的内容保存到Direct2D格式的位图里,后续直接调用 renderTarget->DrawBitmap即可。本例中,位图将保存为类的字段。

本例中 COM 接口指针皆使用 com_ptr,这是 WinRT 的 COM 智能指针类,com_ptr<I>::get() 返回的是实际接口指针,put() 返回实际接口指针的指针。可以用 ATL 的 ComPtr 类代替,功能相同,但用法稍有不同。

缓存

假设已有 RichEdit Control 句柄 m_editBox,欲将其图像缓存到一个D2D位图里,后续要把位图绘制到 Render target 或 ID2D1DeviceContext 对象 m_ctx 上。字段 m_bitmap 作为位图缓存,字段 m_bmpRT 作为位图缓存的呈现目标(不会在绘制位图时真的用到,但要存)。

则可用如下代码把该编辑框的 DC 的内容复制到 m_bitmap 里:

cpp 复制代码
float dpiX, dpiY;
m_ctx->GetDpi(&dpiX, &dpiY);
auto dpiFactor = dpiX / 96.0f;

RECT rect;
GetClientRect(m_editBox, &rect);

// 先创建内存render target(BitmapRenderTarget),类似于创建内存DC,
// 不同之处在于不用手动创建、选择bitmap,D2D会自动完成该操作。
auto bmpRtPixelSize = D2D1::SizeU(rect.right, rect.bottom);
auto bmpRtSize = D2D1::SizeF(bmpRtPixelSize.width / dpiFactor, bmpRtPixelSize.height / dpiFactor);
auto bmpRtPixelFmt = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE);
HRESULT hr = m_ctx->CreateCompatibleRenderTarget(bmpRtSize, bmpRtPixelSize, bmpRtPixelFmt,
											   D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE,
											   m_bmpRT.put());

// 获取与 GDI 兼容的 render target 接口指针。
// 该接口仍然属于上面创建的 BitmapRenderTarget 对象(对 QueryInterface
// 的理解),所以尽管 gdiRT 本身没有 BeginDraw 方法,仍可调用 
// m_bmpRT->BeginDraw() 来使该对象处于正确状态。EndDraw() 同理。
com_ptr<ID2D1GdiInteropRenderTarget> gdiRT;
m_bmpRT->QueryInterface(gdiRT.put());
m_bmpRT->BeginDraw();
HDC rtDC{};
hr = gdiRT->GetDC(D2D1_DC_INITIALIZE_MODE_CLEAR, &rtDC);

// 把编辑框 DC 内容复制到 render target 的 DC 上
HDC hdc = GetDC(m_editBox);
BitBlt(rtDC, 0, 0, rect.right, rect.bottom, hdc, 0, 0,SRCCOPY);
ReleaseDC(m_editBox, hdc);

gdiRT->ReleaseDC(nullptr);
hr = m_bmpRT->EndDraw();
if (FAILED(hr)) {
	// 处理异常
}

m_bmpRT->GetBitmap(m_bitmap.put());

绘制到任意 ID2D1RenderTarget 或 ID2D1DeviceContext 上

直接调用 DrawBitmap 即可:

cpp 复制代码
m_ctx->DrawBitmap(m_bitmap.get());
相关推荐
汉克老师9 小时前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
智者知已应修善业12 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
云泽80814 小时前
C++11 核心特性全解:列表初始化、右值引用与移动语义实战
开发语言·c++
AI进化营-智能译站15 小时前
ROS2 C++开发系列12-用多态与虚函数构建可扩展的ROS2机器人行为模块
开发语言·c++·ai·机器人
Morwit15 小时前
QML组件之间的通信方案(暴露子组件)
c++·qt·职场和发展
qeen8715 小时前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
图码15 小时前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
handler0115 小时前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
zhouwy11315 小时前
Linux进程与线程编程详解
linux·c++
卧室小白16 小时前
Redis-哨兵模式
数据库·redis·缓存