64,654
社区成员
发帖
与我相关
我的任务
分享
void CClientDlg::OnOK()
{
CDC* pDeskDC = GetDesktopWindow()->GetDC(); //获取桌面画布对象
CRect rc;
GetDesktopWindow()->GetClientRect(rc); //获取屏幕的客户区域
CDC memDC; //定义一个内存画布
memDC.CreateCompatibleDC(pDeskDC); //创建一个兼容的画布
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDeskDC,rc.Width(),rc.Height()); //创建兼容位图
memDC.SelectObject(&bmp); //选中位图对象
BITMAP bitmap;
bmp.GetBitmap(&bitmap);
int panelsize = 0; //记录调色板大小
if (bitmap.bmBitsPixel<16) //判断是否为真彩色位图
panelsize = pow(2,bitmap.bmBitsPixel*sizeof(RGBQUAD));
BITMAPINFO *pBInfo = (BITMAPINFO*)LocalAlloc(LPTR,sizeof(BITMAPINFO)+panelsize);//分配堆空间
pBInfo->bmiHeader.biBitCount = bitmap.bmBitsPixel;
pBInfo->bmiHeader.biClrImportant = 0;
pBInfo->bmiHeader.biCompression = 0;
pBInfo->bmiHeader.biHeight = bitmap.bmHeight;
pBInfo->bmiHeader.biPlanes = bitmap.bmPlanes;
pBInfo->bmiHeader.biSize = sizeof(BITMAPINFO);
pBInfo->bmiHeader.biSizeImage = bitmap.bmWidthBytes*bitmap.bmHeight;
pBInfo->bmiHeader.biWidth = bitmap.bmWidth;
pBInfo->bmiHeader.biXPelsPerMeter = 0;
pBInfo->bmiHeader.biYPelsPerMeter = 0;
memDC.BitBlt(0,0,bitmap.bmWidth,bitmap.bmHeight,pDeskDC,0,0,SRCCOPY);//该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境
char* pData = new char[bitmap.bmWidthBytes* bitmap.bmHeight];
::GetDIBits(memDC.m_hDC,bmp,0,bitmap.bmHeight,pData,pBInfo,DIB_RGB_COLORS);//GetDIBits函数检取指定位图的信息,并将其以指定格式复制到一个缓冲区中
int BufSize = panelsize+ sizeof(BITMAPINFO)+bitmap.bmWidthBytes*bitmap.bmHeight;
Bitmap* mmage;
mmage = Bitmap::FromBITMAPINFO(pBInfo,pData);//使用已经存在的信息来创建一个bitmap,返回值为指针
CLSID clsid;
GetCodecClsid(L"image/jpeg", &clsid);
HGLOBAL m_hMem = GlobalAlloc(GMEM_MOVEABLE, 0);//内存句柄,但不是指针
IStream *pstm=NULL;//一种字节序列,流
CreateStreamOnHGlobal(m_hMem, TRUE, &pstm);//从指定内存创建流对象
mmage->Save(pstm,&clsid,NULL);
m_JpegSize = GlobalSize(m_hMem);
LPBYTE lpData = (LPBYTE)GlobalLock(m_hMem);
m_Addr.sin_family = AF_INET;
m_Addr.sin_port = htons(5002);
m_Addr.sin_addr.S_un.S_addr = inet_addr(m_ServerIP);
m_Bmpsize = GraphSize;
//计算每个位图发送的次数
m_Count = m_JpegSize / GraphSize;
m_Mod = m_JpegSize % GraphSize;
if ( m_Mod != 0)
m_Count+=1;
m_FrameIndex = 0;
memcpy(m_pSendBuf,lpData,m_JpegSize);
//发送数据 块大小 总大小 块数 缓冲区指针
int ret = SendData(m_FrameIndex,m_Mod,GraphSize,m_JpegSize,m_Count,m_pSendBuf,m_Addr);
memDC.DeleteDC();
pDeskDC->DeleteDC();
pstm->Release();
if (mmage)
delete mmage;
delete [] pData;
GlobalUnlock(m_hMem);
GlobalFree(m_hMem);
::LocalFree((HLOCAL)pBInfo);
bmp.DeleteObject();
}
int CClientDlg::SendData(UINT index, int mod , int bmpsize , int totalsize ,int frames,
char *pSendBuf, sockaddr_in &addr)
{
/*序号2位||结束标记2位||JPG数据||JPG数据大小4位||JPG数据总大小4位||数据报大小4位*/
char* pPackage;
int packsize = 0;
if ( mod ==0 || index != frames-1)
packsize = 2+2+bmpsize+4+4+4;//这里的包大小是怎么计算的?
else
packsize = 2+2+mod+4+4+4;
pPackage = new char[packsize];
memset(pPackage,0,packsize);
//填充数据报
*(WORD*)&pPackage[0] = index; //填充序号
if (index != frames-1) //填充结束标记
*(WORD*)&pPackage[2] = 0;
else
*(WORD*)&pPackage[2] = 1;
//填充位图数据
pSendBuf += bmpsize*index;
memcpy(&pPackage[4],pSendBuf,packsize-12);
//填充位图大小
*(int*)&pPackage[packsize-12] = bmpsize;
//填充JPG数据总大小
*(int*)&pPackage[packsize-8] = totalsize;
//填充数据报大小
*(int*)&pPackage[packsize-4] = packsize;
m_Confirm = FALSE;
int ret = sendto(m_Socket,pPackage,packsize,0,(sockaddr*)&addr,sizeof(addr));
delete[] pPackage;
return ret;
}