C++中屏幕截图并发送
·
功能概述
- 该函数使用 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发送。
⚠️ 问题:
- 硬编码
2560x1520可能导致截图不完整 ❌。 - 缺少
screen.Save()失败检查 ❌。 - 未调用
Send(pack),可能丢失截图数据 ❌。
🔧 优化: ✔ 改成 nWidth, nHeight 适配不同屏幕。 ✔ 检查 screen.Save() 结果。 ✔ 确保 CPacket 发送截图数据。
更多推荐


所有评论(0)