获取屏幕位图代码:
HBITMAP CScreenShotDlg::GetScreenBitmap()
{
HDC hSrcDc;
HDC hMemDc;
HBITMAP hBitmap;
HBITMAP hOldBitmap;
int nWidth; //!<有效宽度
int nHeigth; //!<有效长度
int m_nScreenW = GetSystemMetrics(SM_CXSCREEN);
int m_nScreenH = GetSystemMetrics(SM_CYSCREEN);
CRect rect(0, 0, m_nScreenW, m_nScreenH);
int nX1 = v_lpRect->left;
int nY1 = v_lpRect->top;
int nX2 = v_lpRect->right;
int nY2 = v_lpRect->bottom;
nX1 = nX1 < 0 ? 0 : nX1;
nY1 = nY1 < 0 ? 0 : nY1;
nX2 = nX2 > m_nScreenW ? m_nScreenW : nX2;
nY2 = nY2 > m_nScreenH ? m_nScreenH : nY2;
nWidth = nX2 - nX1;
if (nWidth < 0)
{
nWidth = abs(nWidth);
nX1 = v_lpRect->right;
nX2 = v_lpRect->left;
}
nHeigth = nY2 - nY1;
if (nHeigth < 0)
{
nHeigth = abs(nHeigth);
nY1 = v_lpRect->bottom;
nY2 = v_lpRect->top;
}
//!<判断矩形是否为空矩形
if (v_lpRect != NULL)
{
if ((v_lpRect->bottom - v_lpRect->top == 0)
|| (v_lpRect->left - v_lpRect->right == 0))
{
return NULL;
}
}
//!<创建屏幕DC
hSrcDc = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
//!<创建屏幕兼容DC,默认1*1像素大小
hMemDc = CreateCompatibleDC(hSrcDc);
//!<创建屏幕兼容位图,为一个黑色背景位图
hBitmap = CreateCompatibleBitmap(hSrcDc, nWidth, nHeigth);
//!<将位图加载到内存DC,这样内存DC的大小就和屏幕大小一致了
hOldBitmap = (HBITMAP)SelectObject(hMemDc, hBitmap);
//!<直接拷贝,将内容拷贝到内存DC中
BitBlt(hMemDc, 0, 0, nWidth, nHeigth, hSrcDc, nX1, nY1, SRCCOPY);
//!<返回真正屏幕位图
hBitmap = (HBITMAP)SelectObject(hMemDc, hOldBitmap);
DeleteDC(hSrcDc);
DeleteDC(hMemDc);
return hBitmap;
}
保存到文件代码:
BOOL CScreenShotDlg::SaveBitmapToFile( HBITMAP v_hBitmap, const char* v_szFileName )
{
HDC hDC = NULL;
int nBits = 0;
WORD wBitCount = 0;
hDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
nBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (nBits <= 1)
{
wBitCount = 1;
}
else if (nBits <= 4)
{
wBitCount = 4;
}
else if (nBits <=8 )
{
wBitCount = 8;
}
else
{
wBitCount = 24;
}
DWORD dwPaletteSize = 0;
if(wBitCount <= 8)//小于八位按八位处理
dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);
BITMAP Bitmap;
BITMAPINFOHEADER bmiHead; //!<位图信息头结构
GetObject(v_hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bmiHead.biSize = sizeof(BITMAPINFOHEADER);
bmiHead.biWidth = Bitmap.bmWidth;
bmiHead.biHeight = Bitmap.bmHeight;
bmiHead.biPlanes = 1;
bmiHead.biBitCount = wBitCount;
bmiHead.biCompression = BI_RGB;
bmiHead.biSizeImage = 0;
bmiHead.biXPelsPerMeter = 0;
bmiHead.biYPelsPerMeter = 0;
bmiHead.biClrUsed = 0;
bmiHead.biClrImportant = 0;
//!<位图中像素字节大小
DWORD dwBmpBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32)* 4 * Bitmap.bmHeight;
//!<为位图内容分配内存
HANDLE hDib = GlobalAlloc(GHND, dwBmpBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
LPBITMAPINFOHEADER lpbmiHead = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbmiHead = bmiHead;
//!<处理调色板
HANDLE hPal = NULL;
HANDLE hOldPal = NULL;
hPal = GetStockObject(DEFAULT_PALETTE);
if(hPal)
{
hDC = ::GetDC(NULL);
hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
//获取该调色板下新的像素值
GetDIBits(hDC, v_hBitmap, 0, (UINT)Bitmap.bmHeight,
(LPSTR)lpbmiHead + sizeof(BITMAPINFOHEADER) + dwPaletteSize,
(BITMAPINFO*)lpbmiHead, DIB_RGB_COLORS);
//恢复调色板
if(hOldPal)
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
HANDLE hFile = CreateFile(v_szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
//设置位图文件头
BITMAPFILEHEADER bmfHead;//位图文件头结构
bmfHead.bfType = 0x4d42;//"bm"
DWORD dwDibSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
dwPaletteSize + dwBmpBitsSize;//位图文件大小
bmfHead.bfSize = dwDibSize;
bmfHead.bfReserved1 = 0;
bmfHead.bfReserved2 = 0;
bmfHead.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER)+ dwPaletteSize;
//写入位图文件头
DWORD dwWritten = 0;//写入文件字节数
WriteFile(hFile, (LPSTR)&bmfHead, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
//写入位图文件其余内容
WriteFile(hFile, (LPSTR)lpbmiHead, dwDibSize, &dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(hFile);
return TRUE;
}