我如何仅更改一台显示器的分辨率

How I change the resolution one monitor only

比如我的电脑有两个显示器,主显示器的分辨率是800*600,另一个显示器的分辨率是1600*900。

我想在 一台显示器上定义分辨率?

函数'SetDisplayConfig'改变两个小屏幕的分辨率...

https://docs.microsoft.com/fr-fr/windows-hardware/drivers/display/ccd-apis https://docs.microsoft.com/fr-fr/windows/win32/api/winuser/nf-winuser-setdisplayconfig

[DllImport("User32.dll")]
        public static extern int SetDisplayConfig(
            uint numPathArrayElements,
            [In] DisplayConfigPathInfo[] pathArray,
            uint numModeInfoArrayElements,
            [In] DisplayConfigModeInfo[] modeInfoArray,
            SdcFlags flags
        );
private static Boolean SetDisplaySettings(int Id_Monitor, uint Width, uint Height, uint Scaling)
        {
            try
            {
                CCDWrapper.DisplayConfigPathInfo[] pathInfoArray = new CCDWrapper.DisplayConfigPathInfo[0] { };
                CCDWrapper.DisplayConfigModeInfo[] modeInfoArray = new CCDWrapper.DisplayConfigModeInfo[0] { };
                CCDWrapper.MonitorAdditionalInfo[] additionalInfo = new CCDWrapper.MonitorAdditionalInfo[0] { };
                bool Status = GetDisplaySettings(ref pathInfoArray, ref modeInfoArray, ref additionalInfo, true);                       

                CCDWrapper.DisplayConfigPathInfo[] pathInfoArrayCurrent = new CCDWrapper.DisplayConfigPathInfo[0] { };
                CCDWrapper.DisplayConfigModeInfo[] modeInfoArrayCurrent = new CCDWrapper.DisplayConfigModeInfo[0] { };
                CCDWrapper.MonitorAdditionalInfo[] additionalInfoCurrent = new CCDWrapper.MonitorAdditionalInfo[0] { };
                bool StatusCurrent = GetDisplaySettings(ref pathInfoArrayCurrent, ref modeInfoArrayCurrent, ref additionalInfoCurrent, false);

                if (StatusCurrent)
                {
                    for (int iPathInfo = 0; iPathInfo <= pathInfoArray.Length-1; iPathInfo++)
                    //for (int iPathInfo = 0; iPathInfo <= pathInfoArray.Length - 1; iPathInfo++)                      
                    {                        
                        for (int iPathInfoCurrent = 0; iPathInfoCurrent <= pathInfoArrayCurrent.Length - 1; iPathInfoCurrent++)
                        {
                            if ((pathInfoArray[iPathInfo].sourceInfo.id == pathInfoArrayCurrent[iPathInfoCurrent].sourceInfo.id) && (pathInfoArray[iPathInfo].targetInfo.id == pathInfoArrayCurrent[iPathInfoCurrent].targetInfo.id))
                            {
                                pathInfoArray[iPathInfo].sourceInfo.adapterId.LowPart = pathInfoArrayCurrent[iPathInfoCurrent].sourceInfo.adapterId.LowPart;
                                pathInfoArray[iPathInfo].targetInfo.adapterId.LowPart = pathInfoArrayCurrent[iPathInfoCurrent].targetInfo.adapterId.LowPart;
                                pathInfoArray[iPathInfo].targetInfo.scaling = (CCDWrapper.DisplayConfigScaling)Scaling;
                                break;                                                                        
                            }
                        }                                                
                    }

                    for (int iModeInfo = 0; iModeInfo <= modeInfoArray.Length - 1; iModeInfo++)
                    {                       
                        for (int iPathInfo = 0; iPathInfo <= pathInfoArray.Length - 1; iPathInfo++)
                        {
                            if ((modeInfoArray[iModeInfo].id == pathInfoArray[iPathInfo].targetInfo.id) && (modeInfoArray[iModeInfo].infoType == CCDWrapper.DisplayConfigModeInfoType.Target))
                            {
                            for (int iModeInfoSource = 0; iModeInfoSource <= modeInfoArray.Length - 1; iModeInfoSource++)
                            {
                                if ((modeInfoArray[iModeInfoSource].id == pathInfoArray[iPathInfo].sourceInfo.id) && (modeInfoArray[iModeInfoSource].adapterId.LowPart == modeInfoArray[iModeInfo].adapterId.LowPart) && (modeInfoArray[iModeInfoSource].infoType == CCDWrapper.DisplayConfigModeInfoType.Source))
                                {  
                                    modeInfoArray[iModeInfoSource].adapterId.LowPart = pathInfoArray[iPathInfo].sourceInfo.adapterId.LowPart;
                                    modeInfoArray[iModeInfoSource].sourceMode.height = Height;
                                    modeInfoArray[iModeInfoSource].sourceMode.width = Width;
                                    break;                                            
                                }
                            }
                            modeInfoArray[iModeInfo].adapterId.LowPart = pathInfoArray[iPathInfo].targetInfo.adapterId.LowPart;
                            break;
                            }
                        }                                              
                    }

                    uint numPathArrayElements = System.Convert.ToUInt32(pathInfoArray.Length);
                    uint numModeInfoArrayElements = System.Convert.ToUInt32(modeInfoArray.Length);

                    long Result = CCDWrapper.SetDisplayConfig(numPathArrayElements, pathInfoArray, numModeInfoArrayElements, modeInfoArray, CCDWrapper.SdcFlags.Apply | CCDWrapper.SdcFlags.UseSuppliedDisplayConfig | CCDWrapper.SdcFlags.SaveToDatabase | CCDWrapper.SdcFlags.NoOptimization | CCDWrapper.SdcFlags.AllowChanges);
                    if (Result == 0)
                            return true;
                        else
                            return false;                                   
                }
                else
                    return false;                
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("ResolutionEcran", "Erreur SetDisplaySettings : " + ex.Message, EventLogEntryType.Error);
                return false;
            }
        }
