Невозможно центрировать окно консоли, используя следующий код
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);
}
Я пытаюсь центрировать окно консоли, используя приведенный выше код, но кажется, что окно просто перемещалось в случайное положение на моем экране каждый раз, когда я запускаю программу, есть идеи, как это исправить?
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);
Не использовать GetSystemMetrics()
для этого, потому что он возвращает только метрики основного монитора. Настройка нескольких мониторов довольно распространена в наши дни, поэтому пользователи будут справедливо расстроены, если вы проигнорируете это.
Кроме того, окно обычно должно быть выровнено не с физической поверхностью монитора, а с рабочей областью, которая исключает панель (и) задач. Да, на каждой стороне экрана может быть несколько панелей задач (называемых " панели приложений" в сленге 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.