пятница, 17 апреля 2009 г.

Окно на нужном мониторе

У меня два монитора.

У других разработчиков, вероятно, был только один. И поэтому мне, как пользователю приходится страдать. Проблема вот в чем: если разработчик не позаботился о нервах пользователя, то все всплывающие окна будут показываться на основном мониторе. Если окно программы находится на втором(третьем и т.д.) мониторах, то курсору мыши приходится преодолевать огромные расстояния, чтобы нажать какую-либо кнопку на всплывающем окне. Ну и головой вертеть тоже неприятно.
При этом избежать проблемы очень просто. Нужно создавать окна на том мониторе, где находится курсор мыши. Следующая функция поможет вывести окно по центру монитора, на котором пользователь оставил курсор:
RECT WherePlaceWindow( long win_width, long win_height )
{
    POINT point = { 0 };
    MONITORINFO mi = { sizeof(MONITORINFO), 0 };
    HMONITOR hMonitor = 0;
    RECT rcArea = { 0 };

    ::GetCursorPos( &point );
    hMonitor = ::MonitorFromPoint( point, MONITOR_DEFAULTTONEAREST );
    if ( ::GetMonitorInfo( hMonitor, &mi ) ) { // тут GetMonitorInfo сработало
        rcArea.left = ( mi.rcMonitor.right + mi.rcMonitor.left - win_width ) /2;
        rcArea.top = ( mi.rcMonitor.top + mi.rcMonitor.bottom - win_height ) /2;
    } else { // если не сработало, то придумает что-то другое
        ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
        rcArea.left = (rcArea.right + rcArea.left - win_width)/2;
        rcArea.top = (rcArea.top + rcArea.bottom - win_height)/2;
    }  

    // теперь rcArea.left и rcArea.right содержат координаты левого верхнего угла окна
    return rcArea;
}
Основная идея в том, чтобы найти монитор с помощью функции MonitorFromPoint, а затем получить его координаты на десктопе. Для тех мониторов, которые левее и/или выше основного, координаты будут отрицательными, поэтому нужно быть готовым к отрицательным координатам окна везде в программе.

Комментировать в ВКонтакте