SDK 抓屏程序

3 篇文章 0 订阅

    学习编程也有一段时间了,一开始想过抓屏是怎么做的。经过一段时间积累,确实有所长进呵。

    首先抓屏我认为分两个部份:首先取得某个窗口的句柄进而取得该窗口DC内容;其次由该窗口设备DC内容生成BMP文件。

我觉得这两个部份都是很重要的,因为不了解BMP文件结构就不可能创建标准BMP文件,还有window的设备DC,windows绘图有关的操作使用DC实现。Device Context。

   

  1. int   GetBmpPixels()
  2. {
  3.          int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);//屏幕尺寸
  4.     int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
  5.     HWND hDesktopWnd = GetDesktopWindow();//获得桌面窗口句柄
  6.     HDC hDesktopDC = GetDC(hDesktopWnd);  //获得对应桌面窗口的设备DC
  7.     HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);//创建内存设备兼容DC
  8.     HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight);//创建内存兼容位图
  9.     SelectObject(hCaptureDC,hCaptureBitmap);将位图和设备DC相联 
  10.     BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,hDesktopDC,0,0,SRCCOPY);//拷贝桌面内容到内存DC中 
  11.     if   (OpenClipboard(m_hWnd))   //m_hWnd为窗口句柄   
  12.     {   
  13.         //清空剪贴板   
  14.         EmptyClipboard();   
  15.         //把屏幕内容粘贴到剪贴板上,     
  16.         SetClipboardData(CF_BITMAP,hCaptureBitmap);   
  17.         //关闭剪贴板   
  18.         CloseClipboard();   
  19.     }
  20.          //保存到文件
  21.     SaveBitmapToFile(hCaptureBitmap,_T("src.bmp"));
  22.     ::ReleaseDC(hDesktopWnd,hDesktopDC);
  23.     DeleteDC(hCaptureDC);
  24.     DeleteObject(hCaptureBitmap);
  25. }
  26. int   SaveBitmapToFile(HBITMAP   hBitmap ,LPCTSTR   lpFileName)   //hBitmap   为刚才的屏幕位图句柄   
  27. {           //lpFileName   为位图文件名   
  28.     HDC                         hDC;                     
  29.     //设备描述表   
  30.     int                         iBits;               
  31.     //当前显示分辨率下每个像素所占字节数   
  32.     WORD                         wBitCount;         
  33.     //位图中每个像素所占字节数   
  34.     //定义调色板大小,   位图中像素字节大小 , 位图文件大小   ,   写入文件字节数   
  35.     DWORD   dwPaletteSize=0,dwBmBitsSize, dwDIBSize,dwWritten;   
  36.     BITMAP                 Bitmap;                   
  37.     //位图属性结构   
  38.     BITMAPFILEHEADER       bmfHdr;                   
  39.     //位图文件头结构   
  40.     BITMAPINFOHEADER       bi;                           
  41.     //位图信息头结构     
  42.     LPBITMAPINFOHEADER   lpbi;                       
  43.     //指向位图信息头结构   
  44.     HANDLE fh,   hDib,   hPal,hOldPal=NULL;   
  45.     //定义文件,分配内存句柄,调色板句柄   
  46.     //计算位图文件每个像素所占字节数   
  47.     hDC   =   CreateDC(_T("DISPLAY"),NULL,NULL,NULL);   
  48.     iBits   =   GetDeviceCaps(hDC,BITSPIXEL)* GetDeviceCaps(hDC,PLANES);   
  49.     DeleteDC(hDC);   
  50.     if   (iBits <= 1)   
  51.         wBitCount = 1;   
  52.     else   if   (iBits <= 4)   
  53.         wBitCount   =   4;   
  54.     else   if   (iBits   <=   8)   
  55.         wBitCount   =   8;   
  56.     else   if   (iBits   <=   24)   
  57.         wBitCount   =   24;  
  58.     else
  59.         wBitCount   =   32;
  60.     //计算调色板大小   
  61.     if   (wBitCount   <=   8)   
  62.         dwPaletteSize   =   (1<< wBitCount)*sizeof(RGBQUAD);   
  63.     //设置位图信息头结构   
  64.     GetObject(hBitmap,   sizeof(BITMAP),   (LPSTR)&Bitmap);   
  65.     bi.biSize                         =   sizeof(BITMAPINFOHEADER);   
  66.     bi.biWidth                       =   Bitmap.bmWidth;   
  67.     bi.biHeight                     =   Bitmap.bmHeight;   
  68.     bi.biPlanes                     =   1;   
  69.     bi.biBitCount                   =   wBitCount;   
  70.     bi.biCompression             =   BI_RGB;   
  71.     bi.biSizeImage                 =   0;   
  72.     bi.biXPelsPerMeter           =   0;   
  73.     bi.biYPelsPerMeter           =   0;   
  74.     bi.biClrUsed                   =   0;   
  75.     bi.biClrImportant             =   0;   
  76.     dwBmBitsSize   =   ((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight;   
  77.     //为位图内容分配内存   
  78.     hDib     =   GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));   
  79.     lpbi   =   (LPBITMAPINFOHEADER)GlobalLock(hDib);   
  80.     *lpbi   =   bi;   
  81.     //   处理调色板         
  82.     hPal   =   GetStockObject(DEFAULT_PALETTE);   
  83.     if   (hPal)   
  84.     {   
  85.         hDC     =   GetDC(NULL);   
  86.         hOldPal   =   SelectPalette(hDC,(HPALETTE)hPal,FALSE);   
  87.         RealizePalette(hDC);   
  88.     }   
  89.     //   获取该调色板下新的像素值   
  90.     GetDIBits(hDC,hBitmap,0,(UINT)Bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize, (LPBITMAPINFO)lpbi,   DIB_RGB_COLORS);   
  91.     //恢复调色板         
  92.     if   (hOldPal)   
  93.     {  
  94.         SelectPalette(hDC,(HPALETTE)hOldPal,   TRUE);   
  95.         RealizePalette(hDC);   
  96.         ReleaseDC(NULL,   hDC);   
  97.     }   
  98.     //创建位图文件           
  99.     fh   =   CreateFile(lpFileName,   GENERIC_WRITE, 0,   NULL,   CREATE_ALWAYS,   
  100.                                  FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);   
  101.     if   (fh   ==   INVALID_HANDLE_VALUE)   
  102.         return   FALSE;   
  103.     //   设置位图文件头   
  104.     bmfHdr.bfType   =   0x4D42;     //   "BM"   
  105.     dwDIBSize         =   sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;       
  106.     bmfHdr.bfSize   =   dwDIBSize;   
  107.     bmfHdr.bfReserved1   =   0;   
  108.     bmfHdr.bfReserved2   =   0;   
  109.     bmfHdr.bfOffBits   =   (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;   
  110.     //   写入位图文件头   
  111.     WriteFile(fh,(LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER),&dwWritten,NULL);   
  112.     //   写入位图文件其余内容   
  113.     WriteFile(fh,(LPSTR)lpbi,dwDIBSize,&dwWritten,NULL);   
  114.     //清除         
  115.     GlobalUnlock(hDib);   
  116.     GlobalFree(hDib);   
  117.     CloseHandle(fh);  
  118.     return 0;
  119. }  

至此程序已经能够将桌面整个屏幕保存成一个位图文件了。总结一下:

1.获得桌面窗口句柄      :GetDesktopWindow()

2.取得桌面窗口设备DC :GetDC(hDesktopWnd)

3.创建与设备兼容DC和位图,并将DC与位图绑定,将窗口设备DC内容拷贝到桌面窗口兼容DC中:

   CreateCompatibleDC(hDesktopDC);
   CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight);

   SelectObject(hCaptureDC,hCaptureBitmap);

   BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,hDesktopDC,0,0,SRCCOPY);

4.打开剪切板并将DC信息粘贴到剪切板中

   OpenClipboard(m_hWnd) //hWnd为程序窗口句柄   
    //清空剪贴板  
    EmptyClipboard();  
    //把屏幕内容粘贴到剪贴板上,    
    SetClipboardData(CF_BITMAP,hCaptureBitmap);  
    //关闭剪贴板  
    CloseClipboard();   

5. 保存到位图文件

   SaveBitmapToFile(hCaptureBitmap,_T("src.bmp"));

6.释放资源
   ReleaseDC(hDesktopWnd,hDesktopDC);
   DeleteDC(hCaptureDC);
   DeleteObject(hCaptureBitmap); 

//

过程即此,剩下仍有很多要做,现在只是简单的桌面窗口抓屏,可以提供接口实现多种窗口的抓屏,这些也是很多抓屏软件已经实现的。还没有预览和文件保存接口,再进一步即多种格式图片文件的支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值