枚举和显示控件

若要枚举计算机上的所有设备,请调用 EnumDisplayDevices 函数。 返回的信息还指示哪个监视器是桌面的一部分。

若要枚举桌面上与剪辑区域相交的设备,请调用 EnumDisplayMonitors。 这会向每个监视器返回 HMONITOR 句柄,该句柄与 GetMonitorInfo 一起使用。 若要枚举虚拟屏幕中的所有设备,请使用 EnumDisplayMonitors。 如以下代码所示:

EnumDisplayMonitors(NULL, NULL, MyInfoEnumProc, 0);  

若要获取有关显示设备的信息,请使用 EnumDisplaySettingsEnumDisplaySettingsEx

ChangeDisplaySettingsEx 函数用于控制计算机上的显示设备。 它可以修改设备的配置,例如指定监视器在虚拟桌面上的位置和更改任何显示器的位深度。 通常,应用程序不使用此函数。 若要以编程方式将显示监视器添加到多监视器系统,请将 DEVMODE.dmFields 设置为 DM_POSITION,并使用 DEVMODE.dmPosition ) 为要添加的监视器指定与现有监视器显示区域至少一个像素相邻 (的位置。 若要分离监视器,请将 DEVMODE.dmFields 设置为 DM_POSITION,并将 DEVMODE.dmPelsWidthDEVMODE.dmPelsHeight 设置为零。

以下代码演示如何从桌面分离所有辅助显示设备:

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 来动态更改设置,无需重启。