桌面截图
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; }
文件传输。
相关文章推荐
- 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
- 应该知道的Linux技巧
- 27种设计模式介绍
- python 函数多实参处理
- 百度地图PopupOverlay点击事件
- ArrayList和LinkedList的区别
- linux学习(五) shell脚本(2)
- GetObject()
- UVA-1330 LA 3029 City Game(最大子矩阵)
- 不想提拔你,就是因为你只想把工作做好
- Android与Mina集成
- 面试题-查找一个数组是否存在数目大于一半的数
- sync()函数是做什么的?何时需要用它?
- python return语句
- ibatis小知识点
- 糊涂窗口综合症和Nagle算法
- iOS 5中的strong和weak关键字
- python函数全局变量和局部变量
- 体验输出字符中有多少个‘A
- x86和x64