1

私は、WindowsXPのデスクトップをデュアルビューにするかクローンするかを自動的に切り替えるのに役立つアプリケーションを書いています。アプリケーションは、GUIに小さなwxWidgetsウィンドウを使用します。GUI内に、デュアルビューとクローンを簡単に切り替えることができるボタンがあると便利です。

デュアルビューまたはクローンを制御するためのアクセスを提供するac/c ++ライブラリはありますか?

4

2 に答える 2

2

私が知る限り、マルチビューを有効または無効にするはずのこのスクリプトをチェックしてください。スクリプト言語で書かれていますが、通常の WinAPI 関数を利用しているため、それらを見ることで何が起こっているかを知ることができるはずです。

私が知る限り、2 番目のモニターを無効にするには、2 番目のモニターでChangeDisplaySettingsExを呼び出し、幅、高さ、色深度、およびリフレッシュ レートを 0 に設定することで行われるようです。おそらく有効なパラメータ。

とにかく、スクリプトを試して (インタープリターはホームページで無料で入手できます)、探している機能が実現するかどうかを確認するのがおそらく最善でしょう (スクリプトは 2 つの特定のモニター用にハードコードされていることに注意してください。モニターの名前を付けて動作させます)。

于 2009-09-15T17:23:20.570 に答える
0

次のコードは機能します。モニターの解像度を維持しません。

void AppFrame::OnButtonModify(wxCommandEvent& event)
{
  static bool bSwitch = false;

  if (bSwitch)
  {
    ExtendExternalDisplay();
  }
  else
  {
    CloneExternalDisplay();
  }
  bSwitch = !bSwitch;
}

