Вращать дисплеи программно в Windows XP?(C ++ / Qt и WindowsAPI) - PullRequest
2 голосов
/ 09 марта 2012

Итак, по сути, мы пишем приложение уровня обслуживания, которое может изменять атрибуты различных настроек уровня пользователя. Я сейчас работаю над дисплеем.

Мы заставили его работать для версии нашего программного обеспечения для Windows 7, и почти все работает, за исключением поворота дисплеев в Windows XP (что, как ни странно, работает в Windows 7). Функция «ChangeDisplaySettingsEX» в API Windows, предоставляемая Microsoft, возвращает код возврата для плохого режима отображения (DISP_CHANGE_BADMODE), поэтому я попытался применить флаг, чтобы разрешить «небезопасные» режимы отображения (потому что я бунтарь. Да, я попробую небезопасные режимы отображения, будьте осторожны: здесь мы имеем дело с плохими **). Применение этого флага привело к тому, что функция вернула параметр недопустимых флагов (DISP_CHANGE_BADFLAGS).

После дальнейших исследований очевидно, что в Windows XP нет способа повернуть дисплей. Мы могли бы, однако, найти способ сделать это, но это был отдельный драйвер, предоставленный Intel (IEGD). Для меня это означает две вещи: первая состоит в том, что нет способа сделать это даже не программно через Windows, и нет способа сделать это с помощью вызовов Windows API. Во-вторых, если Intel нашла способ запрограммировать драйвер для этого, должен быть НЕКОТОРЫЙ способ сделать это.

Я положу немного кода ниже, извините, это вроде tl; dr. Версия tl; dr может быть просто названием поста, я полагаю ...

...

    else if( key == "Rotation" ) {
                QString rotationsStr = value.toString();
                QStringList rotations = rotationsStr.split(",", QString::SkipEmptyParts);

                for( int i = 0; i < currentLayout.size(); i++){
                    WinMon tempMon = currentLayout.at(i);

                    DWORD dwTemp = tempMon.dm.dmPelsHeight;
                    if(rotations.size() > 1) {
                        switch( rotations.at(i).toInt(&ok, 10) )
                        {
                        case 0:     // Rotate 0 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_DEFAULT;
                            break;

                        case 1:     // Rotate 90 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_90;
                            break;

                        case 2:     // Rotate 180 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_180;
                            break;

                        case 3:     // Rotate 270 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_270;
                            break;

                        }
                    }

                    else
                    {
                        switch( rotations.at(0).toInt(&ok, 10) ) {

                        case 0:     // Rotate 0 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_DEFAULT;
                            break;

                        case 1:     // Rotate 90 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_90;
                            break;

                        case 2:     // Rotate 180 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_90 ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_270){
                                tempMon.dm.dmPelsHeight= tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_180;
                            break;

                        case 3:     // Rotate 270 degrees

                            tempMon.dm.dmFields = DM_DISPLAYORIENTATION;
                            if(currentLayout.at(i).dm.dmDisplayOrientation == DMDO_DEFAULT ||
                               currentLayout.at(i).dm.dmDisplayOrientation == DMDO_180){
                                tempMon.dm.dmPelsHeight = tempMon.dm.dmPelsWidth;
                                tempMon.dm.dmPelsWidth = dwTemp;
                                tempMon.dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
                            }
                            tempMon.dm.dmDisplayOrientation = DMDO_270;
                            break;
                        }
                    }

                    currentLayout.replace(i, tempMon);
                }
            }

Мы применяем настройки ниже:

     long returnCode;

    for( int i=0; i < currentLayout.size(); i++ ){
        WinMon myMon = currentLayout.at(i);

        returnCode = ChangeDisplaySettingsEx(myMon.name.utf16(),(DEVMODE*)&(myMon.dm), NULL, CDS_UPDATEREGISTRY|CDS_NORESET, NULL);
        if( returnCode != DISP_CHANGE_SUCCESSFUL )
        {
            qWarning() << "Failed to change display " << i;
            qWarning() << "Return Code:  " << returnCode;

            qWarning() << " ";
            qWarning() << "DISP_CHANGE_SUCCESSFUL  : " << DISP_CHANGE_SUCCESSFUL;
            qWarning() << "DISP_CHANGE_BADDUALVIEW : " << DISP_CHANGE_BADDUALVIEW;
            qWarning() << "DISP_CHANGE_BADFLAGS    : " << DISP_CHANGE_BADFLAGS;
            qWarning() << "DISP_CHANGE_BADMODE     : " << DISP_CHANGE_BADMODE;
            qWarning() << "DISP_CHANGE_BADPARAM    : " << DISP_CHANGE_BADPARAM;
            qWarning() << "DISP_CHANGE_FAILED      : " << DISP_CHANGE_FAILED;
            qWarning() << "DISP_CHANGE_NOTUPDATED  : " << DISP_CHANGE_NOTUPDATED;
            qWarning() << "DISP_CHANGE_RESTART     : " << DISP_CHANGE_RESTART;
            qWarning() << " ";
            qWarning() << "Again, your return value was: " << returnCode;
            return false;
        }
    }

    ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
    return true;

Так что код внизу, в частности, написан не очень элегантно, но это потому, что мы пытались разобраться, как это сделать, прежде чем очистить его.

Итак, у кого-нибудь есть идеи, как повернуть дисплеи таким образом для Windows XP?

1 Ответ

2 голосов
/ 09 марта 2012

Все функции дисплея и монитора в XP не такие четкие, как в WDDM.Хотя вы можете перечислять мониторы, «прикрепленные» к дисплею, вы не можете изменить режим монитора, вызвав ChangeDisplaySettingsEx.Чтобы изменить режим отображения, вы вызываете CDSE с отображением, например, «\\. \ Display1» или что-то в этом роде.Я потратил много времени, играя с этими функциями на XP в прошлой жизни, и я не думаю, что вы можете делать с ними то, что хотите.

Насколько я знаю, поворот экрана - этоподробности реализации драйвера дисплея под XP, и нет стандартного способа сделать это из пространства пользователя.Некоторые драйверы Intel отображают портретные режимы при вызове EnumDisplaySettings.Установив дисплей в один из этих режимов, вы получите повернутый экран.

Короче говоря, не существует стандартного способа сделать это для всех поставщиков видеокарт.Но вы можете сделать то же самое, что и их служебные приложения для достижения эффекта.

В Windows 7 ОС обеспечивает поворот и зеркальное отображение. Эта ссылка должна дать вам подробную информацию о том, как все работает под Win7.Боюсь, для XP не существует эквивалента.

...