屏幕截图和发送
要实现远程控制,被控端的屏幕监控是要解决的问题,在这里采用了屏幕截图发送的方式来实现屏幕实时监控
在此项目里把截取的图片保存为png格式,并存于内存流中在进行发送
//发送屏幕截图
int SendScreen() {
CImage screen;//GDI
//GetDC()功能作用:检索指定窗口的客户区的显示上下文环境句柄
//参数1:指定窗口句柄
//返回值:返回值表示指定窗口区域的DC句柄,失败返回NULL
HDC hScreen = ::GetDC(NULL);//获取设备上下文 拿到HDC屏幕句柄
//GetDeviceCaps()函数功能:获取DC的指定数据
//参数1:指定的HDC句柄
//参数2:指定定数据。BITSPIXEL:像素相连颜色位数, HORZRES:宽, VERTRES:高
int nBitPerPixel = GetDeviceCaps(hScreen, BITSPIXEL);//获取设备网络属性
int nWidth = GetDeviceCaps(hScreen, HORZRES);//宽
int nHeight = GetDeviceCaps(hScreen, VERTRES);//高
screen.Create(nWidth, nHeight, nBitPerPixel);//创建屏幕
BitBlt(screen.GetDC(), 0, 0, 1920, 1020, hScreen, 0, 0, SRCCOPY);//把图像复制到screen中
ReleaseDC(NULL, hScreen);//释放
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, 0);//调整大小,在内存中分配一个全局的堆
if (hMem == NULL)return-1;
IStream* pStream = NULL;//建立内存流
HRESULT ret = CreateStreamOnHGlobal(hMem, TRUE, &pStream);//在全局对象上设置内存流
if (ret == S_OK) {
screen.Save(pStream, Gdiplus::ImageFormatPNG);//图像保存到内存流中
LARGE_INTEGER bg = {0};
pStream->Seek(bg, STREAM_SEEK_SET, NULL);//从头开始设置,把流指针指向头
PBYTE pData = (PBYTE)GlobalLock(hMem);//上锁,用于读取数据
SIZE_T nSize = GlobalSize(hMem);//获取大小
CPacket pack(6, pData, nSize);//封装成包
CServerSocket::getInstance()->Send(pack);//发送包
GlobalUnlock(hMem);//解锁
}
//释放
pStream->Release();
GlobalFree(hMem);
screen.ReleaseDC();
return 0;
}