2009-09-14 4 views
1

J'écris une application où il serait utile de basculer automatiquement entre le bureau de Windows XP en dualview ou cloné. L'application utilise une petite fenêtre wxWidgets pour l'interface graphique. Ce serait bien d'avoir un bouton dans l'interface graphique qui pourrait facilement basculer entre dualview et cloned.Existe-t-il une bibliothèque multi-moniteurs c/C++ permettant de changer le réglage de bureau de dualview ou de clone de XP?

Y a-t-il une bibliothèque c/C++ qui donne accès au contrôle dualview ou cloné?

Répondre

1

Le tri de code suivant fonctionne. Il ne garde pas la résolution du moniteur.

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  

} 
2

Découvrez le this script qui, pour autant que je sache, est supposé activer ou désactiver multiview. Bien qu'il soit écrit dans un langage de script, il tire parti des fonctions WinAPI normales, vous devriez donc être capable de découvrir ce qui se passe en les regardant. Pour autant que je sache, il semble que la désactivation d'un second moniteur se fasse en appelant ChangeDisplaySettingsEx sur le deuxième moniteur et en fournissant une largeur, hauteur, profondeur de couleur et taux de rafraîchissement de 0. Pour le réactiver, on appellerait ChangeDisplaySettingsEx une deuxième fois avec des paramètres valables probablement.

Quoi qu'il en soit, il serait probablement préférable d'essayer le script (l'interpréteur est disponible gratuitement sur la page d'accueil) et voir si elle atteint la fonctionnalité que vous recherchez (notez que le script est codé en dur pour devra les remplacer par les noms de vos moniteurs pour le faire fonctionner).

+0

devrais-je dire qu'il est tout à fait possible que je mal interprété et que cela ne permet pas en fait/désactiver MultiView, alors que je dis qu'il est bon de vérifier (je me mais ne dispose pas d'un multi-écrans installer). Si cela ne fonctionne pas, je ne suis pas sûr de ce que je vais faire - les seules autres choses que j'ai vues à propos de multiview en ligne ne concernent que les pilotes (et pas les applications en soi) – GRB

Questions connexes