Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

ACTIVATE and WINDOW: add a CENTER verb

Charles Dye

Super Moderator
May
5,021
130
Staff member
... to center the window on the primary monitor. This can be done now with the POS= verb plus @WINSIZE, @WINMETRICS, and some tedious arithmetic; but a CENTER verb would simplify the process considerably.
 
My CONSIZE plugin (4CONSOLE) hes options 1~9 for canonical positions (like a tic-tac-toe layout). I could supply code. It's just a lot of tedious math (which IIRC, I did somewhat cleverly)
 
I have code too, although mine probably isn't as clever as yours. So CENTER is just a synonym for ALIGN=5.
 
Here's the clever part (below). I must have had only one monitor when I wrote it. It uses the work area (rcWork) of the primary monitor (which has the task bar). So it doesn't get things quite right on my second monitor. And I'm in no mood to mess with it (now or possibly any time soon)!

Code:
    INT    x = 0,
        y = 0,
        w = rcConsole.right - rcConsole.left,
        h = rcConsole.bottom - rcConsole.top;

    if ( --center ) // 1 ~ 9  --> 0 ~ 8
    {
        switch ( center % 3 )    // horizontal, left edge default
        {
            case 1    :    x = (rcWork.right - rcWork.left - w) / 2;    // centered
                        break;
            case 2    :    x = rcWork.right - w;                        // right edge
                        break;
        }
        switch ( center / 3 )    // vertical, top edge default
        {
            case 1    :    y = (rcWork.bottom - rcWork.top - h) / 2;    // centered
                        break;
            case 2    :    y = rcWork.bottom - h;                        // bottom edge
                        break;    
        }
    }
 
Yes, that is neat. And I'm not aware of any way to get the work area for any monitor other than the primary; I think you just have to go with the monitor dimensions.
 
That should be easy. I already had this but I was using mi.rcMonitor instead of mi.rcWork. I'll report after I have tried it.

Code:
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM nMonitors)
{
    static INT index = 0;
    if ( index == nMonitors )
        return FALSE;
    MONITORINFO mi = {sizeof(MONITORINFO), 0};
    GetMonitorInfo(hMonitor, &mi);
    pMonitorRects[index++] = mi.rcWork;
    return TRUE;
}
 
Yes, that's good, thank you.

Especially for Windows 11, where the taskbar appears on all monitors, not just the primary.
 
That should be easy. I already had this but I was using mi.rcMonitor instead of mi.rcWork. I'll report after I have tried it.

Code:
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM nMonitors)
{
    static INT index = 0;
    if ( index == nMonitors )
        return FALSE;
    MONITORINFO mi = {sizeof(MONITORINFO), 0};
    GetMonitorInfo(hMonitor, &mi);
    pMonitorRects[index++] = mi.rcWork;
    return TRUE;
}
It does work. Window RECTs (notably that of the console) include a 6-8-pixel shadow on all sides. That makes the result of putting the console window at a monitor edge somewhat less than ideal. Fudging it would lead to the shadow bleeding onto another monitor in many cases. Do you know if you can get rid of the shadows altogether? They don't do much for me.
 
Curious ... is it one long taskbar spanning two minitors or a one-monitor taskbar duplicated on another monitor?
 
Curious ... is it one long taskbar spanning two minitors or a one-monitor taskbar duplicated on another monitor?

One taskbar per monitor, but they aren't quite identical. Both have the Start button, quick launch icons, and the clock. Only the taskbar on the primary monitor has the system tray and notifications button.
 
It does work. Window RECTs (notably that of the console) include a 6-8-pixel shadow on all sides. That makes the result of putting the console window at a monitor edge somewhat less than ideal. Fudging it would lead to the shadow bleeding onto another monitor in many cases. Do you know if you can get rid of the shadows altogether? They don't do much for me.

According to MSDN, you can use DwmGetWindowAttribute() to get the true frame size sans shadow. I have not tried it myself.
 
You can turn off the shadows here (after "Find a setting" ... perf), but it doesn't seem to affect Get/SetWindowPos (I didn't logout or restart).

1719075439152.png


According to MSDN, you can use DwmGetWindowAttribute() to get the true frame size sans shadow.

Yeah but after DwmGetWindowAttribute, I reckon you'd have to do a lot of monkeying around when you SetWindowPos.
 
Funny, using Get/SetWondowPos and no shadow-monkeying, I get the shadow on the left, right, and bottom, but not on the top.

1719076389555.png
 

Similar threads

Back
Top