如何在未连接显示器的情况下设置屏幕分辨率?

时间:2018-01-10 09:08:22

标签: c# winapi screen-resolution

在我的公司,我们有时会使用表面自动化来自动化我们的流程。这意味着,程序正在屏幕上搜索图像并单击它们,例如:

我们使用2560 x 1440的屏幕分辨率进行开发。我们有许多计算机在那里工作 - 而且并非所有计算机都连接到显示器。当我断开显示器时,Windows正在将分辨率更改为1024 x 768我想避免。在互联网上,我读到了NirCmd这个工具 - 但在我这个大而保守的公司中使用这样的工具并不容易,我想知道,如果C#有可能的话。

我发现一个完美的解决方案 - 但是,只有连接了一个监视器(在此请求的末尾找到代码)。 即使没有连接显示器,是否有可能更改分辨率?或者是否有可能一劳永逸地定义分辨率,Windows在没有连接屏幕的情况下使用?这对我不起作用: https://superuser.com/questions/604026/how-to-set-default-screen-resolution-and-color-depth-without-monitor-in-windows

运行良好的代码 - 但仅限于连接屏幕:

[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE1
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string dmDeviceName;
    public short dmSpecVersion;
    public short dmDriverVersion;
    public short dmSize;
    public short dmDriverExtra;
    public int dmFields;

    public short dmOrientation;
    public short dmPaperSize;
    public short dmPaperLength;
    public short dmPaperWidth;

    public short dmScale;
    public short dmCopies;
    public short dmDefaultSource;
    public short dmPrintQuality;
    public short dmColor;
    public short dmDuplex;
    public short dmYResolution;
    public short dmTTOption;
    public short dmCollate;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string dmFormName;
    public short dmLogPixels;
    public short dmBitsPerPel;
    public int dmPelsWidth;
    public int dmPelsHeight;

    public int dmDisplayFlags;
    public int dmDisplayFrequency;

    public int dmICMMethod;
    public int dmICMIntent;
    public int dmMediaType;
    public int dmDitherType;
    public int dmReserved1;
    public int dmReserved2;

    public int dmPanningWidth;
    public int dmPanningHeight;
};

class User_32
{
    [DllImport("user32.dll")]
    public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);
    [DllImport("user32.dll")]
    public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags);

    public const int ENUM_CURRENT_SETTINGS = -1;
    public const int CDS_UPDATEREGISTRY = 0x01;
    public const int CDS_TEST = 0x02;
    public const int DISP_CHANGE_SUCCESSFUL = 0;
    public const int DISP_CHANGE_RESTART = 1;
    public const int DISP_CHANGE_FAILED = -1;
}

public static class ScreenResolution
{
    /// <summary>
    /// Ändert die Bildschirmauflösung in die gewünschte Größe
    /// </summary>
    /// <param name="width"></param>
    /// <param name="height"></param>
    public static void ChangeResolution(int width, int height)
    {
        Screen screen = Screen.PrimaryScreen;

        int iWidth = width;
        int iHeight = height;

        DEVMODE1 dm = new DEVMODE1();
        dm.dmDeviceName = new String(new char[32]);
        dm.dmFormName = new String(new char[32]);
        dm.dmSize = (short)Marshal.SizeOf(dm);

        if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm))
        {
            dm.dmPelsWidth = iWidth;
            dm.dmPelsHeight = iHeight;

            int iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_TEST);

            if (iRet == User_32.DISP_CHANGE_FAILED)
            {
                MessageBox.Show("Unable to process your request");
                MessageBox.Show("Description: Unable To Process Your Request. Sorry For This Inconvenience.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_UPDATEREGISTRY);

                switch (iRet)
                {
                    case User_32.DISP_CHANGE_SUCCESSFUL:
                        {
                            break;
                            //successfull change
                        }
                    case User_32.DISP_CHANGE_RESTART:
                        {
                            MessageBox.Show("Description: You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            break;
                            //windows 9x series you have to restart
                        }
                    default:
                        {
                            MessageBox.Show("Description: Failed To Change The Resolution.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            break;
                            //failed to change
                        }
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

要更改屏幕分辨率programaticaly使用ChangeDisplaySettings()。

语法:

LONG ChangeDisplaySettings(
  _In_ DEVMODE *lpDevMode,
  _In_ DWORD   dwflags
);