001 Programming Windows - Chapter 14 Blow-Up程序的錯誤

Post date: 2012/10/26 上午 02:31:07

在Programming Windows Chapter 14 Blow-Up的程序中,在完成屏幕截取後,作者使用如下代碼複製屏幕內容到位圖:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

HDC hdc = GetDC( _hWnd );

HDC hdcMem = CreateCompatibleDC( hdc );

hBitmap = CreateCompatibleBitmap( hdc, abs(ptEnd.x-ptBeg.x), abs(ptEnd.y-ptBeg.y) );
SelectObject( hdcMem, hBitmap );

StretchBlt( hdcMem,
            0, 0,
            abs(ptEnd.x-ptBeg.x), abs(ptEnd.y-ptBeg.y),
            hdc,
            ptBeg.x, ptBeg.y,
            ptEnd.x-ptBeg.x, ptEnd.y-ptBeg.y,
            SRCCOPY );

DeleteDC( hdcMem );
ReleaseDC( _hWnd, hdc );

在我自己的Win7-32bit下測試是無法正確複製內容的,因為GetDC( _hWnd )只是獲取客戶區的DC,無法獲得客戶區外的數據,效果如下:

複製內容後:

為了正確的複製截取的屏幕內容,我們需要獲取屏幕DC,並且使用屏幕坐標來進行操作,代碼如下:

POINT ptScreenBeg = ptBeg;
POINT ptScreenEnd = ptEnd;
ClientToScreen( _hWnd, &ptScreenBeg );
ClientToScreen( _hWnd, &ptScreenEnd );

HDC hdc = GetDCEx( hWndDesktop, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE );

HDC hdcMem = CreateCompatibleDC( hdc );

hBitmap = CreateCompatibleBitmap( hdc, abs(ptScreenEnd.x-ptScreenBeg.x), abs(ptScreenEnd.y-ptScreenBeg.y) );
SelectObject( hdcMem, hBitmap );

StretchBlt( hdcMem,
            0, 0,
            abs(ptScreenEnd.x-ptScreenBeg.x), abs(ptScreenEnd.y-ptScreenBeg.y),
            hdc,
            ptScreenBeg.x, ptScreenBeg.y,
            ptScreenEnd.x-ptScreenBeg.x, ptScreenEnd.y-ptScreenBeg.y,
            SRCCOPY );

DeleteDC( hdcMem );
ReleaseDC( hWndDesktop, hdc );

這樣,我們就可以正確將截取的屏幕內容複製到位圖了,如下:

複製內容後: