Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1619857
  • 博文数量: 441
  • 博客积分: 20087
  • 博客等级: 上将
  • 技术积分: 3562
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-19 15:35
文章分类

全部博文(441)

文章存档

2014年(1)

2012年(1)

2011年(8)

2010年(16)

2009年(15)

2008年(152)

2007年(178)

2006年(70)

分类: C/C++

2008-11-14 11:36:30

像红蜻蜓, 还有QQ等,上面的屏幕截图都非常的不错, 那么,如何在自己的程序中加入这一功能呢?屏幕截图, 实际上就是把屏幕拷贝下来, 然后将其保存到文件或者保存到剪贴板, 下面的函数,向你展示了这一功能:


HBITMAP CopyScreenToBitmap(LPRECT lpRect)
{
    HDC hSrcDC = NULL, hMemDC = NULL;
    HBITMAP hBitmap = NULL, hOldBitmap = NULL;
    int x1, y1, x2, y2;
    int nWidth, nHeight;
    int xScreen, yScreen;

    if ( IsRectEmpty(lpRect) )
        return NULL;

    hSrcDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    hMemDC = CreateCompatibleDC(hSrcDC);
    x1 = lpRect->left;
    y1 = lpRect->top;
    x2 = lpRect->right;
    y2 = lpRect->bottom;
    xScreen = GetDeviceCaps(hSrcDC, HORZRES);
    yScreen = GetDeviceCaps(hSrcDC, VERTRES);
    if ( x1 < 0 )
        x1 = 0;
    if ( y1 < 0 )
        y1 = 0;
    if ( x2 > xScreen )
        x2 = xScreen;
    if ( y2 > yScreen )
        y2 = yScreen;
    nWidth = x2 - x1;
    nHeight = y2 - y1;
    
    hBitmap = CreateCompatibleBitmap(hSrcDC, nWidth, nHeight);
    hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
    
    BitBlt(hMemDC, 0, 0, nWidth, nHeight, hSrcDC, x1, y1, SRCCOPY);
    hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
    
    DeleteDC(hSrcDC);
    DeleteDC(hMemDC);

    return hBitmap;
}

BOOL SaveBitmapToFile(HBITMAP hBitmap, LPCTSTR lpFileName)
{
    HDC hDC = NULL;
    int iBits = 0;
    WORD wBitCount = 0;
    DWORD dwPaletteSize = 0;
    DWORD dwBmBitsSize = 0, dwDibSize = 0, dwWritten = 0;

    BITMAP Bitmap;
    BITMAPFILEHEADER bmfHdr;
    BITMAPINFOHEADER bi;
    LPBITMAPINFOHEADER    lpbi;
    HANDLE fh = NULL, hDib = NULL, hPal = NULL, hOldPal = NULL;

    hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    if ( hDC == NULL )
        return FALSE;
    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));
    if ( hDib == NULL )
        return FALSE;
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    if ( lpbi == NULL )
    {
        GlobalFree(hDib);
        return FALSE;
    }
    *lpbi = bi;

    hPal = GetStockObject(DEFAULT_PALETTE);
    if ( hPal == NULL)
    {
        GlobalUnlock(hDib);
        GlobalFree(hDib);
        return FALSE;
    }
    if ( hPal )
    {
        hDC = GetDC(NULL);
        hOldPal = (HANDLE)SelectPalette(hDC, (HPALETTE)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, (HPALETTE)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 )
    {
        GlobalUnlock(hDib);
        GlobalFree(hDib);
        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;
    
    if ( !WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL) )
    {
        GlobalUnlock(hDib);
        GlobalFree(hDib);
        return FALSE;
    }

    if ( !WriteFile(fh, (LPSTR)lpbi, dwDibSize, &dwWritten, NULL) )
    {
        GlobalUnlock(hDib);
        GlobalFree(hDib);
        return FALSE;
    }

    GlobalUnlock(hDib);
    GlobalFree(hDib);
    CloseHandle(fh);

    return TRUE;
}

void SaveToClipbord(HWND hWnd, HBITMAP hBitmap)
{
    if (OpenClipboard(hWnd))
    {
        EmptyClipboard();
        SetClipboardData(CF_BITMAP, hBitmap);
        CloseClipboard();
    }
}

阅读(2200) | 评论(0) | 转发(0) |
0

上一篇:[VC] 屏幕截图

下一篇:PE文件结构分析

给主人留下些什么吧!~~