19,472
社区成员




CDC dc;
CDC *pDC = &dc;//屏幕DC
HWND hwnd = ::GetForegroundWindow();
HDC activeDC = ::GetWindowDC(hwnd); //获得当前活动窗口的hDC
pDC->Attach(activeDC);//获取当前活动窗口的DC
RECT rect;
::GetWindowRect(hwnd,&rect);//得到活动窗口的大小
UINT Width = rect.right - rect.left;
UINT Height = rect.bottom - rect.top;
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
BITMAP bmp;
memBitmap.GetBitmap(&bmp);//获得位图信息
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;
BYTE * up = new BYTE[bmp.bmWidthBytes * bmp.bmHeight];//申请内存保存位图数据
GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, up,
(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据
//以下是保存图片的代码,略
BOOL SaveHwndToBmpFile(HWND hWnd, LPCTSTR lpszPath)
{
HWND hDesktop = ::GetDesktopWindow();
ASSERT(hDesktop);
if(NULL == hWnd)
{
hWnd = hDesktop;
}
RECT rect;
::GetWindowRect(hWnd, &rect);
int nWidht = rect.right - rect.left;
int nHeight = rect.bottom - rect.top;
HDC hSrcDC = ::GetWindowDC(hWnd);
ASSERT(hSrcDC);
HDC hMemDC = ::CreateCompatibleDC(hSrcDC);
ASSERT(hMemDC);
HBITMAP hBitmap = ::CreateCompatibleBitmap(hSrcDC, nWidht, nHeight);
ASSERT(hBitmap);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemDC, hBitmap);
::BitBlt(hMemDC, 0, 0, nWidht, nHeight, hSrcDC, 0, 0, SRCCOPY);
BITMAP bitmap = {0};
::GetObject(hBitmap, sizeof(BITMAP), &bitmap);
BITMAPINFOHEADER bi = {0};
BITMAPFILEHEADER bf = {0};
CONST int nBitCount = 24;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bitmap.bmWidth;
bi.biHeight = bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = nBitCount;
bi.biCompression = BI_RGB;
DWORD dwSize = ((bitmap.bmWidth * nBitCount + 31) / 32) * 4 * bitmap.bmHeight;
HANDLE hDib = GlobalAlloc(GHND, dwSize + sizeof(BITMAPINFOHEADER));
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
::GetDIBits(hMemDC, hBitmap, 0, bitmap.bmHeight, (BYTE*)lpbi + sizeof(BITMAPINFOHEADER), (BITMAPINFO*)lpbi, DIB_RGB_COLORS);
try
{
CFile file;
file.Open(lpszPath, CFile::modeCreate | CFile::modeWrite);
bf.bfType = 0x4d42;
dwSize += sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bf.bfSize = dwSize;
bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
file.Write((BYTE*)&bf, sizeof(BITMAPFILEHEADER));
file.Write((BYTE*)lpbi, dwSize);
file.Close();
}
catch(CFileException* e)
{
e->ReportError();
e->Delete();
}
GlobalUnlock(hDib);
GlobalFree(hDib);
::SelectObject(hMemDC, hOldBitmap);
::DeleteObject(hBitmap);
::DeleteDC(hMemDC);
::ReleaseDC(hWnd, hSrcDC);
return TRUE;
}
// 调用方法
HWND hWnd = GetSafeHwnd();
if(hWnd)
{
DWORD dwStart = GetTickCount();
SaveHwndToBmpFile(hWnd, _T("E://12.bmp"));
DWORD dwValue = GetTickCount() - dwStart;
CString strText(_T(""));
strText.Format(_T("%d ms"), dwValue);
AfxMessageBox(strText);
}