private static Boolean GetDisplaySettings(ref CCDWrapper.DisplayConfigPathInfo[] pathInfoArray, ref CCDWrapper.DisplayConfigModeInfo[] modeInfoArray, ref CCDWrapper.MonitorAdditionalInfo[] additionalInfo, Boolean ActiveOnly, [System.Runtime.InteropServices.Optional] int ID_Monitor)
        {
            uint numPathArrayElements;
            uint numModeInfoArrayElements;

            CCDWrapper.QueryDisplayFlags queryFlags = CCDWrapper.QueryDisplayFlags.AllPaths;
            if (ActiveOnly)
            {
                //queryFlags = CCDWrapper.QueryDisplayFlags.OnlyActivePaths;
                queryFlags = CCDWrapper.QueryDisplayFlags.OnlyActivePaths;
            }

            var status = CCDWrapper.GetDisplayConfigBufferSizes(queryFlags, out numPathArrayElements, out numModeInfoArrayElements);
            if (status == 0)
            {
                pathInfoArray = new CCDWrapper.DisplayConfigPathInfo[numPathArrayElements];
                modeInfoArray = new CCDWrapper.DisplayConfigModeInfo[numModeInfoArrayElements];
                additionalInfo = new CCDWrapper.MonitorAdditionalInfo[numModeInfoArrayElements];                               

                status = CCDWrapper.QueryDisplayConfig(queryFlags, ref numPathArrayElements, pathInfoArray, ref numModeInfoArrayElements, modeInfoArray, IntPtr.Zero);
                if (status == 0)
                {                    
                    for (var iMode = 0; iMode < numModeInfoArrayElements; iMode++)
                    {
                        if (modeInfoArray[iMode].infoType == CCDWrapper.DisplayConfigModeInfoType.Target)
                        {
                            try
                            {
                                additionalInfo[iMode] = CCDWrapper.GetMonitorAdditionalInfo(modeInfoArray[iMode].adapterId, modeInfoArray[iMode].id);
                            }
                            catch (Exception)
                            {
                                additionalInfo[iMode].valid = false;
                            }
                        }
                    }
                    return true;
                }
                else
                {
                    //Erreur : Querying display;
                }
            }
            else
            {
                //Erreur : Taille Buffer;
            }

            return false;
        }

使用ChangeDisplaySettingsEx函数将指定显示设备的设置更改为指定的图形模式。以下是您可以参考的示例。

#include <windows.h>

int main()
{
    for (DWORD devNum = 0; ; devNum++)
    {
        DISPLAY_DEVICE dev = {0};
        dev.cb = sizeof(DISPLAY_DEVICE);

        if (!EnumDisplayDevices(NULL, devNum, &dev, EDD_GET_DEVICE_INTERFACE_NAME))
            break;

        wprintf(L"Display name: %s \n", dev.DeviceName);

        DEVMODE dMode = { 0 };
        dMode.dmSize = sizeof(dMode);

        if (!EnumDisplaySettings(dev.DeviceName, ENUM_CURRENT_SETTINGS, &dMode))
        {
            wprintf(L"EnumDisplaySettings error: %d \n", GetLastError());
            continue;
        }

        wprintf(L"Display old settings: \n");
        wprintf(L"dmBitsPerPel: %d \n", dMode.dmBitsPerPel);
        wprintf(L"dmPelsWidth: %d \n", dMode.dmPelsWidth);
        wprintf(L"dmPelsHeight: %d \n", dMode.dmPelsHeight);
        wprintf(L"dmDisplayFlags: %x \n", dMode.dmDisplayFlags);
        wprintf(L"dmDisplayFrequency: %d \n", dMode.dmDisplayFrequency);

        dMode.dmPelsWidth = 800;
        dMode.dmPelsHeight = 600;
        ChangeDisplaySettingsEx(dev.DeviceName, &dMode, NULL, 0, NULL);

        DEVMODE dModeNew = { 0 };
        dModeNew.dmSize = sizeof(DEVMODE);
        if (!EnumDisplaySettings(dev.DeviceName, ENUM_CURRENT_SETTINGS, &dModeNew))
        {
            wprintf(L"EnumDisplaySettings error: %d \n", GetLastError());
            continue;
        }

        wprintf(L"Display new settings: \n");
        wprintf(L"dmBitsPerPel: %d \n", dModeNew.dmBitsPerPel);
        wprintf(L"dmPelsWidth: %d \n", dModeNew.dmPelsWidth);
        wprintf(L"dmPelsHeight: %d \n", dModeNew.dmPelsHeight);
        wprintf(L"dmDisplayFlags: %x \n", dModeNew.dmDisplayFlags);
        wprintf(L"dmDisplayFrequency: %d \n", dModeNew.dmDisplayFrequency);

    }

    getchar();
}

我将 dwflags 设置为 0 让当前屏幕的图形模式动态变化。请参阅 ChangeDisplaySettingsEx's documentdwflags 参数部分,以决定您希望如何更改图形模式。

抱歉我回复晚了...我没来。

我还需要更改显示器的缩放比例(某些分辨率下的黑条被移除)。

[Flags]
        public enum DisplayConfigScaling : uint
        {
            Zero = 0x0,

            Identity = 1,
            Centered = 2,
            Stretched = 3,
            Aspectratiocenteredmax = 4,
            Custom = 5,
            Preferred = 128,
            ForceUint32 = 0xFFFFFFFF
        }

函数'ChangeDisplaySettingsEx'可能会改变显示器的比例?

非常感谢您的帮助。