ChangeDisplaySettings 似乎只适用于主监视器(返回 DISP_CHANGE_BADMODE)

Posted

技术标签:

【中文标题】ChangeDisplaySettings 似乎只适用于主监视器(返回 DISP_CHANGE_BADMODE)【英文标题】:ChangeDisplaySettings only seems to work for primary monitor (returns DISP_CHANGE_BADMODE) 【发布时间】:2020-07-12 16:58:47 【问题描述】:

我的系统中有两台显示器:笔记本电脑显示器和外接显示器。 独立是主屏幕,我想更改屏幕旋转。我从http://msdn.microsoft.com/en-us/library/ms812499.aspx 中的示例开始,这是我的简单测试代码:

DWORD displayNumber = 1;

DISPLAY_DEVICE dd;
ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);

DEVMODE dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);

if (0 != EnumDisplayDevices(NULL, displayNumber , &dd, EDD_GET_DEVICE_INTERFACE_NAME))

    if (0 != EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm))
    
        // swap height and width
        DWORD dwTemp = dm.dmPelsHeight;
        dm.dmPelsHeight = dm.dmPelsWidth;
        dm.dmPelsWidth = dwTemp;

        // determine new orientaion
        switch (dm.dmDisplayOrientation)
        
        case DMDO_DEFAULT:
            dm.dmDisplayOrientation = DMDO_270;
            break;
        case DMDO_270:
            dm.dmDisplayOrientation = DMDO_180;
            break;
        case DMDO_180:
            dm.dmDisplayOrientation = DMDO_90;
            break;
        case DMDO_90:
            dm.dmDisplayOrientation = DMDO_DEFAULT;
            break;
        default:
            break;
        
        long lRet = ChangeDisplaySettings(&dm, 0);
        if (DISP_CHANGE_SUCCESSFUL != lRet)
        
            switch (lRet)
            
                case DISP_CHANGE_BADDUALVIEW:
                    MessageBox(0, _T("DISP_CHANGE_BADDUALVIEW"), _T("ChangeDisplaySettings failed"), 0);
                    break;
                case DISP_CHANGE_BADFLAGS:
                    MessageBox(0, _T("DISP_CHANGE_BADFLAGS"), _T("ChangeDisplaySettings failed"), 0);
                    break;
                case DISP_CHANGE_BADMODE:
                    MessageBox(0, _T("DISP_CHANGE_BADMODE"), _T("ChangeDisplaySettings failed"), 0);
                    break;
                case DISP_CHANGE_BADPARAM:
                    MessageBox(0, _T("DISP_CHANGE_BADPARAM"), _T("ChangeDisplaySettings failed"), 0);
                    break;
                case DISP_CHANGE_FAILED:
                    MessageBox(0, _T("DISP_CHANGE_FAILED"), _T("ChangeDisplaySettings failed"), 0);
                    break;
                case DISP_CHANGE_NOTUPDATED:
                    MessageBox(0, _T("DISP_CHANGE_NOTUPDATED"), _T("ChangeDisplaySettings failed"), 0);
                    break;
                case DISP_CHANGE_RESTART:
                    MessageBox(0, _T("DISP_CHANGE_RESTART"), _T("ChangeDisplaySettings failed"), 0);
                    break;
                default:
                    MessageBox(0, _T("default"), _T("ChangeDisplaySettings failed"), 0);
                    break;
            
        
    

目前,第一台显示器是笔记本电脑显示器(也是主显示器),第二台显示器是外接显示器。

如果我使用displayNumber = 0 执行上面的代码,一切都会按预期进行:笔记本电脑屏幕旋转,主屏幕保持原样。

但是,如果我设置displayNumber = 1ChangeDisplaySettings 将返回DISP_CHANGE_BADMODE。似乎只能以这种方式更改主显示器的旋转。

相反,如果我将外接显示器设置为主显示器,displayNumber = 1 将按预期工作。但是,使用displayNumber = 0,当笔记本电脑显示屏(第一显示屏)按预期旋转时,外接显示器上的设置会变得一团糟。

这是怎么回事?

【问题讨论】:

外接显示器时两次都失败,您确认该显示器的显示驱动程序支持旋转更改吗? @KenWhite:是的,它适用于设置和 iRotate。但是,我同时找到了解决方案。似乎必须使用ChangeDisplaySettingsEx 【参考方案1】:

看来我需要改用ChangeDisplaySettingsEx 并明确指定显示设备。我在https://gist.github.com/umq/986635 上找到了一个有效的示例代码。

代替

long lRet = ChangeDisplaySettings(&dm, 0);

写:

long lRet = ChangeDisplaySettingsEx(dd.DeviceName, &dm, NULL, 0, NULL);

完成。

【讨论】:

你能edit这个答案并发布你的工作代码解决方案吗?在异地位置包含主要内容的答案在这里没有用。相关内容应该在此处,以便将其与问题一起保留在此处,以确保将来对其他人可用。 (不过,不要删除对其他网站的归属。) 如果这确实解决了您的问题,请记得标记自己,以帮助遇到相同问题的人。

以上是关于ChangeDisplaySettings 似乎只适用于主监视器(返回 DISP_CHANGE_BADMODE)的主要内容,如果未能解决你的问题,请参考以下文章

win32(全屏)无边框窗口重叠任务栏

Jquery点击功能似乎只工作一次

NavigationLink 似乎只占用很小的空间

最小化全屏窗口的最佳方法

onPostExecute() 似乎只被调用一次

为啥 C++ rand() 似乎只生成相同数量级的数字?