MFC 抓取窗口或屏幕位图

来源:互联网 发布:国际专线网络价格 编辑:程序博客网 时间:2024/06/03 07:22

李国帅 编写于2011年4月


int CGoogleMapDlg::SaveBitmapToFile(){    TCHAR UserProfile[MAX_PATH];    memset(UserProfile, 0, sizeof(TCHAR)*MAX_PATH);    GetEnvironmentVariable(_T("USERPROFILE"), UserProfile, MAX_PATH);    _tcscat_s(UserProfile,MAX_PATH, _T("\\My Documents\\"));    SYSTEMTIME timeNow;    GetLocalTime(&timeNow);    TCHAR FileName[MAX_PATH];    memset(FileName, 0, sizeof(FileName));    _sntprintf_s(FileName,MAX_PATH, MAX_PATH-1, _T("%04d%02d%02d%02d%02d%02d.bmp"), timeNow.wYear, timeNow.wMonth, timeNow.wDay, timeNow.wHour, timeNow.wMinute, timeNow.wSecond);    _tcscat_s(UserProfile,MAX_PATH, FileName);    LPSTR   lpFileName = UserProfile;//为位图文件名    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;//调色板句柄    CDC   dc;    HDC   hdc = ::GetDC(m_hWnd);    dc.Attach(hdc);    CDC   memDC;    memDC.CreateCompatibleDC(&dc);    CRect   r;    GetClientRect(&r);    CSize   sz(r.Width(), r.Height());    CBitmap   bm;    bm.CreateCompatibleBitmap(&dc, sz.cx, sz.cy);    CBitmap* oldBitmap = memDC.SelectObject(&bm);    memDC.BitBlt(0, 0, sz.cx, sz.cy, &dc, 0, 0, SRCCOPY);    HBITMAP   hBitmap = (HBITMAP)bm;//hBitmap   为刚才的屏幕位图句柄    //计算位图文件每个像素所占字节数    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   if(iBits   <=   32)        wBitCount = 32;    //计算调色板大小    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   ;    //为位图内容分配内存    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, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);    //恢复调色板    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)    {        //   设置位图文件头        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);    memDC.SelectObject(oldBitmap);    bm.Detach();     //   make   sure   bitmap   not   deleted   with   CBitmap   object    return 0;}