无法使用以下代码使我的控制台窗口居中

时间:2017-03-20 14:02:19

标签: c++ winapi windows-console

.as-console-wrapper { max-height: 100% !important; top: 0; }

我试图通过使用上面的代码来控制我的控制台窗口,但似乎每次执行程序时窗口都会移动到我的屏幕上的随机位置,任何想法如何修复它?

2 个答案:

答案 0 :(得分:2)

您需要(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);

答案 1 :(得分: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设置进行缩放。