2

プログラムで2番目のモニターの表示が重複するようにしようとしています。以下の私の機能は、2番目のモニターの表示を「重複表示」に変更する必要があります。つまり、2番目のモニターに1番目/プライマリモニターにあるすべてのものを表示させます。

私の問題:関数を実行すると、2番目のモニターが正常に検出され、DEVMODE dmPosition.xプロパティを変更することで、モニターの表示x座標が0、つまりプライマリモニター画面の左側に変更されます。私の2台のモニターは両方とも自動的に更新されます(黒くなり、画面が再表示されます)が、2台目のモニターには重複表示ではなく拡張表示があります。

2台目のモニターの表示を複製する方法はありますか?

関連情報: -2台目の
モニターはLCD TVであり、HDMI経由でラップトップに接続されています-私の機能コードは、再起動せずに2台目のモニターを接続する方法を説明するこのMSDNページ
の例とまったく同じです。LINE30を変更しました。 -1回のWinAPI関数呼び出しを使用してWindows7の表示を変更できることは承知していますが、Windows2000以降で動作するにはプログラムが必要です。

// From http://support.microsoft.com/kb/308216/en-gb Title: You must restart...
BOOL TVManager::AddUnattachedDisplayDeviceToDesktop()
{
    DWORD DispNum = 0;
    DISPLAY_DEVICE DisplayDevice;
    DEVMODE defaultMode;
    HDC hdc;
    int nWidth;
    BOOL bFoundSecondary = FALSE;

    hdc    = GetDC(0);
    nWidth = GetDeviceCaps(hdc, HORZRES);
    ReleaseDC(0, hdc);

    // Initialize DisplayDevice.
    ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
    DisplayDevice.cb = sizeof(DisplayDevice);

    // Get display devices.
    while ((EnumDisplayDevices(NULL, DispNum, &DisplayDevice, 0)) && (bFoundSecondary == FALSE))
    { 
        ZeroMemory(&defaultMode, sizeof(DEVMODE));
        defaultMode.dmSize = sizeof(DEVMODE);
        if (!EnumDisplaySettings((LPTSTR)DisplayDevice.DeviceName, ENUM_REGISTRY_SETTINGS, &defaultMode)) {
            printf("1\n");
            return FALSE; // Store default failed
        }

        if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) {
            //Found the first secondary device.
            _tprintf(_T("Found the first secondary device: Name: %s, Pos: %d, Width: %d\n"), DisplayDevice.DeviceName, defaultMode.dmPosition.x, nWidth);
            bFoundSecondary           = TRUE;
            defaultMode.dmPosition.x = 0; // LINE CHANGED: ONLY CHANGE FROM MSDN'S CODE
            defaultMode.dmFields      = DM_POSITION; 
            ChangeDisplaySettingsEx((LPTSTR)DisplayDevice.DeviceName, &defaultMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL); 
            _tprintf(_T("Check for error: %u\n"), GetLastError()); // prints "Check for error: 0" which means no error occurred

            // A second call to ChangeDisplaySettings updates the monitor.
            ChangeDisplaySettings(NULL, 0); 
            _tprintf(_T("Check for error: %u\n"), GetLastError()); // prints "Check for error: 0" which means no error occurred
        } 

        // Reinitialize DisplayDevice. 
        ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
        DisplayDevice.cb = sizeof(DisplayDevice);
        DispNum++;
    } // End while the display devices. 

    return TRUE;
}
4

1 に答える 1

4

Windows XP 以前では、Vista 以降 (WDDM) とは異なるディスプレイ ドライバ モデル (XPDM) を使用しています。XPDM でのミラーリングは、グラフィック カードのベンダーに大きく依存します。一般的な考え方は、デスクトップを拡張するために拡張ドライバーを提供することです。デスクトップの一部をミラーリングするには、ミラー ドライバーを提供します。

ほとんどの場合、各拡張ドライバーはグラフィック カードの 1 つの出力を担当します。デュアル DVI カードを持っているとしましょう。デバイス マネージャに 2 つの拡張ドライバが表示され、それぞれが DVI ポートの 1 つを担当します。デスクトップを拡張するようにモニターを設定する場合は、拡張ドライバーを有効にして適切な場所に配置します。

ミラーリングはよりトリッキーです。これは、異なるカード ベンダー間で動作が少し異なる場合がある場所です。OS の観点からは、これが起こっていることです。グラフィックス カード ポートに関連付けられている拡張ドライバーが無効になっています。ミラー ドライバがまだ有効になっていない場合は、有効になります。次に、ミラー ドライバを (0, 0) に配置します。次に、グラフィックカード/ドライバー内でいくつかのトリックが発生し、モニターはミラードライバーの画面バッファー内にあるものを表示しています.

XPDM でモニターをミラー モードに設定するには、現在表示されている拡張ドライバーを見つけて無効にする必要があります。これだけで十分です。一部のベンダーは自動的に残りの作業を行い、プライマリ ディスプレイのミラーリングを開始します。一部のベンダーは、拡張モードに入る前にモニターが最後に行っていたことをすべて実行します。モニターに何も表示されない場合は、ミラー ドライバーを有効にしてみてください。ミラー ドライバを見つけて有効にした場合、その後どうなるかは誰にもわかりません。モニターをミラー ドライバーに接続する一般的な方法はありません。

于 2013-03-01T16:11:53.937 に答える