1

Main frame in my app is common: class CMainFrame : public CFrameWndEx.

In my code I am looking for a MainFrame position on the screen and if it is out, (for example when any monitor is swiched off or disconnected) I move the window on a valid area.

int VIRTSCR_Left = GetSystemMetrics(SM_XVIRTUALSCREEN);
int VIRTSCR_Top = GetSystemMetrics(SM_YVIRTUALSCREEN);
int VIRTSCR_Width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int VIRTSCR_Height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
int VIRTSCR_Right = VIRTSCR_Left + VIRTSCR_Width;
int VIRTSCR_Bottom = VIRTSCR_Top + VIRTSCR_Height;

So in my case I get (for one screen) 0, 1920, 0, 1200.

CMainFrame size and position, when it is maximized:

CRect rc;
pMainFrame->GetWindowRect(rc);

Give to me -8, -8, 1928, 1168. (At bottom is 40px high Windows main taskbar).

So around the visible main frame is next invisible 8px wide margin.
Where I can find this value 8px?
Is it reacheble by GetSystemMetrics(...)?
Is the value 8px same for for other screen resoluttions (for example 2k, 3k monitors)?

Thank you for ideas and help :)
Lubomir

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Lubomir
  • 11
  • 1
  • 2
    It's not clear, why you need this information. If you need to reposition the window, move it to an active display, and maximize it. There is no need to understand system internals to get that to work. – IInspectable May 08 '18 at 07:58
  • 1
    Check out [this thread](https://stackoverflow.com/questions/34139450/getwindowrect-returns-a-size-including-invisible-borders). I think `DwmGetWindowAttribute` with `DWMWA_EXTENDED_FRAME_BOUNDS` should give you that 8px value. Btw [here](https://blogs.msdn.microsoft.com/oldnewthing/20120326-00/?p=8003) is an explanation of why do you get such results. – Sergey Shevchenko May 08 '18 at 08:04
  • DwmGetWindowAttribute does not support Windows 7. [Support](https://msdn.microsoft.com/en-us/library/aa969515(v=vs.85).aspx) is for Windows Vista and later. I need support for Windows 7 too. I tested my code on Win7 and it give the same result, 8 hidden px around CMainFrame.The reason I need it is to decide exactly if any part of my App window is still on visible desktop or not yet. – Lubomir May 08 '18 at 09:35
  • Then I'd suggest to check whether the window has a WS_MAXIMIZE style before asking for `GetWindowRect`, if so - the window is definitely placed on one and only one desktop and you may take any action accordin to this. If it's not maximized you will get a correct window rect. – Sergey Shevchenko May 08 '18 at 09:55
  • Windows 7 comes _after_ Windows Vista. So if it is supported since (hence "Minimum supported ..." in docs) Vista it is supported on Windows 7 as well. – Christian.K May 08 '18 at 10:05
  • Ahh yes, I completely forget, Vista is older then W7. :) Sorry. I added two lines: `RECT ExendedRect;` `HRESULT hr = DwmGetWindowAttribute(pWnd->m_hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, &ExendedRect, sizeof(RECT));` Now I get linker error: error LNK2019: unresolved external symbol __imp_DwmGetWindowAttribute referenced in function. I looked for Dwmapi.lib, but I did not find any... – Lubomir May 08 '18 at 12:03
  • And now I am completely lost :-). When I mesure my NONMAXIMIZED Main frame window by GetWindowRect, I get rectangle for example 176x204 px. And When I make Alt+PrtScr and I measure the picture in any raster editor, I get 162x197 px. The Wide of real raster picture is smaller by 16 px and the high is smaller by 7 px. UFFF :-). – Lubomir May 08 '18 at 16:56
  • And now I am completely lost :-). When I mesure my NONMAXIMIZED Main frame window by GetWindowRect, I get rectangle for example 176x204 px. And When I make Alt+PrtScr and I measure the picture in any raster editor, I get 162x197 px. The Wide of real raster picture is smaller by 16 px and the high is smaller by 7 px ON WINDOWS 10 but ON WINDOWS 7 are both rectangles exactly the same UFFF :-). – Lubomir May 08 '18 at 17:08

1 Answers1

0

The 8 pixels is the border thickness (it's not always 8). You don't need borders when window is in maximized stated, so the OS hides the borders by pushing them out of view.

No part of client area gets hidden. The controls and drawings in client area are not affected.

The title bar drawing may change slightly. For example title bar's text is centered vertically, when title bar gets thinner and the text moves up slightly. So you want to leave this alone.

The maximized window does not cover the entire screen. There is a taskbar at the bottom (it's usually at the bottom and it can be 40 pixels high) We need the desktop area which does not include the taskbar. This are can be obtained from SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0), it's different that maximum screen area.

In a practical program, you may want to start the program in maximized state. Then use CWnd::ShowWindow(SW_SHOWMAXIMIZED). If you don't want maximized state, then use another method like SetWindowPos

Use GetWindowPlacement to find if window is currently in maximized state.


DwmGetWindowAttribute with DWMWA_EXTENDED_FRAME_BOUNDS can be used to find Windows 10 transparent borders when window is not maximized. It doesn't apply in this case.
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77