• 基于visual c++之windows核心编程代码分析(40)实现屏幕截取


    屏幕截取器(Screen scraper)是允许一台 PC 来从主机上截取基于字符的数据和显示它在一个更容易了解的图形用户界面(GUI)上的一类软件。现在更新的屏幕截取器在 HTML 上显示信息,因此它能够用一个浏览器来访问。区别屏幕截取与常规剖析的关键因素在于被截取的输出是名义上送给人类消费,而不是机器解释。有很多屏幕截取的同义词在那里:数据抓取、数据萃取、网络抓取、网页包装和 HTML 抓取(后四个特定用于抓取 web 页面)。

    我们都体验过QQ的截图功能特别好使,下面我们亲自来实践基于C++开发一个我们自己的截图功能。

    请见代码讲解。

    #include<windows.h>
    
    HANDLE DDBtoDIB( HBITMAP bitmap, DWORD dwCompression, HPALETTE  hPal,DWORD * sizeimage) ;
    BOOL CapScreen(LPTSTR FileName);//截屏函数
    
    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);
    
        // we need a device context to get the dib from
        hdc = GetDC(NULL);
        hPal = SelectPalette(hdc,hPal,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 CapScreen(LPTSTR FileName)
    {
    	DWORD sizeimage;
    	HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL); 
    	HDC CompatibleHDC = CreateCompatibleDC(hdc); 
    	HBITMAP BmpScreen = CreateCompatibleBitmap(hdc,GetDeviceCaps(hdc, HORZRES),GetDeviceCaps(hdc, VERTRES)); 
    	SelectObject(CompatibleHDC, BmpScreen);
    	BitBlt(CompatibleHDC,0,0,GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES),hdc,0,0,SRCCOPY);
    	
    HANDLE	pbitmapwithoutfileh=DDBtoDIB(BmpScreen, BI_RGB,0,&sizeimage);
    	BITMAPFILEHEADER bfh;
       //设置位图信息头结构
    	bfh.bfType = ((WORD)('M'<< 8)|'B');
    	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;
    }
    
    int main(void)
    {
    CapScreen("d:\\desktop.bmp");
    return 0;
    }


     

  • 相关阅读:
    媒体格式分析之flv -- 基于FFMPEG
    x264源代码分析-转
    比特币的相关问题整理(详细的)
    比特币价格首超黄金 年涨幅超7600%
    比特币不是虚拟货币,这是一个真实世界----李笑来
    比特币投机者嘲笑称比特币为泡沫的人原因
    比特币:一个让投资人为之疯狂的神奇货币
    比特币沉浮录
    比特币淘金热席卷中国专业“挖矿机”受疯抢
    国内首起比特币交易平台诈骗案涉案人被捕
  • 原文地址:https://www.cnblogs.com/new0801/p/6177785.html
Copyright © 2020-2023  润新知