2010-07-20 6 views

ответ

49
// get the device context of the screen 
HDC hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL);  
// and a device context to put it in 
HDC hMemoryDC = CreateCompatibleDC(hScreenDC); 

int width = GetDeviceCaps(hScreenDC, HORZRES); 
int height = GetDeviceCaps(hScreenDC, VERTRES); 

// maybe worth checking these are positive values 
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height); 

// get a new bitmap 
HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemoryDC, hBitmap); 

BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY); 
hBitmap = (HBITMAP) SelectObject(hMemoryDC, hOldBitmap); 

// clean up 
DeleteDC(hMemoryDC); 
DeleteDC(hScreenDC); 

// now your image is held in hBitmap. You can save it or do whatever with it 
+0

Это работает во всех окнах, основанных на nt, от Windows NT4 до Windows 7. – Woody

+6

Почему вы используете CreateDC, а не только GetDC (NULL)? – Anders

+0

Честно говоря, я не смотрел на это какое-то время, это код с довольно обратного пути, который я использовал в приложении. Он работает во всем, поэтому я никогда не возвращался к нему! Если GetDC будет лучше, я могу изменить ответ. – Woody

3

Существует образец MSDN, Capturing an Image, для записи произвольного HWND в DC (вы можете попробовать передать результат из GetDesktopWindow на это). Но насколько хорошо это будет работать под новым настольным компоновщиком на Vista/Windows 7, я не знаю.

24
  1. Используйте GetDC(NULL);, чтобы получить DC для всего экрана.
  2. Используйте CreateCompatibleDC, чтобы получить совместимый DC.
  3. Используйте CreateCompatibleBitmap, чтобы создать растровое изображение, чтобы сохранить результат.
  4. Используйте SelectObject, чтобы выбрать растровое изображение в совместимый DC.
  5. Используйте BitBlt для копирования с экрана DC на совместимый DC.
  6. Снимите отметку с растрового изображения из совместимого DC.

При создании совместимого растрового изображения вы хотите, чтобы он совместим с экраном постоянного тока, а не с совместимым DC.

+1

А как насчет двух дисплеев? Выстрел из обоих экранов? – i486

23
void GetScreenShot(void) 
{ 
    int x1, y1, x2, y2, w, h; 

    // get screen dimensions 
    x1 = GetSystemMetrics(SM_XVIRTUALSCREEN); 
    y1 = GetSystemMetrics(SM_YVIRTUALSCREEN); 
    x2 = GetSystemMetrics(SM_CXVIRTUALSCREEN); 
    y2 = GetSystemMetrics(SM_CYVIRTUALSCREEN); 
    w = x2 - x1; 
    h = y2 - y1; 

    // copy screen to bitmap 
    HDC  hScreen = GetDC(NULL); 
    HDC  hDC  = CreateCompatibleDC(hScreen); 
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, w, h); 
    HGDIOBJ old_obj = SelectObject(hDC, hBitmap); 
    BOOL bRet = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY); 

    // save bitmap to clipboard 
    OpenClipboard(NULL); 
    EmptyClipboard(); 
    SetClipboardData(CF_BITMAP, hBitmap); 
    CloseClipboard(); 

    // clean up 
    SelectObject(hDC, old_obj); 
    DeleteDC(hDC); 
    ReleaseDC(NULL, hScreen); 
    DeleteObject(hBitmap); 
} 
Смежные вопросы