列挙と表示コントロール

コンピューター上のすべてのデバイスを列挙するには、 EnumDisplayDevices 関数を呼び出します。 返される情報は、デスクトップの一部であるモニターも示します。

クリッピング領域と交差するデスクトップ上のデバイスを列挙するには、 EnumDisplayMonitors を呼び出します。 これにより、 GetMonitorInfo で使用される各モニターに HMONITOR ハンドルが返されます。 仮想画面のすべてのデバイスを列挙するには、 EnumDisplayMonitors を使用します。 次のコードに示すように、

EnumDisplayMonitors(NULL, NULL, MyInfoEnumProc, 0);  

ディスプレイ デバイスに関する情報を取得するには、 EnumDisplaySettings または EnumDisplaySettingsEx を使用します。

ChangeDisplaySettingsEx 関数は、コンピューター上のディスプレイ デバイスを制御するために使用されます。 仮想デスクトップ上のモニターの位置の指定やディスプレイのビット深度の変更など、デバイスの構成を変更できます。 通常、アプリケーションではこの関数は使用されません。 プログラムで複数モニター・システムにディスプレイ・モニターを追加するには、 DEVMODE.dmFields を DM_POSITION に設定し、追加するモニターの位置 ( DEVMODE.dmPosition を使用) を指定します。これは、既存のモニターの表示領域の少なくとも 1 ピクセルに隣接しています。 モニターをデタッチするには、 DEVMODE.dmFields をDM_POSITIONに設定し、 DEVMODE.dmPelsWidthDEVMODE.dmPelsHeight を 0 に設定します。

次のコードは、すべてのセカンダリ ディスプレイ デバイスをデスクトップからデタッチする方法を示しています。

void DetachDisplay()
{
    BOOL            FoundSecondaryDisp = FALSE;
    DWORD           DispNum = 0;
    DISPLAY_DEVICE  DisplayDevice;
    LONG            Result;
    TCHAR           szTemp[200];
    int             i = 0;
    DEVMODE   defaultMode;

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

    // get all display devices
    while (EnumDisplayDevices(NULL, DispNum, &DisplayDevice, 0))
        {
        ZeroMemory(&defaultMode, sizeof(DEVMODE));
        defaultMode.dmSize = sizeof(DEVMODE);
        if ( !EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName, ENUM_REGISTRY_SETTINGS, &defaultMode) )
                  OutputDebugString("Store default failed\n");

        if ((DisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) &&
            !(DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE))
            {
            DEVMODE    DevMode;
            ZeroMemory(&DevMode, sizeof(DevMode));
            DevMode.dmSize = sizeof(DevMode);
            DevMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION
                        | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ;
            Result = ChangeDisplaySettingsEx((LPSTR)DisplayDevice.DeviceName, 
                                            &DevMode,
                                            NULL,
                                            CDS_UPDATEREGISTRY,
                                            NULL);

            //The code below shows how to re-attach the secondary displays to the desktop

            //ChangeDisplaySettingsEx((LPSTR)DisplayDevice.DeviceName,
            //                       &defaultMode,
            //                       NULL,
            //                       CDS_UPDATEREGISTRY,
            //                       NULL);

            }

        // Reinit DisplayDevice just to be extra clean

        ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
        DisplayDevice.cb = sizeof(DisplayDevice);
        DispNum++;
        } // end while for all display devices
}

アプリケーションは、ディスプレイ デバイスごとに、デバイスの構成パラメーターと場所パラメーターを記述する情報をレジストリに保存できます。 また、 DISPLAY_DEVICE構造の DISPLAY_DEVICE_ATTACHED_TO_DESKTOP フラグを使用して、デスクトップの一部であるディスプレイとそうでないディスプレイをアプリケーションで判断することもできます。 すべての構成情報がレジストリに格納されると、アプリケーションは ChangeDisplaySettingsEx をもう一度呼び出して、再起動を必要とせず、設定を動的に変更できます。