#include <time.h>
#include <afxwin.h>
#include <stdio.h>
#include <comdef.h>
#include <iostream>
#include <atlimage.h>

/*
 * hwnd:要截图的窗口的句柄
 * fileName:要比较的图片的路径
 * offsets:有4个成员的int型数组,用于设置比较图片时,上、下、左、右的偏移量
 * offsets[0]:左
 * offsets[1]:上
 * offsets[2]:右
 * offsets[3]:下
 */
bool print_screen(HWND hwnd, const char* fileName, int offsets[])
{
    LPCTSTR pFileName = NULL;

    if(sizeof(TCHAR)==sizeof(char))
    {
        pFileName=(LPCTSTR)fileName;
    }
    else
    {
        int length= sizeof(TCHAR)*(strlen(fileName)+1);
        LPTSTR tcBuffer=new TCHAR[length];
        memset(tcBuffer,0,length);
        MultiByteToWideChar(CP_ACP,0,fileName,strlen(fileName),tcBuffer,length);
        pFileName=(LPCTSTR)tcBuffer ;
    }
    long t_start = ::GetTickCount();
    CDC dc;
    CDC *pDC = &dc;//屏幕DC

        // HWND hwnd = ::GetForegroundWindow(); // 获得当前活动窗口
    HDC activeDC = ::GetWindowDC(hwnd);   //获得要截屏的窗口的hDC

    pDC->Attach(activeDC);//获取当前活动窗口的DC
    RECT rect;
    ::GetWindowRect(hwnd,&rect);//得到窗口的大小
    int Width = rect.right - rect.left;

    int Height = rect.bottom - rect.top;

    /*cout << "Width:" << Width << endl

    << "Height:" << Height << endl << endl;*/

    CDC memDC;//内存DC

    memDC.CreateCompatibleDC(pDC);

    CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap

    memBitmap.CreateCompatibleBitmap(pDC, Width, Height);

    oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC

    memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC
        //以下代码保存memDC中的位图到文件

    BITMAP bmp;

    memBitmap.GetBitmap(&bmp);//获得位图信息

    FILE *fp = fopen("C:\\abc.bmp", "w+b");
    BITMAPINFOHEADER bih = {0};//位图信息头

    bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小

    bih.biCompression = BI_RGB;

    bih.biHeight = bmp.bmHeight;//高度

    bih.biPlanes = 1;

    bih.biSize = sizeof(BITMAPINFOHEADER);

    bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小

    bih.biWidth = bmp.bmWidth;//宽度

    BITMAPFILEHEADER bfh = {0};//位图文件头

    bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量

    bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件总的大小

    bfh.bfType = (WORD)0x4d42;

    fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头

    fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头

    byte * p = new byte[bmp.bmWidthBytes * bmp.bmHeight];//申请内存保存位图数据

    GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, p,

        (LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据

    fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);//写入位图数据

    delete [] p;

    fclose(fp);

        // 以下代码用于比较指定的BMP文件与内存中的截图
    CImage img;
    img.Load(pFileName);
    int nWidth = img.GetWidth();//获取图像宽度
    int nHeight = img.GetHeight();//获取图像高度
    if (Width != nWidth || Height != nHeight)
    {
        return false;
    }
    byte* pRealData;
    pRealData=(byte*)img.GetBits();

    int pit=img.GetPitch();

    int bitCount=img.GetBPP()/8;

    for (int y = offsets[1]; y < Height - offsets[3]; ++y)
    {
        for (int x = offsets[0]; x < Width - offsets[2]; ++x)
        {
            int pity = pit * y;
            int pitx = x*bitCount;
            if (up[bmp.bmWidth * (bmp.bmHeight - y - 1) + x] != 
(*(pRealData + pity + pitx + 2) << 16) + (*(pRealData + pity + pitx + 1) << 8) + 
*(pRealData + pity + pitx))
            {
                printf("(%d, %d) = %x, ",x, y, up[bmp.bmWidth *
 (bmp.bmHeight - y - 1) + x]);
                printf("(%d, %d) = %x\n",x, y, (*(pRealData + 
pity + pitx + 2) << 16) + (*(pRealData + pity + pitx + 1) << 8) + *(pRealData + 
pity + pitx));
                return false;
            }
        }
    }
    return true;
}

/*
 * hwnd:要截图的窗口的句柄
 * fileName:要比较的图片的路径
 * left:比较图片时的左偏移量
 * top:比较图片时的上偏移量
 * right:比较图片时的右偏移量
 * bottom:比较图片时的下偏移量
 */
int screenPrint(HWND hwnd, const char* fileName, int left, int top, int right, int bottom)
{
    if (left < 0 || top < 0 || right < 0 || bottom < 0)
    {
        return -1;
    }
    int offsets[4];
    offsets[0] = left;
    offsets[1] = top;
    offsets[2] = right;
    offsets[3] = bottom;
    bool isTheSame = print_screen(hwnd, fileName, offsets);
    if (isTheSame)
    {
        return 0;
    }
    else
    {
        return -1;
    }
}

将窗口截图存为Bmp的C++代码第二种方法:

