2012-03-08 17 views
2

本質的には、さまざまなユーザーレベルの設定の属性を変更できるサービスレベルのアプリケーションを作成しています。私は今、ディスプレイの部分に取り組んでいます。Windows XPでディスプレイをプログラム的に回転させますか? (C++/QtとWindowsAPI)

私たちはWindows 7用のソフトウェアのバージョンで動作するようになっていますが、Windows XPのディスプレイを回転させることを除いてほとんどすべてが機能します(奇妙なことに、Windows 7でも動作します)。 Microsoftが提供するWindows APIの "ChangeDisplaySettingsEX"関数は、悪い表示モード(DISP_CHANGE_BADMODE)の戻りコードを返しているので、 "危険な"表示モードを許可するフラグを適用しようとしました。安全でない表示モードを試してみてください、私たちはここで悪い**を扱っています)。そのフラグを適用すると、関数は不良フラグのパラメータ(DISP_CHANGE_BADFLAGS)を返します。

さらに調査すると、明らかに、Windows XPに固有の方法でディスプレイを回転させる方法はありません。しかし、私たちはそれを行う方法を見つけることができましたが、それはインテル(IEGD)によって提供される別のドライバを介してでした。私にとっては、これは2つのことを意味します。第1は、Windows以外のプログラムでもこれを行う方法はなく、Windows API呼び出しを使用してこれを行う方法もないということです。もう1つは、インテルがドライバーをプログラムする方法を見つけた場合、それを行う方法がいくつかあるはずです。

私は以下のコードを記入します。申し訳ありませんが、これはtlの一種です。で、だから、

 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; 

コード:; 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); 
       } 
      } 

...ポスト、私が思うのタイトルかもしれません特に底は特にエレガントに書かれていませんが、それは私たちがそれをきれいにする前にそれを行う方法を手に入れようとしていたからです。

Windows XPではこのようにディスプレイを回転させる方法は誰にも分かりますか?

答えて

2

XPでの表示とモニタのすべての機能は、WDDMと同じくらい明確ではありません。ディスプレイに「添付」されたモニターを列挙することはできますが、ChangeDisplaySettingsExを呼び出すことでモニターのモードを変更することはできません。表示モードを変更するには、ディスプレイでCDSEを呼び出します。 "\\。\ Display1"かそのようなもの。私は前の人生でXP上でこれらの機能を使って遊ぶのに時間を費やしていましたが、あなたがそれらでやりたいことをやることはできないと思います。

私が知る限り、画面の回転はXPの下のディスプレイドライバの実装の詳細であり、ユーザー空間からこれを行う標準的な方法はありません。一部のIntelドライバは、EnumDisplaySettingsを呼び出すと、ポートレートモードを一覧表示します。これらのモードの1つにディスプレイを設定すると、回転した画面になります。

要するに、すべてのグラフィックスカードベンダーに標準的な方法はありません。しかし、おそらくあなたのユーティリティアプリがその効果を達成するのと同じことをすることができます。

Windows 7では、回転とミラーリングがOSによって提供されています。 This linkは、Win7での動作の詳細を示します。私は恐れるXPのための同等のものはありません。

+0

お返事ありがとうございました。それは私が恐れていたものです。私はそれがWindows 7用のOSに組み込まれていると言いましたが、これは私が確かめることができます。私が言ったように、私たちはこの機能をWindows 7用のソフトウェアのバージョンに完全に実装しました。 これはMSDN APIの不満です。彼らは、彼らが言うこれらの効果を達成することができる関数と構造体をリストし、それはできません。しかたがない。 Windows XPですべてのグラフィックスカード/プロセッサーとそれぞれのドライバーのために普遍的に行う方法がない場合は、私はおそらく進むべきだと思います。再度、感謝します! – LeapDayWilliam

関連する問題