void AppFrame::ExtendExternalDisplay() 
{

  int   nModeSwitch = NULL;
  DEVMODE dmPrimary, dmSecondary, dmThird, savedmSecondary;

#define szPrimaryDisplay TEXT( "\\\\.\\DISPLAY1" )
#define szSecondaryDisplay TEXT( "\\\\.\\DISPLAY2" )
#define szThirdDisplay TEXT( "\\\\.\\DISPLAY3" )

  ZeroMemory( &dmPrimary, sizeof(dmPrimary) );
  dmPrimary.dmSize = sizeof(dmPrimary);
  ZeroMemory( &dmSecondary, sizeof(dmSecondary) );
  dmSecondary.dmSize = sizeof(dmSecondary);
  ZeroMemory( &dmThird, sizeof(dmThird) );
  dmThird.dmSize = sizeof(dmThird);
  ZeroMemory( &dmThird, sizeof(dmThird) );
  dmThird.dmSize = sizeof(dmThird);

  BOOL result;
  HDC handle;
  DWORD iDevNum = 0;
  DWORD dwFlags = 0;
  DISPLAY_DEVICE lpDisplayDevice, lpDisplayDeviceOne, lpDisplayDeviceTwo;    
  ZeroMemory(&lpDisplayDevice, sizeof(lpDisplayDevice));       
  ZeroMemory(&lpDisplayDeviceOne, sizeof(lpDisplayDeviceOne));
  ZeroMemory(&lpDisplayDeviceTwo, sizeof(lpDisplayDeviceTwo));
  lpDisplayDevice.cb = sizeof(lpDisplayDevice);
  lpDisplayDeviceOne.cb = sizeof(lpDisplayDeviceOne);
  lpDisplayDeviceTwo.cb = sizeof(lpDisplayDeviceTwo);

  // All this does is confirm the number of display devices the graphics board is capable of handling
  while(EnumDisplayDevices(NULL, iDevNum, &lpDisplayDevice, dwFlags))
  {
    if (iDevNum == 0)
    {
      lpDisplayDeviceOne = lpDisplayDevice;
      TRACE("DeviceName:   '%s'\n", lpDisplayDeviceOne.DeviceName);
      TRACE("DeviceString: '%s'\n", lpDisplayDeviceOne.DeviceString);
      TRACE("Flags:        %08X %s%s\n", lpDisplayDeviceOne.StateFlags,((lpDisplayDeviceOne.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) ? "Desktop " : ""), ((lpDisplayDeviceOne.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) ? "Primary" : "")); 
    }

    if (iDevNum == 1)
    {
      lpDisplayDeviceTwo = lpDisplayDevice;
      TRACE("DeviceName:   '%s'\n", lpDisplayDeviceTwo.DeviceName);
      TRACE("DeviceString: '%s'\n", lpDisplayDeviceTwo.DeviceString);
      TRACE("Flags:        %08X %s%s\n", lpDisplayDeviceTwo.StateFlags,((lpDisplayDeviceTwo.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) ? "Desktop " : ""), ((lpDisplayDeviceTwo.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) ? "Primary" : "")); 
    }

    iDevNum ++;
  }  

  // load DISPLAY1 monitor information // ENUM_CURRENT_SETTINGS     
  if (!EnumDisplaySettings(szPrimaryDisplay, ENUM_REGISTRY_SETTINGS, (DEVMODE*)&dmPrimary))
  {
    TRACE("EnumDisplaySettings unable to enumerate primary display\n");
    return;
  }

  if (!EnumDisplaySettings(szSecondaryDisplay, ENUM_REGISTRY_SETTINGS, (DEVMODE*)&dmSecondary))
    TRACE("EnumDisplaySettings unable to enumerate secondary display display\n");

  // these don't enumerate in clone mode
  if (!EnumDisplaySettings(szSecondaryDisplay, ENUM_CURRENT_SETTINGS, (DEVMODE*)&savedmSecondary))  
    TRACE("EnumDisplaySettings unable to enumerate secondary display using ENUM_CURRENT_SETTINGS settings\n");

  // disable a display, doesn't work
  //    nModeSwitch = ChangeDisplaySettingsEx (szSecondaryDisplay, NULL, NULL, NULL, NULL);
  //    CDdx::ErrorDisplayDevice(nModeSwitch);                      // test and TRACE result

  dmPrimary.dmFields = DM_POSITION;
  dmPrimary.dmPosition.x = 0;           // set DISPLAY1 as the primary display
  dmPrimary.dmPosition.y = 0;           // set DISPLAY1 as the primary display

  // set DISPLAY1 as primary display (dmPosition.x = 0)
  nModeSwitch = ChangeDisplaySettingsEx (szPrimaryDisplay, (DEVMODE*)&dmPrimary, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
//  CDdx::ErrorDisplayDevice(nModeSwitch);                      // test and TRACE result

  // despite the other lines of code this next line is neccesary to wake the video projector
  dmSecondary = dmPrimary;

  dmSecondary.dmFields = DM_POSITION | DM_PELSWIDTH | DM_PELSHEIGHT;
  dmSecondary.dmPosition.x = dmPrimary.dmPelsWidth + 1;
  dmSecondary.dmPosition.y = 0;
  dmSecondary.dmPelsWidth = dmPrimary.dmPelsWidth;          // resize the primary display to match the secondary display
  dmSecondary.dmPelsHeight = dmPrimary.dmPelsHeight;            // resize the primary display to match the secondary display    

  nModeSwitch = ChangeDisplaySettingsEx (szSecondaryDisplay, (DEVMODE*)&dmSecondary, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
//  CDdx::ErrorDisplayDevice(nModeSwitch);                      // test and TRACE result

  // load DISPLAY3 monitor information
  if (!EnumDisplaySettings(szThirdDisplay, ENUM_CURRENT_SETTINGS, (DEVMODE*)&dmThird))
  {
    TRACE("EnumDisplaySettings unable to enumerate third display display\n");
  }
  else
  {
    dmThird.dmPelsWidth = dmSecondary.dmPelsWidth;              // resize the primary display to match the secondary display
    dmThird.dmPelsHeight = dmSecondary.dmPelsHeight;            // resize the primary display to match the secondary display    
    dmThird.dmPosition.x = -dmThird.dmPelsWidth;                // set DISPLAY3 as the third display
    dmPrimary.dmPosition.y = 0;                                 // set DISPLAY1 as the third display

    // set DISPLAY3 as third display (-dmThird.dmPelsWidth)
    nModeSwitch = ChangeDisplaySettingsEx (szThirdDisplay, (DEVMODE*)&dmThird, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
//    CDdx::ErrorDisplayDevice(nModeSwitch);                        // test and TRACE result
  }

  // really important line makes the whole thing happen
  nModeSwitch = ChangeDisplaySettingsEx (NULL, NULL, NULL, 0, NULL);
//  CDdx::ErrorDisplayDevice(nModeSwitch);                          // test and TRACE result

}

void AppFrame::CloneExternalDisplay()
{
  int   nModeSwitch = NULL;
  DEVMODE dmPrimary, dmSecondary, dmThird;
#define szPrimaryDisplay TEXT( "\\\\.\\DISPLAY1" )
#define szSecondaryDisplay TEXT( "\\\\.\\DISPLAY2" )
#define szThirdDisplay TEXT( "\\\\.\\DISPLAY3" )

  ZeroMemory( &dmPrimary, sizeof(dmPrimary) );
  dmPrimary.dmSize = sizeof(dmPrimary);
  ZeroMemory( &dmSecondary, sizeof(dmSecondary) );
  dmSecondary.dmSize = sizeof(dmSecondary);
  ZeroMemory( &dmThird, sizeof(dmThird) );

  // load DISPLAY1 monitor information
  if (!EnumDisplaySettings(szPrimaryDisplay, ENUM_CURRENT_SETTINGS, (DEVMODE*)&dmPrimary))
  {
    TRACE("EnumDisplaySettings unable to enumerate primary display\n");
    return;
  }

  if (!EnumDisplaySettingsEx(szSecondaryDisplay, ENUM_REGISTRY_SETTINGS, (DEVMODE*)&dmSecondary, 0))
    TRACE("EnumDisplaySettings unable to enumerate secondary display display\n");

  dmPrimary.dmFields = DM_POSITION;
  dmPrimary.dmPosition.x = 0;                                   // set DISPLAY1 as the primary display
  dmPrimary.dmPosition.y = 0;                                   // set DISPLAY1 as the primary display

  // set DISPLAY1 as primary display (dmPosition.x = 0)
  nModeSwitch = ChangeDisplaySettingsEx (szPrimaryDisplay, (DEVMODE*)&dmPrimary, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
//  CDdx::ErrorDisplayDevice(nModeSwitch);                      // test and TRACE result

  // this should disable display
  dmSecondary.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT;
  dmSecondary.dmPelsWidth = 0; //dmPrimary.dmPelsWidth;         // resize the primary display to match the secondary display
  dmSecondary.dmPelsHeight = 0;//dmPrimary.dmPelsHeight;            // resize the primary display to match the secondary display    

  // this should clone the display
  dmSecondary.dmFields |= DM_POSITION;
  dmSecondary.dmPosition.x = 0;         // set DISPLAY1 as the primary display
  dmSecondary.dmPosition.y = 0;         // set DISPLAY1 as the primary display

  nModeSwitch = ChangeDisplaySettingsEx (szSecondaryDisplay, (DEVMODE*)&dmSecondary, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
//  CDdx::ErrorDisplayDevice(nModeSwitch);                      // test and TRACE result

  nModeSwitch = ChangeDisplaySettingsEx (NULL, NULL, NULL, 0, NULL);                                    // set DISPLAY1 as the primary display
//  CDdx::ErrorDisplayDevice(nModeSwitch);                  // test and TRACE result    

}
于 2010-05-14T17:54:19.323 に答える