桌面截图

  1 HANDLE DDBtoDIB(HBITMAP bitmap,DWORD dwCompression,HPALETTE hPal,DWORD *sizeimage)  
  2 {
  3     BITMAP              bm;
  4     BITMAPINFOHEADER    bi;
  5     LPBITMAPINFOHEADER     lpbi;
  6     DWORD             dwLen;          //颜色位图的大小
  7     HANDLE            hDib;
  8     HANDLE            handle;
  9     HDC               hdc;
 10 
 11     //不支持BI_BITFIELDS类型
 12     if( dwCompression == BI_BITFIELDS )
 13         return NULL;
 14 
 15     //如果调色板为空,则用默认调色板
 16     if (hPal==NULL)
 17         hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE );
 18 
 19     //获取位图信息
 20     GetObject(bitmap,sizeof(bm),(LPSTR)&bm);
 21 
 22     //初始化位图信息头
 23     bi.biSize        = sizeof(BITMAPINFOHEADER);
 24     bi.biWidth        = bm.bmWidth;
 25     bi.biHeight         = bm.bmHeight;
 26     bi.biPlanes         = 1;
 27     bi.biBitCount        = bm.bmPlanes * bm.bmBitsPixel;
 28     bi.biCompression    = dwCompression;
 29     bi.biSizeImage        = 0;
 30     bi.biXPelsPerMeter    = 0;
 31     bi.biYPelsPerMeter    = 0;
 32     bi.biClrUsed        = 0;
 33     bi.biClrImportant    = 0;
 34 
 35     //计算信息头及颜色表大小
 36     int ncolors = (1 << bi.biBitCount);     //左移
 37     if( ncolors> 256 ) 
 38         ncolors = 0;
 39     dwLen  = bi.biSize + ncolors * sizeof(RGBQUAD);   //颜色表的大小
 40 
 41     hdc = GetDC(NULL);
 42     hPal = SelectPalette(hdc,hPal,FALSE);    //将逻辑调色板(放在内存中的调色板)选入设备上下文中,第三个函数设为FALSE是为了不让逻辑设备调色板将物理调色板覆盖
 43     RealizePalette(hdc);
 44 
 45     //为信息头及颜色表分配内存
 46     hDib = GlobalAlloc(GMEM_FIXED,dwLen);    //分配指定的内存空间
 47 
 48     if (!hDib){
 49         SelectPalette(hdc,hPal,FALSE);   //如果失败,则需要恢复原先的调色板
 50         ReleaseDC(NULL,hdc);
 51         return NULL;
 52     }
 53 
 54     lpbi = (LPBITMAPINFOHEADER)hDib;
 55     *lpbi = bi;
 56     //调用 GetDIBits 计算图像大小
 57     GetDIBits(hdc, bitmap, 0L, (DWORD)bi.biHeight,
 58             (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS );
 59 
 60     bi = *lpbi;
 61     //图像的每一行都对齐(32bit)边界
 62     if (bi.biSizeImage == 0){
 63         bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)     
 64                         * bi.biHeight;
 65     if (dwCompression != BI_RGB)
 66             bi.biSizeImage = (bi.biSizeImage * 3) / 2;
 67     }
 68 
 69     //重新分配内存大小,以便放下所有数据
 70     dwLen += bi.biSizeImage;
 71     if (handle = GlobalReAlloc(hDib, dwLen, GMEM_MOVEABLE))
 72         hDib = handle;
 73     else{
 74         GlobalFree(hDib);
 75 
 76         //重选原始调色板
 77         SelectPalette(hdc,hPal,FALSE);
 78         ReleaseDC(NULL,hdc);
 79         return NULL;
 80     }
 81 
 82     //获取位图数据
 83     lpbi = (LPBITMAPINFOHEADER)hDib;
 84 
 85     //最终获得的DIB
 86     BOOL bgotbits = GetDIBits( hdc, bitmap,
 87                   0L,                      //扫描行起始处
 88                 (DWORD)bi.biHeight,      //扫描行数
 89                 (LPBYTE)lpbi             //位图数据地址
 90                 + (bi.biSize + ncolors * sizeof(RGBQUAD)),
 91                 (LPBITMAPINFO)lpbi,      //位图信息地址
 92                 (DWORD)DIB_RGB_COLORS);  //颜色板使用RGB
 93 
 94     if( !bgotbits )
 95     {
 96         GlobalFree(hDib);
 97         
 98         SelectPalette(hdc,hPal,FALSE);
 99         ReleaseDC(NULL,hdc);
100         return NULL;
101     }
102 
103     SelectPalette(hdc,hPal,FALSE);
104     ReleaseDC(NULL,hdc);
105     *sizeimage=bi.biSizeImage;     
106     return hDib;          //得到设备无依赖位图
107 }

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

 1 BOOL CutScreen(LPTSTR FileName)
 2 {
 3     DWORD sizeimage;
 4     HDC hdc=CreateDC("DISPLAY",NULL,NULL,NULL);
 5     HDC CompatibleHDC= CreateCompatibleDC(hdc);
 6     HBITMAP BmpScreen=CreateCompatibleBitmap(hdc,GetDeviceCaps(hdc,HORZSIZE),GetDeviceCaps(hdc,VERTSIZE));
 7     SelectObject(CompatibleHDC,BmpScreen);
 8     BitBlt(CompatibleHDC,0,0,GetDeviceCaps(hdc,HORZSIZE),GetDeviceCaps(hdc,VERTSIZE),hdc,0,0,SRCCOPY);
 9 
10     HANDLE    pbitmapwithoutfileh=DDBtoDIB(BmpScreen,BI_RGB,0,&sizeimage);
11     
12     //设置位图信息头结构
13     BITMAPFILEHEADER bfh;
14     bfh.bfType=((WORD)('M'<<8)|'B');     //将单位设为MB
15     bfh.bfReserved1=0;
16     bfh.bfReserved2=0;
17     bfh.bfSize=54+sizeimage;
18     bfh.bfOffBits=54;
19 
20     //创建位图文件
21     HANDLE hFile=CreateFile(FileName,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
22 
23     DWORD dwWrite;
24     // 写入位图文件头
25     WriteFile(hFile,&bfh,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
26     // 写入位图文件其余内容
27     WriteFile(hFile,pbitmapwithoutfileh,bfh.bfSize,&dwWrite,NULL);  
28     DeleteDC(hdc);
29 
30     CloseHandle(CompatibleHDC);
31 
32     return TRUE;
33 
34 }

得到位图

 1 DWORD GetScreenProc(COMMAND command,SOCKET client)
 2 {
 3     char path[MAX_PATH];
 4     GetTempPath(MAX_PATH,path);   // 得到保存在临时文件夹中的图片
 5     strcat(path,"Screen.bmp");   //得到位图的完整路径
 6     CutScreen(path);
 7 
 8     COMMAND cmd;
 9     FILEINFO fi;
10     memset((char*)&cmd,0,sizeof(cmd));
11     memset((char*)&fi,0,sizeof(fi));
12 
13     cmd.ID=GetScreen;
14 
15     CFile file;
16     int nChunkCount=0;
17     if(file.Open((char*)command.lparam ,CFile::modeRead | CFile::typeBinary) )   //打开文件
18     {
19         cout<<command.lparam<<endl;
20         int FileLen=(int)file.GetLength();    //获取文件长度
21         fi.FileLen=FileLen;
22         strcpy((char*)fi.FileName,file.GetFileName()) ;   //获取文件名称
23         memcpy((char*)&cmd.lparam ,(char*)&fi,sizeof(fi));
24         send(client,(char*)&cmd,sizeof(cmd),0);
25         nChunkCount=FileLen/CHUNK_SIZE;       //计算文件发送次数
26         if(FileLen%CHUNK_SIZE!=0)
27         {
28             nChunkCount++;
29         }
30         char *date=new char [CHUNK_SIZE];    //创建数据缓存区
31         for(int i=0;i<nChunkCount;i++)
32         {
33             int nLeft;
34             if(i+1==nChunkCount)
35             {
36                 nLeft=FileLen-CHUNK_SIZE*(nChunkCount-1);
37             }
38             else
39             {
40                 nLeft=CHUNK_SIZE;
41             }
42             int idx=0;
43             file.Read(date,CHUNK_SIZE); //将内容保存到date中
44             while(nLeft>0)
45             {
46                 int ret=send(client,&date[idx],nLeft,0);   //发送文件
47                 if(ret==SOCKET_ERROR)
48                 {
49                     cout<<"文件下载过程发生错误!"<<endl;
50                     break;
51                 }
52                 nLeft-=ret;
53                 idx+=ret;
54             }
55         }
56         cout<<"文件传输完成!"<<endl;
57         file.Close();
58         delete []date;
59     }
60     return 0;
61 }

文件传输。

原文地址:https://www.cnblogs.com/newworldcom/p/3454481.html