代码之家  ›  专栏  ›  技术社区  ›  Paul Kelly

是否有一个C/C++多监视器库用于在DualVIEW或克隆的XP桌面设置之间进行更改?

  •  1
  • Paul Kelly  · 技术社区  · 15 年前

    我正在编写一个应用程序,它将有助于在dualview中自动切换WindowsXP的桌面或克隆。应用程序使用一个小的wxwidgets窗口作为GUI。在图形用户界面中有一个按钮可以很容易地在dualview和克隆之间切换,这将是一件好事。

    是否有一个C/C++库可以访问DalalVIEW或克隆?

    2 回复  |  直到 14 年前
        1
  •  2
  •   GRB    15 年前

    退房 this script 据我所知,它应该启用或禁用多视图。虽然它是用脚本语言编写的,但它确实利用了普通的winapi函数,因此您应该能够通过查看这些函数来了解发生了什么。

    据我所知,禁用第二个监视器似乎是通过调用 ChangeDisplaySettingsEx 在第二个显示器上,提供宽度、高度、颜色深度和刷新率0。要重新启用它,可以使用有效参数再次调用changedisplaysettingsex。

    不管怎样,最好尝试一下脚本(在主页上可以免费使用解释器),看看它是否实现了您要寻找的功能(注意,脚本是为两个特定的监视器硬编码的,您必须用监视器的名称替换它们才能使其工作)。

        2
  •  1
  •   Paul Kelly    14 年前

    以下代码类型的工作。它不能保持监视器的分辨率。

    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    
    
    }