2009-09-14 44 views

回答

1

以下代碼種類的作品。它不保持顯示器分辨率。

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

退房this script據我所知,它應該啓用或禁用多視圖。雖然它是用腳本語言編寫的,但它可以利用普通的WinAPI函數,所以你應該能夠通過查看它們來了解發生了什麼。

據我所知,通過在第二個顯示器上調用ChangeDisplaySettingsEx並提供寬度,高度,顏色深度和刷新率爲0來實現禁用第二個顯示器。要重新啓用它,可以調用ChangeDisplaySettingsEx據推測第二次使用有效參數。

無論如何,最好嘗試一下腳本(解釋器在主頁上可免費使用)並查看它是否實現了您要查找的功能(請注意,該腳本是針對兩個特定監視器硬編碼的,您將不得不用您的顯示器的名稱替換它們以使其工作)。

+0

我應該說這是完全可能的,我誤解了它,這實際上並沒有啓用/禁用多視圖,所以我說這是很好的檢查(我自己,但沒有多監視器建立)。如果這不起作用,我不確定會是什麼 - 我所看到的關於multiview在線的唯一其他事情僅與驅動程序有關(而不是與應用程序本身有關) – GRB 2009-09-15 18:45:00

相關問題