11

Looking around the net I see that most people think that GetDC(NULL) will get a device context for the entire primary monitor (the one with 0,0 at its top left). However, I get the feeling most people are just saying that because that's what the msdn page for GetDC might be saying.

However, if you look at the following two pages (at least these two) seem to be saying that GetDC(NULL) returns a device context that covers the entire virtual screen (the one that encompasses every monitor attached to the system).

(1) https://www.microsoft.com/msj/0697/monitor/monitor.aspx -> search the page for "This gets the RECT of the virtual desktop" and look at the bits around that statement (particularly the GetDC(NULL) above it).

(2) http://msdn.microsoft.com/en-gb/library/windows/desktop/dd162610%28v=vs.85%29.aspx -> search the page for "GetDC(NULL)"

I have been trying to figure out which it really is, but the multitude of conflicting opinions defeats me.

Does anyone have any real experience of this, and can test it on a multimonitor system? (I only have one monitor so I can't.)

Does it get a DC covering the entire primary monitor OR a DC covering the entire virtual screen?

Edit

For anyone wanting to try it out, on my system, if I create a default project and put the following in WinMain it turns the screen black. If you have multiple monitors and you try it, the question becomes does it turn just your primary monitor black OR all your monitors?

HDC hdc = GetDC(NULL);
RECT r = {LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX};
FillRect(hdc, &r, (HBRUSH)(COLOR_BTNTEXT + 1));
ReleaseDC(NULL, hdc);
user2044467
  • 113
  • 1
  • 1
  • 5

2 Answers2

12

It gets a DC that covers the entire virtual screen. I just tested with:

#include <windows.h>
#include <conio.h>

int main() {

    HDC screen = GetDC(NULL);

    RECT r = {-1200, 100, -200, 500};
    HBRUSH br = CreateSolidBrush(RGB(0, 255, 0));

    FillRect(screen, &r, br);

    getch();
    InvalidateRect(NULL, &r, true);

    return 0;
}

...and it successfully draws a green rectangle on my secondary screen (positioned to the left of the primary screen so it has negative X coordinates).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Thanks Jerry! Could you try it with your rect set to "{LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX}"? I'm just wondering if the DC is just covering one of your monitors (for whatever reason it may do such a thing). – user2044467 Feb 05 '13 at 19:58
  • With `{LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX}`, it does nothing (doesn't draw anything at all) but with `{-1200, 200, 1200, 1000}` it draws a rectangle onto both screens. – Jerry Coffin Feb 05 '13 at 20:02
  • That's great. Thanks for doing that. You've answered the question as far as I can see! – user2044467 Feb 05 '13 at 20:05
  • According to [this page](https://msdn.microsoft.com/en-us/library/windows/desktop/dd183490(v=vs.85).aspx), you need to call `CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);` to get DC that covers all monitors. – c00000fd Sep 21 '15 at 07:13
  • Surprisingly, if you draw the rectangle using GDI+, the rectangle will only appear in the primary monitor. With GDI, on the other hand, you can even draw on an area that crosses monitors boundaries. – GetFree Dec 14 '17 at 02:52
3

I'm currently trying to rewrite a gamma setter utility, because it is using GetDC(NULL) instead of EnumDisplayMonitors + GetDC, and as a result, changes the gamma of the entire desktop.

Your program is similar, it paints both displays black.

Frigo
  • 1,709
  • 1
  • 14
  • 32
  • Thanks Frigo. You've confirmed Jerry's test I think. Strange his won't accept the {LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX} - I'm guessing it's some difference between whatever versions of whatever IDEs we're all using, or more likely the Windows versions! – user2044467 Feb 05 '13 at 20:07