2015-02-01 12 views
5

के साथ एकाधिक स्क्रीन कैप्चर मैं कई डिस्प्ले इकाइयों के साथ स्क्रीन कैप्चर पर काम कर रहा हूं। चूंकि GetDesktopWindow() केवल प्राथमिक मॉनीटर को हैंडल प्राप्त करता है, मैंने नौकरी करने के लिए EnumDisplayMonitors() का उपयोग करने का प्रयास किया।एमएसडीएन लाइब्रेरी

MSDN वेबसाइट पढ़ने के बाद, मैं मुख्य() में इन लिखा है:

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

और "BOOL कॉलबैक MyCapScreenEnumProc (HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, lParam dwData)" कॉलबैक के लिए समारोह, मैं MSDN:Capturing an Image से नमूना समारोह "पूर्णांक CaptureAnImage (HWND hWnd)" की नकल की और निम्नलिखित संशोधन किया:

  1. बजाय एक पढ़ने HWND पैरामीटर, मैं इसे समारोह में घोषणा की और GetDesktopWindow() के साथ प्रारंभ
  2. डिवाइस संदर्भ
  3. डिवाइस संदर्भ
  4. RECT
  5. के लिए पैरामीटर lprcMonitor इस्तेमाल किया के रूप में पैरामीटर hdcMonitor इस्तेमाल किया खींच लिए कोड से हटाया

    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; 
    } 
    
    :
  6. अद्वितीय फ़ाइल नाम

यहाँ पूर्ण कोड है पैदा करने के लिए कोड जोड़ा 210

हालांकि, यह पता चला है कि यह प्राथमिक स्क्रीन को दो बार कैप्चर करता है। दूसरे कैप्चर के स्क्रीन आकार के साथ मेरे दूसरे मॉनीटर के समान। मुझे नहीं पता कि कोड के साथ क्या गलत है। क्या कोई इसे कार्य करने के लिए बेहतर तरीका सुझा सकता है या सुझाव दे सकता है? धन्यवाद!

उत्तर

4

आप पर नजर रखने से BitBlt की जरूरत lprcMonitor में आपको दिए गए निर्देशांक, शून्य बिंदु से नहीं:

// 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

धन्यवाद! इसने समस्या हल की! – Samuel

संबंधित मुद्दे