功能概述

  • 该函数使用 GDI(Graphics Device Interface) 进行屏幕截图,并将其存储为 PNG 格式。
  • 然后,它将截图数据打包到 CPacket(6, pData, nSize) 并发送出去(虽然 Send 代码缺失,但通常 CPacket 结构体用于网络传输)。
  • 代码最后清理资源,释放 HDC 句柄和 IStream 资源。

代码详解

1. 初始化 GDI 相关对象

CImage screen;// GDI
HDC hScreen = ::GetDC(NULL);
  • CImage screen用于存储屏幕截图CImage 是 MFC 提供的 GDI+ 图片类。
  • ::GetDC(NULL)获取整个屏幕的设备上下文(HDC),用于绘图。

2. 获取屏幕信息

int nBitPerPixel = GetDeviceCaps(hScreen, BITSPIXEL);// 24, 32 bit
int nWidth = GetDeviceCaps(hScreen, HORZRES);
int nHeight = GetDeviceCaps(hScreen, VERTRES);
  • BITSPIXEL:获取 屏幕颜色深度(24 或 32 位)。
  • HORZRES:屏幕 水平分辨率
  • VERTRES:屏幕 垂直分辨率

3. 创建图像对象

screen.Create(nWidth, nHeight, nBitPerPixel);

创建一个 CImage 对象,大小为 屏幕分辨率,颜色深度为 nBitPerPixel

4. 复制屏幕内容

BitBlt(screen.GetDC(), 0, 0, 2560, 1520, hScreen, 0, 0, SRCCOPY);
ReleaseDC(NULL, hScreen);
  • BitBlt():从 hScreen 复制屏幕图像到 screen
    • screen.GetDC():获取 CImage 的 HDC 进行绘制。
    • hScreen:屏幕的 HDC。
    • 问题BitBlt 目标宽高固定为 2560 x 1520,但屏幕分辨率可能不同(应使用 nWidth, nHeight)。
  • ReleaseDC(NULL, hScreen):释放屏幕 HDC 资源。

5. 申请全局内存

HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, 0);
if (hMem == NULL) return -1;

6. 创建 IStream

IStream* pstream = NULL;
HRESULT ret = CreateStreamOnHGlobal(hMem, TRUE, &pstream);

CreateStreamOnHGlobal():将 hMem 转换为 IStream 以支持 GDI+ 保存图片

7. 保存图像为 PNG

if (ret == S_OK) {
    screen.Save(pstream, Gdiplus::ImageFormatPNG);

使用 screen.Save() 将截图保存到 pstream,格式为 PNG

8. 读取 IStream 数据

LARGE_INTEGER  bg = { 0 };
pstream->Seek(bg, STREAM_SEEK_SET, NULL);
PBYTE pData = (PBYTE)GlobalLock(hMem);
SIZE_T nSize = GlobalSize(hMem);
  • 重置 IStream 位置(指针归零)。
  • 锁定 hMem 获取指针 pData
  • 获取 hMem 的大小 nSize,用于 CPacket 传输。

9. 发送数据

CPacket pack(6, pData, nSize);
GlobalUnlock(hMem);

封装 CPacket(6, pData, nSize),然后 Send(pack) 发送数据(代码缺失)

10. 释放资源

pstream->Release();
GlobalFree(hMem);
screen.ReleaseDC();

释放 IStream,释放 全局内存,释放 CImage 句柄

总结

功能

  • 使用 BitBlt 截屏并保存为 PNG
  • 将截图存入 IStream,封装 CPacket 发送。

⚠️ 问题

  1. 硬编码 2560x1520 可能导致截图不完整 ❌。
  2. 缺少 screen.Save() 失败检查 ❌。
  3. 未调用 Send(pack),可能丢失截图数据 ❌。

🔧 优化: ✔ 改成 nWidth, nHeight 适配不同屏幕。 ✔ 检查 screen.Save() 结果。 ✔ 确保 CPacket 发送截图数据

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