C++ 是否有信用证++;用于在XP和x27之间切换的多监视器库;dualview或clone的桌面设置?

C++ 是否有信用证++;用于在XP和x27之间切换的多监视器库;dualview或clone的桌面设置?,c++,c,windows,desktop,multiple-monitors,C++,C,Windows,Desktop,Multiple Monitors,我正在编写一个应用程序,它将有助于自动切换之间有WindowsXP的桌面在dualview或克隆。该应用程序为GUI使用一个小的wxWidgets窗口。如果GUI中有一个按钮,可以方便地在dualview和Clone之间切换,那就太好了 是否有一个c/c++库可以访问控制dualview或克隆?检查一下,据我所知,应该启用或禁用multiview。虽然它是用脚本语言编写的,但它确实利用了普通的WinAPI函数,因此您应该能够通过查看它们来了解发生了什么 据我所知,禁用第二个监视器似乎是通过调用第

我正在编写一个应用程序,它将有助于自动切换之间有WindowsXP的桌面在dualview或克隆。该应用程序为GUI使用一个小的wxWidgets窗口。如果GUI中有一个按钮,可以方便地在dualview和Clone之间切换,那就太好了

是否有一个c/c++库可以访问控制dualview或克隆?

检查一下,据我所知,应该启用或禁用multiview。虽然它是用脚本语言编写的,但它确实利用了普通的WinAPI函数,因此您应该能够通过查看它们来了解发生了什么

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


无论如何,最好尝试一下脚本(解释器在主页上免费提供),看看它是否实现了您想要的功能(注意,脚本是为两个特定的监视器硬编码的,您必须用监视器的名称替换它们才能使其工作).

以下代码是一种工作方式。它不能保持监视器的分辨率

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    

}

我应该说,完全有可能是我误解了它,这实际上并没有启用/禁用multiview,所以我说检查一下很好(我会自己检查,但没有多监视器设置)。但是,如果这不起作用,我不确定会发生什么——我所看到的关于multiview online的其他事情只与驱动程序有关(而不是应用程序本身)