以下代码截获客户区内容,保存到CBitmap变量中:
CDC* pDC = NULL;
CDC dc;
CRect rc;
CBitmap bmp;pDC = m_pWndPlay->GetDC();
dc.CreateCompatibleDC(pDC);GetClientRect(rc);
bmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
CBitmap* pOld = dc.SelectObject(&bmp);
dc.BitBlt(0, 0, rc.Width(), rc.Height(), pDC, 0, 0, SRCCOPY);
dc.SelectObject(pOld);问题:
1、如果其他窗口盖住该客户区一部分,bmp是否包含覆盖部分,如何去掉,只保留
   真正客户区的内容??
2、如何把bmp保存到一BMP文件中??

解决方案 »

  1.   

    对于您提到的第一个问题,如果其他窗口盖住了该客户区的一部分,确实会包含覆盖部分。这个问题应该可以通过在进行截获客户区内容前激活该窗口或其他使得这个窗口显示在最前的方法来解决。对于第二个问题,您需要做的是取得BMP文件中的特定头部的信息,然后创建一个新文件,依次写入BMP头部以及实际的图像数据即可,如果您愿意,可以参看下面的代码: HDC       hScrDC;      
    CBitmap bitmap, *oldbitmap, *newbitmap;
    int       nX, nY, nX2, nY2;      
    int       nWidth, nHeight;      
    int       xScrn, yScrn; //屏幕分辨率        

    RECT lpRect;
    this->GetClientRect(&lpRect); if (IsRectEmpty(&lpRect))
    return;
    //为屏幕创建设备上下文
    hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    CDC* psrcDC = GetDC();
    CDC memDC;
    //创建兼容的内存DC
    //hMemDC = CreateCompatibleDC(hScrDC);
    memDC.CreateCompatibleDC(psrcDC); nX = lpRect.left;
    nY = lpRect.top;
    nX2 = lpRect.right;
    nY2 = lpRect.bottom;
    // 获得屏幕分辨率
    xScrn = GetDeviceCaps(hScrDC, HORZRES);
    yScrn = GetDeviceCaps(hScrDC, VERTRES); nWidth = nX2 - nX;
    nHeight = nY2 - nY;
    // 创建兼容位图
    bitmap.CreateCompatibleBitmap(psrcDC, nWidth, nHeight);
    // 选入位图
    oldbitmap = memDC.SelectObject(&bitmap);
    // 拷贝
    memDC.BitBlt(0, 0, nWidth, nHeight, psrcDC, nX, nY, SRCCOPY);

    DeleteDC(hScrDC);

    // 以下内容为保存为文件的操作
    HDC            hDC;         
    //当前显示分辨率下每个像素所占字节数
    int            iBits;      
            WORD            wBitCount;   
    //调色板大小等
    DWORD           dwPaletteSize=0,
    dwBmBitsSize,
    dwDIBSize, dwWritten;
        BITMAP          Bitmap;        
        //位图文件头结构
        BITMAPFILEHEADER   bmfHdr;        
        //位图信息头结构
    BITMAPINFOHEADER   bi;                LPBITMAPINFOHEADER lpbi;          
         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;
    //调色板的大小
    if (wBitCount <= 8)
    dwPaletteSize = (1 <<  wBitCount) *
    sizeof(RGBQUAD);

    //设置位图信息头
    bitmap.GetBitmap(&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 ;
    //分配数据的内存
    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)bitmap, 0, (UINT) Bitmap.bmHeight,
    (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
    (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
    //恢复原来的调色板
    if (hOldPal)
    {
    SelectPalette(hDC, hOldPal, TRUE);
    RealizePalette(hDC);
    ::ReleaseDC(NULL, hDC);
    }
    //创建位图文件
    fh = CreateFile("screen.bmp", GENERIC_WRITE, 
    0, NULL, CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (fh == INVALID_HANDLE_VALUE)
    return ;
    // 位图文件头部
    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);
    - 微软全球技术中心 VC技术支持本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款
    (http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。为了为您创建更好的讨论环境,请参加我们的用户满意度调查
    (http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。