Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the dimensions (RECT) of all the screens in win32 API?

Tags:

screen

winapi

I'm writing an application for the testing team. What this application does is it lets you take a screenshot of any part of the screen (and then it uploads it to testing team server with comments).

Taking screenshot involves selecting the region on the screen to take screenshot of. For this I'm creating a semi-transparent window and overlaying it over the entire screen. I'm currently using GetDesktopWindow() and GetWindowRect() to get the dimensions of the screen but this doesn't work in multi-screen environments.

How do I overlay a window over all possible screens?

The screen configurations can be pretty exotic, such as:

     [LCD]
[LCD][LCD][LCD]

(4 lcd screens - one at the top, 3 at the bottom)

Or

[LCD]     [LCD]
[LCD][LCD][LCD]
[LCD]     [LCD]

(7 lcd screens - 3 on the right, 3 on the left, 1 in the middle).

Etc.

Does anyone know how I could overlay 1 window all the screens? I wonder what the dimensions would look like in the 1st exotic example, when there is no screen on the top-row left and right?

Perhaps I should be creating one overlay window per LCD screen?

Any ideas?

like image 707
bodacydo Avatar asked Aug 07 '13 19:08

bodacydo


3 Answers

You can use the EnumDisplayMonitors function for this. Here's a little class that automatically builds a vector of all monitors in the system, as well as a union of them all.

struct MonitorRects
{
    std::vector<RECT>   rcMonitors;
    RECT                rcCombined;

    static BOOL CALLBACK MonitorEnum(HMONITOR hMon,HDC hdc,LPRECT lprcMonitor,LPARAM pData)
    {
        MonitorRects* pThis = reinterpret_cast<MonitorRects*>(pData);
        pThis->rcMonitors.push_back(*lprcMonitor);
        UnionRect(&pThis->rcCombined, &pThis->rcCombined, lprcMonitor);
        return TRUE;
    }

    MonitorRects()
    {
        SetRectEmpty(&rcCombined);
        EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this);
    }
};

If you just create one big window using the rcCombined rectangle from that, it will overlay all the screens and the "missing" bits will just be clipped out automatically by the system.

like image 86
Jonathan Potter Avatar answered Jan 04 '23 04:01

Jonathan Potter


Refer to MSDN for detail about working with multiple monitors:

Multiple Display Monitors

Virtual Screen

Multiple Monitor System Metrics

You can use GetSystemMetrics() with the SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN, SM_CXVIRTUALSCREEN, and SM_CYVIRTUALSCREEN metrics to retrieve the rectangle of the entire virtual screen that contains all of the physical screens.

like image 44
Remy Lebeau Avatar answered Jan 04 '23 03:01

Remy Lebeau


No, that is a bug. Negative coordinates are part of the design, if a user moves a monitor beyond the 0,0 (top, left) point of the primary monitor, this is acceptable, and thus negative coordinates will be applicable for the monitor that was moved beyond left and top of the primary monitor bounding rectangle. The 0,0 primary point is not a virtual screen coordinate reference.

like image 34
Jibun no Kage Avatar answered Jan 04 '23 04:01

Jibun no Kage