3

The docs for the ptMaxSize and ptMaxPosition components of MINMAXINFO say:

For top-level windows, this value is based on (...) the primary monitor.

Raymond Chen elaborates:

If the specified size is greater than or equal to the size of the primary monitor, then the ptMax­Size is adjusted to include the difference in size between the primary monitor and the actual monitor. (...) But if ptMax­Size does not completely cover the monitor, then its value is used as-is.

So, if I want to fill out MINMAXINFO such that a window maximised to a nonprimary monitor, in a setup with a primary monitor of a different resolution / orientation, fills the work area, but without overlapping the taskbar if that happens to be on the same monitor... how do I reliably do that?

ISTM that, once I've obtained the work area dimensions for the monitor the window is on and calculated the desired window max size:

  • if the primary monitor is the same width or wider than the work area, I can leave the width alone
  • otherwise, if the window is wider than the monitor it is on, I can subtract the difference between the monitor widths
  • otherwise, I have no means of describing the width I want

...and the same for height.

If I code that up, I do get exactly the described behaviour... except in the case where the monitors have the same resolution but different orientation, where the adjustment doesn't seem to get applied.

This all seems incredibly convoluted and odd. Am I missing or misunderstanding something? Is there actually some simple robust calculation I should be doing instead?

RandomEngy
  • 14,931
  • 5
  • 70
  • 113
moonshadow
  • 86,889
  • 7
  • 82
  • 122
  • That doesn't get put to the test very often. Is there something special about the monitor, like it automatically switching from portrait to landscape layout when you swivel it perhaps? Maybe you shouldn't worry about it too much, such a setup just isn't very common. – Hans Passant Mar 14 '16 at 12:10
  • @Hans: I would love to just bury this, but sadly, I am having to worry about it because users I support have such setups, and are experiencing unexpected behaviour. Manually handling WM_GETMINMAXINFO at all is presumably unusual, but for tedious reasons we do have to do that as well. Presumably there is *something* the default message handler does for this that I could be doing... – moonshadow Mar 14 '16 at 12:28
  • 2
    Odds that anybody here can help you are rather low. Use Microsoft Support for vexing issues like this. – Hans Passant Mar 14 '16 at 12:31

1 Answers1

0

In a situation like you describe, you should be able to calculate the RECT to which you want your window to maximize, and that RECT should be entirely on one monitor (you are talking about taking the monitor or workspace bounds of a monitor and reducing that RECT, which by definition will be entirely on one monitor). Under these circumstances, the logic is easy.

TO BE CLEAR: THIS LOGIC WILL NOT WORK IF THE DESIRED MAXIMIZED RECT OVERFLOWS THE TARGET MONITOR. THAT IS NOT OP'S CASE.

// given the HWND...
HWND hwnd = ...;

// get handles for primary and target monitor
HMONITOR hPrimaryMonitor = MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY);
HMONITOR hTargetMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

// prep primary and target monitor info structures
MONITORINFO primaryMonitorInfo { sizeof MONITORINFO };
MONITORINFO targetMonitorInfo { sizeof MONITORINFO };

// get primary and target monitor info
GetMonitorInfo(hPrimaryMonitor, &primaryMonitorInfo);
GetMonitorInfo(hTargetMonitor, &targetMonitorInfo);

// calculate your desired maximized RECT in absolute screen coordinates
RECT maximizedRect = ...;

// adjust the MINMAXINFO struct
MINMAXINFO* pMinMaxInfo = (MINMAXINFO)lParam;
pMinMaxInfo->ptMaxPosition = {
    primaryMonitorInfo.rcMonitor.left + maximizedRect.left - targetMonitorInfo.rcMonitor.left,
    primaryMonitorInfo.rcMonitor.top + maximizedRect.top - targetMonitorInfo.rcMonitor.top,
};
pMinMaxInfo->ptMaxSize = {
    maximizedRect.right - maximizedRect.left,
    maximizedRect.bottom - maximizedRect.top
};
Michael Gunter
  • 12,528
  • 1
  • 24
  • 58