Click here to Skip to main content
15,881,559 members
Articles / Desktop Programming / MFC
Tip/Trick

Maximize Windows on Multiple Monitors

Rate me:
Please Sign up or sign in to vote.
4.57/5 (4 votes)
16 Dec 2014CPOL2 min read 19.9K   15  
Simple method how to make application's window maximized on different monitors in multi-monitor setup.

Introduction

For a long time, I was searching the web to solve the problem how to maximize / restore window on different monitor in multi-monitor setup, but did not find a direct way how to do this. Using information from several links, I finally get to the working and still simple solution.

Background

I noticed that if the window is moved to another monitor and then maximized, it is maximized on the correct monitor. However to do this in C++ was a harder task. My first (naive) approach was to restore the window (ShowWindow(SW_RESTORE), move it (calling SetWindowPos or MoveWindow) and then maximize it (ShowWindow(SW_MAXIMIZE). Such approach works, but adds some flickering of the window - more noticeable if window is already maximized on one monitor and it is necessary to move it maximized to another monitor.

Using the Code

If it is necessary to position the window within different monitors, it is necessary first to access rectangle in the screen coordinates of the target monitor. Note that pixel with coordinates [0, 0] is at the top-left corner of the primary monitor. Win32 API is very useful to access rectangles of the monitors:

C++
MonitorFromPoint
MonitorFromRect
MonitorFromWindow

For completeness, I present first the naive approach how the window can be maximized on the specified monitor.

C++
void Maximize(HWND hWnd, HMONITOR hMonitor)
{
    // access monitor info
    MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
    GetMonitorInfo(hMonitor, &monitorInfo);

    // restore window to normal size if it is not yet
    ShowWindow(hWnd, SW_RESTORE);

    // move window to the monitor
    SetWindowPos(hWnd, nullptr, monitorInfo.rcMonitor.left, 
    monitorInfo.rcMonitor.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE);

    // maximize window
    ShowWindow(hWnd, SW_MAXIMIZE);    
}

Flickering is more obvious if function is called several times with the same input window and same target monitor. Of course, someone can argue that it is possible to obtain the current state of the window and avoid calling the function (or making some early return in the function if the state is detected to be already correct). However such handling will just add more complexity to the function. I was thinking whether it is not possible to just hide the window and perform restoration of the state just somehow in the background and only at the end show the window. But trying to inject some SetRender(hWnd, FALSE) or ShowWindow(SW_HIDE) calls just made the output even worse. After some tests, I found that changing maximize/normal window changes just one bit (WS_MAXIMIZE) in window's styles and finally with this information I get the final good solution:

C++
void Maximize(HWND hWnd, HMONITOR hMonitor)
{
    // access monitor info
    MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
    GetMonitorInfo(hMonitor, &monitorInfo);

    const LONG currStyles = GetWindowLong(hWnd, GWL_STYLE);
    SetWindowLong(hWnd, GWL_STYLE, currStyles | WS_MAXIMIZE);
    const auto rc = monitorInfo.rcMonitor;
    SetWindowPos(&CWnd::wndTop, rc.left, rc.top, rc.Width(), rc.Height(), 0);
}

And that's it. The function works as expected and if it is even called several times, there is no flickering. The function can be easily changed to also restore window to normal size by removing WS_MAXIMIZE from the window styles and calling SetWindowPos with correct rectangle information.

Links

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --