【问题标题】:Can't center my console window by using the following code无法使用以下代码将我的控制台窗口居中
【发布时间】:2017-08-11 20:26:58
【问题描述】:
void Initialize_Window(void)
{
    RECT rConsole;
    GetWindowRect(GetConsoleWindow(), &rConsole);
    SetWindowPos(GetConsoleWindow(), NULL, 0, 0, 800, 700, 0);
    SetWindowLong(GetConsoleWindow(), GWL_STYLE, GetWindowLong(GetConsoleWindow(), GWL_STYLE) & ~(WS_SIZEBOX | WS_MAXIMIZEBOX));
    SetWindowPos(GetConsoleWindow(), NULL, (GetSystemMetrics(SM_CXSCREEN) - rConsole.right - rConsole.left) / 2, (GetSystemMetrics(SM_CYSCREEN) - rConsole.bottom - rConsole.top) / 2, 0, 0, SWP_NOSIZE);
}

我正在尝试使用上面的代码使我的控制台窗口居中,但似乎每次执行程序时窗口只是移动到屏幕上的随机位置,知道如何修复它吗?

【问题讨论】:

    标签: c++ winapi windows-console


    【解决方案1】:

    您需要(GetSystemMetrics(SM_CXSCREEN) - (rConsole.right - rConsole.left))/2 才能获得中心。


    旁注:您可以使用一个SetWindowPos 而不是两个(并且不需要获取窗口Rect

    const int width = 800;
    const int height = 700;
    //SetWindowLong()...
    SetWindowPos(GetConsoleWindow(), NULL,
       GetSystemMetrics(SM_CXSCREEN)/2 - width/2,
       GetSystemMetrics(SM_CYSCREEN)/2 - height/2,
       width, height, SWP_SHOWWINDOW);
    

    【讨论】:

    • 现在它不再移动但仍然没有居中
    • @BaronZhu 你能详细介绍一下not centered吗?现在在哪里?
    • 垂直居中,但不是水平居中,离中心较低的位置
    • 我不知道。你还记得更改 Y 语句吗?
    • const int 变量有效,现在它居中,感谢!
    【解决方案2】:

    不要为此使用GetSystemMetrics(),因为它只返回主要监视器的指标。如今,多显示器设置非常普遍,因此如果您忽略这一点,用户会很不高兴。

    此外,窗口通常不应与物理 监视器表面对齐,而是与不包括任务栏的工作区 对齐。是的,屏幕两侧可以有多个任务栏(在 Windows 俚语中称为“appbars”)。 full screen windows 是您实际使用完整物理表面的一个例外。

    为了涵盖这两个方面,我们可以使用MonitorFromWindow()GetMonitorInfo()

    首先,我们从窗口句柄中获取“最近”的监视器。这是完全显示窗口或窗口面积最大的监视器:

    HWND hConsoleWnd = ::GetConsoleWindow();
    HMONITOR hMonitor = ::MonitorFromWindow( hConsoleWnd, MONITOR_DEFAULTTONEAREST );
    

    然后我们得到该监视器的工作区域矩形并将窗口相对于该矩形居中:

    if( hMonitor ) 
    {
        MONITORINFO info{ sizeof(info) }; // set cbSize member and fill the rest with zero
        if( ::GetMonitorInfo( hMonitor, &info ) )
        {
            int width = 800;
            int height = 700;
            int x = ( info.rcWork.left + info.rcWork.right ) / 2 - width / 2;
            int y = ( info.rcWork.top + info.rcWork.bottom ) / 2 - height / 2;
    
            ::SetWindowPos( hConsoleWnd, nullptr, x, y, width, height,
                            SWP_NOZORDER | SWP_NOOWNERZORDER );
        }
    }
    

    就是这样。在实际应用程序中,您当然不应该对窗口大小进行硬编码,因为这是用户偏好。对于首次启动,默认大小可能是合理的,但即使这样也不应该硬编码,而是根据 Windows DPI 设置进行缩放。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-31
      • 1970-01-01
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 2013-06-30
      相关资源
      最近更新 更多