2015-02-01 26 views
5

Birden çok ekran birimi ile ekran yakalama üzerinde çalışıyorum. GetDesktopWindow() yalnızca tanıtıcıyı birincil monitörlere aldığından, işi yapmak için EnumDisplayMonitors() öğesini kullanmaya çalıştım.MSDN kütüphanesiyle çoklu ekran görüntüsü yakalama

MSDN Web okuduktan sonra) (ana bu yazmış:

HDC hdc = GetDC(NULL); 
EnumDisplayMonitors(hdc, NULL, MyCapScreenEnumProc, 0); 
ReleaseDC(NULL, hdc); 

Ve "BOOL CALLBACK MyCapScreenEnumProc (Hmonitor Hmonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)" geri arama için

fonksiyonu, ben MSDN:Capturing an Image örnek işlevi " int CaptureAnImage (HWND hWnd)" kopyalanıp aşağıdaki modifikasyon yaptı:

  1. yerine okuma HWND parametresi, bir işlevi olarak ilan
  2. RECT
  3. için parametre lprcMonitor kullanılan cihaz bağlam olarak parametre hdcMonitor kullanılan aygıt içeriğini gerilmesi için kodları çıkarıldı GetDesktopWindow() ile başlatıldı

    BOOL CALLBACK MyCapScreenEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) 
    { 
        HWND hWnd = GetDesktopWindow(); 
        HDC hdcMemDC = NULL; 
        HBITMAP hbmScreen = NULL; 
        BITMAP bmpScreen; 
    
        //generate a unique file name for the bitmaps 
        static int file_number = 1; 
        stringstream ss; 
        ss << "all_capture_" << file_number++ << ".bmp"; 
        string filename = ss.str(); 
        wstring widestr = wstring(filename.begin(), filename.end()); 
    
        // Create a compatible DC which is used in a BitBlt from the window DC 
        hdcMemDC = CreateCompatibleDC(hdcMonitor); 
    
        if (!hdcMemDC) 
        { 
         MessageBox(hWnd, L"CreateCompatibleDC has failed", L"Failed", MB_OK); 
         goto done; 
        } 
    
        // Get the client area for size calculation 
        RECT rcClient = *lprcMonitor; 
    
        // Create a compatible bitmap from the Window DC 
        hbmScreen = CreateCompatibleBitmap(hdcMonitor, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top); 
    
        if (!hbmScreen) 
        { 
         MessageBox(hWnd, L"CreateCompatibleBitmap Failed", L"Failed", MB_OK); 
         goto done; 
        } 
    
        // Select the compatible bitmap into the compatible memory DC. 
        SelectObject(hdcMemDC, hbmScreen); 
    
        // Bit block transfer into our compatible memory DC. 
        if (!BitBlt(hdcMemDC, 
           0, 0, 
           rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, 
           hdcMonitor, 
           0, 0, 
           SRCCOPY)) 
        { 
         MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK); 
         goto done; 
        } 
    
        // Get the BITMAP from the HBITMAP 
        GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen); 
    
        BITMAPFILEHEADER bmfHeader; 
        BITMAPINFOHEADER bi; 
    
        bi.biSize = sizeof(BITMAPINFOHEADER); 
        bi.biWidth = bmpScreen.bmWidth; 
        bi.biHeight = bmpScreen.bmHeight; 
        bi.biPlanes = 1; 
        bi.biBitCount = 32; 
        bi.biCompression = BI_RGB; 
        bi.biSizeImage = 0; 
        bi.biXPelsPerMeter = 0; 
        bi.biYPelsPerMeter = 0; 
        bi.biClrUsed = 0; 
        bi.biClrImportant = 0; 
    
        DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31)/32) * 4 * bmpScreen.bmHeight; 
    
        // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that 
        // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc 
        // have greater overhead than HeapAlloc. 
        HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize); 
        char *lpbitmap = (char *)GlobalLock(hDIB); 
    
        // Gets the "bits" from the bitmap and copies them into a buffer 
        // which is pointed to by lpbitmap. 
        GetDIBits(hdcMonitor, hbmScreen, 0, 
           (UINT)bmpScreen.bmHeight, 
           lpbitmap, 
           (BITMAPINFO *)&bi, DIB_RGB_COLORS); 
    
    
    
    
        // A file is created, this is where we will save the screen capture. 
        HANDLE hFile = CreateFile(widestr.c_str(), 
               GENERIC_WRITE, 
               0, 
               NULL, 
               CREATE_ALWAYS, 
               FILE_ATTRIBUTE_NORMAL, NULL); 
    
        // Add the size of the headers to the size of the bitmap to get the total file size 
        DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 
    
        //Offset to where the actual bitmap bits start. 
        bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); 
    
        //Size of the file 
        bmfHeader.bfSize = dwSizeofDIB; 
    
        //bfType must always be BM for Bitmaps 
        bmfHeader.bfType = 0x4D42; //BM 
    
        DWORD dwBytesWritten = 0; 
        WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); 
        WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); 
        WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL); 
    
        //Unlock and Free the DIB from the heap 
        GlobalUnlock(hDIB); 
        GlobalFree(hDIB); 
    
        //Close the handle for the file that was created 
        CloseHandle(hFile); 
    
        //Clean up 
        done: 
        DeleteObject(hbmScreen); 
        DeleteObject(hdcMemDC); 
        return TRUE; 
    } 
    
    :
  4. benzersiz dosya adları
  5. İşte

tam kodudur oluşturmak için kodları eklendi 210

Bununla birlikte, birincil ekranı iki kez yakaladığı ortaya çıkıyor. İkinci ele geçirmenin ekran boyutu, ikinci monitörümünkiyle aynı. Kodlarda neyin yanlış olduğunu bilmiyorum. Kimse işaret edebilir mi veya görevi daha iyi bir şekilde önerebilir mi? Teşekkürler! Sen monitörden BitBlt gerek

cevap

4

değil sıfır noktasından, lprcMonitor içinde verilen koordinatları:

// Bit block transfer into our compatible memory DC. 
if (!BitBlt(hdcMemDC, 
      0, 0, 
      rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, 
      hdcMonitor, 
      lprcMonitor->left, lprcMonitor->top, // <<--- !!! 
      SRCCOPY)) 
+0

Teşekkür! Bu problemi çözdü! – Samuel