none
Multi monitor setting: Cannot capture mouse cursor

    Question

  • I am having a situation where I cannot seem to capture mouse cursor along with desktop. Let me explain:

    I have two monitors: My primary monitor is the laptop monitor (1366, 768 resolution). The secondary is an extended monitor (1024, 768 resolution).

    I am able to capture desktop successfully. Either monitor 1 or 2. Plus any region with in monitor. It all works well. However, I cannot capture the mouse icon. The following code works fine in single monitor setting.

    void CopyScreenToBitmap(WCHAR * deviceName, LPRECT lpRect, BYTE *pData, BITMAPINFO *pHeader) { HDC hScrDC, hMemDC; // screen DC and memory DC HBITMAP hBitmap, hOldBitmap; // handles to device-dependent bitmaps int nX, nY, nX2, nY2; // coordinates of rectangle to grab int nWidth, nHeight; // DIB width and height int xScrn, yScrn; // screen resolution int xPos = 0, yPos = 0; // The cursor coodinates. CURSORINFO cursorInfo; ICONINFO iconInfo; // check for an empty rectangle if (IsRectEmpty(lpRect)) return;

    if (deviceName == NULL) { hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); } else { hScrDC = CreateDC(deviceName, NULL, NULL, NULL); } hMemDC = CreateCompatibleDC(hScrDC); // get points of rectangle to grab nX = lpRect->left; nY = lpRect->top; nX2 = lpRect->right; nY2 = lpRect->bottom; // get screen resolution xScrn = GetDeviceCaps(hScrDC, HORZRES); yScrn = GetDeviceCaps(hScrDC, VERTRES); //make sure bitmap rectangle is visible if (nX < 0) nX = 0; if (nY < 0) nY = 0; if (nX2 > xScrn) nX2 = xScrn; if (nY2 > yScrn) nY2 = yScrn; nWidth = nX2 - nX; nHeight = nY2 - nY; // create a bitmap compatible with the screen DC hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight); // select new bitmap into memory DC hOldBitmap = (HBITMAP) SelectObject(hMemDC, hBitmap); // bitblt screen DC to memory DC BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY); // Get cursor info now. ZeroMemory(&cursorInfo, sizeof(cursorInfo)); cursorInfo.cbSize = sizeof(cursorInfo); if (GetCursorInfo(&cursorInfo)) { if (cursorInfo.flags == CURSOR_SHOWING) { if (GetIconInfo(cursorInfo.hCursor, &iconInfo)) { xPos = cursorInfo.ptScreenPos.x - nX - iconInfo.xHotspot; yPos = cursorInfo.ptScreenPos.y - nY - iconInfo.yHotspot; DeleteObject(iconInfo.hbmColor); DeleteObject(iconInfo.hbmMask); DrawIcon(hMemDC, xPos, yPos, cursorInfo.hCursor); } DeleteObject(cursorInfo.hCursor); } } hBitmap = (HBITMAP) SelectObject(hMemDC, hOldBitmap); GetDIBits(hScrDC, hBitmap, 0, nHeight, pData, pHeader, DIB_RGB_COLORS); DeleteDC(hScrDC); DeleteDC(hMemDC); DeleteObject(hBitmap); DeleteObject(hOldBitmap); }


    The issue occurs when "deviceName != NULL" and when I use the device name is used as opposed to TEXT("DISPLAY").

    I tried to understand from this thread:

    http://social.msdn.microsoft.com/Forums/en-US/windowssdk/thread/568da411-d6fe-4ca1-b648-929cab35ffa8?prof=required

    But could not.

    Like I mentioned, I can capture any monitor fine with this code. I just cannot capture the mouse icon. I even tried hard coding mouse position to somewhere between 0, 1366 and 0, 768. Still doesn't work.

    Can somebody point to where I am doing wrong?

    Wednesday, February 06, 2013 5:01 AM

Answers

  • I found the issue and fixed it. 

    As per the original answer from this link:

    http://social.msdn.microsoft.com/Forums/en-US/windowssdk/thread/568da411-d6fe-4ca1-b648-929cab35ffa8?prof=required

    I had to do two things:

    1. Use hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);

    as opposed to device name.

    2. Grab coordinates from EnumDisplayMonitors and pass it as the RECT parameter to this function.
    • Marked as answer by Kadambi Wednesday, February 06, 2013 12:01 PM
    Wednesday, February 06, 2013 12:01 PM

All replies

  • From EnumDisplayMonitors, the coordinates for the monitors are:

    0 0 1366 768

    and

    1366 0 2390 768

    Wednesday, February 06, 2013 6:18 AM
  • I found the issue and fixed it. 

    As per the original answer from this link:

    http://social.msdn.microsoft.com/Forums/en-US/windowssdk/thread/568da411-d6fe-4ca1-b648-929cab35ffa8?prof=required

    I had to do two things:

    1. Use hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);

    as opposed to device name.

    2. Grab coordinates from EnumDisplayMonitors and pass it as the RECT parameter to this function.
    • Marked as answer by Kadambi Wednesday, February 06, 2013 12:01 PM
    Wednesday, February 06, 2013 12:01 PM