void CMyDialog::Catchfile()
{
HBITMAP hBitmap = GetSrcBit();

    if (hBitmap != NULL) 
    {
        // szFilters is a text string that includes two file name filter:
        // "*.bmp" for "bmp Files" and "*.*" for "All Files."
        char szFilters[]=
            "bmp Files (*.bmp)|*.bmp|All Files (*.*)|*.*||";

        // Create a Save dialog; the default file name extension is ".bmp".
        CFileDialog fileDlg (FALSE, "bmp", "*.bmp",
            OFN_FILEMUSTEXIST| OFN_HIDEREADONLY, szFilters, this);

        // Display the file dialog. When user clicks OK, fileDlg.DoModal() 
        // returns IDOK.
        if( fileDlg.DoModal() == IDOK )
        {
            CString pathName = fileDlg.GetPathName();

            // Implement opening and reading file in here.
            //...
            //Change the window's title to the opened file's title.
            //CString fileName = fileDlg.GetFileTitle ();

            //SetWindowText(fileName);
            SaveBitmapToFile(hBitmap , pathName.GetBuffer()/*LPSTR lpFileName*/);
        }
    }
}


void CMyDialog::GetSrcBit(/*DWORD BitWidth, DWORD BitHeight*/void)
{
    HBITMAP hBitmap,hOldBitmap;
    CPaintDC dc(this);
    HDC hmyMemDC = CreateCompatibleDC(dc.m_hDC);
    hBitmap = CreateCompatibleBitmap(dc.m_hDC, WIDTH-MARGIN, HEIGHT);
    hOldBitmap = (HBITMAP)SelectObject(hmyMemDC, hBitmap);

    BitBlt(hmyMemDC, 0, 0, WIDTH, HEIGHT,dc.m_hDC, 0, 0, SRCCOPY);


    hBitmap = (HBITMAP)SelectObject(hmyMemDC, hOldBitmap);

    return (hBitmap);
}

// 我们也可以把屏幕内容以位图格式存到磁盘文件上.
// lpFileName 为位图文件脕E     
int CMyDialog::SaveBitmapToFile(HBITMAP hBitmap , LPSTR lpFileName) 
{
    
    HDC hDC;      //设备描述句柄      
    int iBits;    //当前显示分辨率下每个像素所占字节数  
    
    WORD wBitCount;   //位图中每个像素所占字节数

    //定义调色板大小, 位图中像素字节大小 ,
    //位图文件大小
    DWORD  dwPaletteSize=0,
           dwBmBitsSize,
           dwDIBSize, dwWritten;
    
    BITMAP   Bitmap;  //位图属性结构      
    BITMAPFILEHEADER    bmfHdr;  //位图文件头结构

    //位图信息头结构 
    BITMAPINFOHEADER    bi;

    //指向位图信息头结构
    LPBITMAPINFOHEADER lpbi;

    //定义文件,分配内存句柄,调色板句眮E
    HANDLE   fh, hDib;
    HPALETTE hPal,hOldPal=NULL;

    //计算位图文件每个像素所占字节数
    hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
    iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
    DeleteDC(hDC);

    if (iBits <= 1)
        wBitCount = 1;
    else if (iBits <= 4)
        wBitCount = 4;
    else if (iBits <= 8)
        wBitCount = 8;
    else if (iBits <= 24)
        wBitCount = 24;
    else wBitCount = 24; 

    //计算调色板大小
    if (wBitCount <= 8)
        dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);

    //设置位图信息头结构
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
    bi.biSize            = sizeof(BITMAPINFOHEADER);
    bi.biWidth           = Bitmap.bmWidth;
    bi.biHeight          = Bitmap.bmHeight;
    bi.biPlanes          = 1;
    bi.biBitCount         = wBitCount;
    bi.biCompression      = BI_RGB;
    bi.biSizeImage        = 0;
    bi.biXPelsPerMeter     = 0;
    bi.biYPelsPerMeter     = 0;
    bi.biClrUsed         = 0;
    bi.biClrImportant      = 0;

    dwBmBitsSize = ((Bitmap.bmWidth *wBitCount+31)/32)* 4*Bitmap.bmHeight ;
    //为位图内容分配内磥E
    hDib  = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    *lpbi = bi;

    hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
    if (hPal)
    {
        hDC  = ::GetDC(NULL);
        hOldPal = SelectPalette(hDC, hPal, FALSE);
        RealizePalette(hDC);
    }

    // 获取该调色板下新的像素值
    GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);

    //恢复调色皝E  
    if (hOldPal)
    {
        SelectPalette(hDC, hOldPal, TRUE);
        RealizePalette(hDC);
        ::ReleaseDC(NULL, hDC);
    }

    //创建位图文件    
    fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

    if (fh == INVALID_HANDLE_VALUE)
        return FALSE;

    //设置位图文件头
    bmfHdr.bfType = 0x4D42;  // "BM"
    dwDIBSize    = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
        + dwPaletteSize + dwBmBitsSize;  
    bmfHdr.bfSize = dwDIBSize;
    bmfHdr.bfReserved1 = 0;
    bmfHdr.bfReserved2 = 0;
    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) 
        + (DWORD)sizeof(BITMAPINFOHEADER)+ dwPaletteSize;
                                                    
    WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);      
                                                                                                                                    
    WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);                        
                                                                                    
    //清除                                                                            
    GlobalUnlock(hDib);                                                             
    GlobalFree(hDib);                                                               
    CloseHandle(fh);                                                                
                                                                                    
    return TRUE;                                                                    
}