您的位置:首页 > 其它

桌面截图

2013-12-02 18:26 323 查看
HANDLE DDBtoDIB(HBITMAP bitmap,DWORD dwCompression,HPALETTE hPal,DWORD *sizeimage)
{
BITMAP              bm;
BITMAPINFOHEADER    bi;
LPBITMAPINFOHEADER     lpbi;
DWORD             dwLen;          //颜色位图的大小
HANDLE            hDib;
HANDLE            handle;
HDC               hdc;

//不支持BI_BITFIELDS类型
if( dwCompression == BI_BITFIELDS )
return NULL;

//如果调色板为空,则用默认调色板
if (hPal==NULL)
hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE );

//获取位图信息
GetObject(bitmap,sizeof(bm),(LPSTR)&bm);

//初始化位图信息头
bi.biSize        = sizeof(BITMAPINFOHEADER);
bi.biWidth        = bm.bmWidth;
bi.biHeight         = bm.bmHeight;
bi.biPlanes         = 1;
bi.biBitCount        = bm.bmPlanes * bm.bmBitsPixel;
bi.biCompression    = dwCompression;
bi.biSizeImage        = 0;
bi.biXPelsPerMeter    = 0;
bi.biYPelsPerMeter    = 0;
bi.biClrUsed        = 0;
bi.biClrImportant    = 0;

//计算信息头及颜色表大小
int ncolors = (1 << bi.biBitCount);     //左移
if( ncolors> 256 )
ncolors = 0;
dwLen  = bi.biSize + ncolors * sizeof(RGBQUAD);   //颜色表的大小

hdc = GetDC(NULL);
hPal = SelectPalette(hdc,hPal,FALSE);    //将逻辑调色板(放在内存中的调色板)选入设备上下文中,第三个函数设为FALSE是为了不让逻辑设备调色板将物理调色板覆盖
RealizePalette(hdc);

//为信息头及颜色表分配内存
hDib = GlobalAlloc(GMEM_FIXED,dwLen);    //分配指定的内存空间

if (!hDib){
SelectPalette(hdc,hPal,FALSE);   //如果失败,则需要恢复原先的调色板
ReleaseDC(NULL,hdc);
return NULL;
}

lpbi = (LPBITMAPINFOHEADER)hDib;
*lpbi = bi;
//调用 GetDIBits 计算图像大小
GetDIBits(hdc, bitmap, 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS );

bi = *lpbi;
//图像的每一行都对齐(32bit)边界
if (bi.biSizeImage == 0){
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;
if (dwCompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}

//重新分配内存大小,以便放下所有数据
dwLen += bi.biSizeImage;
if (handle = GlobalReAlloc(hDib, dwLen, GMEM_MOVEABLE))
hDib = handle;
else{
GlobalFree(hDib);

//重选原始调色板
SelectPalette(hdc,hPal,FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}

//获取位图数据
lpbi = (LPBITMAPINFOHEADER)hDib;

//最终获得的DIB
BOOL bgotbits = GetDIBits( hdc, bitmap,
0L,                      //扫描行起始处
(DWORD)bi.biHeight,      //扫描行数
(LPBYTE)lpbi             //位图数据地址
+ (bi.biSize + ncolors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi,      //位图信息地址
(DWORD)DIB_RGB_COLORS);  //颜色板使用RGB

if( !bgotbits )
{
GlobalFree(hDib);

SelectPalette(hdc,hPal,FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}

SelectPalette(hdc,hPal,FALSE);
ReleaseDC(NULL,hdc);
*sizeimage=bi.biSizeImage;
return hDib;          //得到设备无依赖位图
}


这是将依赖设备位图变为不依赖设备位图

BOOL CutScreen(LPTSTR FileName)
{
DWORD sizeimage;
HDC hdc=CreateDC("DISPLAY",NULL,NULL,NULL);
HDC CompatibleHDC= CreateCompatibleDC(hdc);
HBITMAP BmpScreen=CreateCompatibleBitmap(hdc,GetDeviceCaps(hdc,HORZSIZE),GetDeviceCaps(hdc,VERTSIZE));
SelectObject(CompatibleHDC,BmpScreen);
BitBlt(CompatibleHDC,0,0,GetDeviceCaps(hdc,HORZSIZE),GetDeviceCaps(hdc,VERTSIZE),hdc,0,0,SRCCOPY);

HANDLE    pbitmapwithoutfileh=DDBtoDIB(BmpScreen,BI_RGB,0,&sizeimage);

//设置位图信息头结构
BITMAPFILEHEADER bfh;
bfh.bfType=((WORD)('M'<<8)|'B');     //将单位设为MB
bfh.bfReserved1=0;
bfh.bfReserved2=0;
bfh.bfSize=54+sizeimage;
bfh.bfOffBits=54;

//创建位图文件
HANDLE hFile=CreateFile(FileName,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);

DWORD dwWrite;
// 写入位图文件头
WriteFile(hFile,&bfh,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
// 写入位图文件其余内容
WriteFile(hFile,pbitmapwithoutfileh,bfh.bfSize,&dwWrite,NULL);
DeleteDC(hdc);

CloseHandle(CompatibleHDC);

return TRUE;

}


得到位图

DWORD GetScreenProc(COMMAND command,SOCKET client)
{
char path[MAX_PATH];
GetTempPath(MAX_PATH,path);   // 得到保存在临时文件夹中的图片
strcat(path,"Screen.bmp");   //得到位图的完整路径
CutScreen(path);

COMMAND cmd;
FILEINFO fi;
memset((char*)&cmd,0,sizeof(cmd));
memset((char*)&fi,0,sizeof(fi));

cmd.ID=GetScreen;

CFile file;
int nChunkCount=0;
if(file.Open((char*)command.lparam ,CFile::modeRead | CFile::typeBinary) )   //打开文件
{
cout<<command.lparam<<endl;
int FileLen=(int)file.GetLength();    //获取文件长度
fi.FileLen=FileLen;
strcpy((char*)fi.FileName,file.GetFileName()) ;   //获取文件名称
memcpy((char*)&cmd.lparam ,(char*)&fi,sizeof(fi));
send(client,(char*)&cmd,sizeof(cmd),0);
nChunkCount=FileLen/CHUNK_SIZE;       //计算文件发送次数
if(FileLen%CHUNK_SIZE!=0)
{
nChunkCount++;
}
char *date=new char [CHUNK_SIZE];    //创建数据缓存区
for(int i=0;i<nChunkCount;i++)
{
int nLeft;
if(i+1==nChunkCount)
{
nLeft=FileLen-CHUNK_SIZE*(nChunkCount-1);
}
else
{
nLeft=CHUNK_SIZE;
}
int idx=0;
file.Read(date,CHUNK_SIZE); //将内容保存到date中
while(nLeft>0)
{
int ret=send(client,&date[idx],nLeft,0);   //发送文件
if(ret==SOCKET_ERROR)
{
cout<<"文件下载过程发生错误!"<<endl;
break;
}
nLeft-=ret;
idx+=ret;
}
}
cout<<"文件传输完成!"<<endl;
file.Close();
delete []date;
}
return 0;
}


文件传输。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: