Post by JiiPeeBOOL CScreenImage::CaptureRect(const CRect& rect)
{
// detach and destroy the old bitmap if any attached
CImage::Destroy();
// create a screen and a memory device context
HDC hDCScreen = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
HDC hDCMem = ::CreateCompatibleDC(hDCScreen);
// create a compatible bitmap and select it in the memory DC
HBITMAP hBitmap =
::CreateCompatibleBitmap(hDCScreen, rect.Width(), rect.Height());
HBITMAP hBmpOld = (HBITMAP)::SelectObject(hDCMem, hBitmap);
// bit-blit from screen to memory device context
// note: CAPTUREBLT flag is required to capture layered windows
DWORD dwRop = SRCCOPY | CAPTUREBLT;
BOOL bRet = ::BitBlt(hDCMem, 0, 0, rect.Width(), rect.Height(),
hDCScreen,
rect.left, rect.top, dwRop);
// attach bitmap handle to this object
Attach(hBitmap);
// restore the memory DC and perform cleanup
::SelectObject(hDCMem, hBmpOld);
::DeleteDC(hDCMem);
::DeleteDC(hDCScreen);
return bRet;
}
BOOL CScreenImage::CaptureWindow(HWND hWnd)
{
CImage::Destroy();
BOOL bRet = FALSE;
if(::IsWindow(hWnd))
{
CRect rect;
::GetWindowRect(hWnd, rect);
bRet = CaptureRect(rect);
}
return bRet;
}
Oh. I see this is not your code but comes from:
http://www.codeguru.com/cpp/article.php/c18347/C-Programming-Easy-Screen-Capture-Using-MFCATL.htm
Running the CaptureDemo application I see the behavior you are talking
about.
The demo _almost_ behaves correctly for capturing a non-maximized
window but extends the bottom right corner by 8 points but gets the
-8, -8 for the top left corner of a maximized window and 8 pixels too
large for the extent of the bottom right. It gets correct corner
coordinates for capturing the full screen image.
The question now is, did it ever work correctly?
The solution I found, although it feels like a bit of a hack, was to
use GetWindowInfo to obtain the rcClient rectangle and pass it to
CaptureRect instead of the window rectangle.
BOOL CScreenImage::CaptureWindow(HWND hWnd)
{
WINDOWINFO info;
info.cbSize = sizeof(WINDOWINFO);
BOOL bRet = FALSE;
if(::IsWindow(hWnd))
{
//CRect rect;
//::GetWindowRect(hWnd, rect);
::GetWindowInfo(hWnd, &info);
bRet = CaptureRect(info.rcClient);
}
return bRet;
}
I think this might be a legacy problem from earlier versions of
Windows that had borders. Windows 7 thru 10 windows don't have visible
borders anymore and I think when maximized the windows were clipped at
the desktop margins and the borders disappeared. Unfortunately, I
don't have any older systems running anymore on which to test.