You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用QueryDisplayConfig/SetDisplayConfig API修改屏幕分辨率失败,返回错误代码87求助

QueryDisplayConfig/SetDisplayConfig API修改屏幕分辨率失败,返回错误代码87求助

我现在尝试用QueryDisplayConfigSetDisplayConfig这两个API修改屏幕分辨率,但不管执行什么操作,调用后始终返回错误代码87(查资料得知是参数无效的意思)。我已经按照文档要求,先调用GetDisplayConfigBufferSizes获取缓冲区大小,但问题依然存在,实在搞不清楚哪里出了问题。

(附相关操作截图:)
Display Config Error Screenshot

以下是我完整的测试代码,麻烦帮忙排查下问题所在:

using System;
using System.IO;
using System.Runtime.InteropServices;

class Program
{
    // Structure definition
    [StructLayout(LayoutKind.Sequential)]
    public struct DISPLAYCONFIG_PATH_INFO
    {
        public uint pathId;
        public uint sourceMode;
        public uint targetMode;
        public uint statusFlags;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DISPLAYCONFIG_MODE_INFO
    {
        public uint width;
        public uint height;
        public uint refreshRate;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DISPLAYCONFIG_PATH_INFO_V2
    {
        public uint pathId;
        public DISPLAYCONFIG_MODE_INFO sourceMode;
        public DISPLAYCONFIG_MODE_INFO targetMode;
        public uint statusFlags;
    }

    // API
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int GetDisplayConfigBufferSizes(uint pathInfoCount, uint modeInfoCount, ref uint pathInfoSize, ref uint modeInfoSize);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int QueryDisplayConfig(uint flags, ref uint pathInfoSize, IntPtr pathInfo, ref uint modeInfoSize, IntPtr modeInfo, IntPtr currentSettings);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int SetDisplayConfig(uint flags, uint pathInfoCount, IntPtr pathInfo, uint modeInfoCount, IntPtr modeInfo, uint currentSettings);

    const uint SDC_TOPOLOGY_CLONE = 0x00000001;
    const uint SDC_TOPOLOGY_EXTEND = 0x00000002;
    const uint SDC_TOPOLOGY_INTERNAL = 0x00000004;

    // log
   private static void Log(string message)
    {
        string logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}";
        Console.WriteLine(logMessage);

        // Optionally log to a file
        try
        {
            string logFile = "screen_resolution_change.log";
            File.AppendAllText(logFile, logMessage + Environment.NewLine);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error writing to log file: {ex.Message}");
        }
    }

   public static void Main()
    {
        uint pathInfoSize = 0;
        uint modeInfoSize = 0;

        // Get buffer size
        Log("Getting buffer sizes for display configuration...");
        int result = GetDisplayConfigBufferSizes(0, 0, ref pathInfoSize, ref modeInfoSize);
        if (result != 0)
        {
            Log($"Error in GetDisplayConfigBufferSizes: {result}");
            return;
        }

        Log($"Buffer sizes - PathInfoSize: {pathInfoSize}, ModeInfoSize: {modeInfoSize}");

        // Allocate memory for path information and mode information
        IntPtr pathInfoBuffer = Marshal.AllocHGlobal((int)pathInfoSize);
        IntPtr modeInfoBuffer = Marshal.AllocHGlobal((int)modeInfoSize);

        try
        {
            // Query display configuration
            Log("Querying current display configuration...");
            result = QueryDisplayConfig(0, ref pathInfoSize, pathInfoBuffer, ref modeInfoSize, modeInfoBuffer, IntPtr.Zero);
            if (result != 0)
            {
                Log($"Error in QueryDisplayConfig: {result}");
                return;
            }

            Log("Current display configuration retrieved successfully.");

            // Obtain and modify resolution
            DISPLAYCONFIG_PATH_INFO_V2 pathInfo = Marshal.PtrToStructure<DISPLAYCONFIG_PATH_INFO_V2>(pathInfoBuffer);
            DISPLAYCONFIG_MODE_INFO newMode = pathInfo.sourceMode;
            newMode.width = 1920; // New resolution width
            newMode.height = 1080; // New resolution height

            // Output the modified resolution
            Log($"Changing resolution to {newMode.width}x{newMode.height}");

            // Modify display settings
            Marshal.StructureToPtr(newMode, modeInfoBuffer, false);

            // Apply new display configuration
            Log("Applying new display configuration...");
            result = SetDisplayConfig(0, 1, pathInfoBuffer, 1, modeInfoBuffer, 0);
            if (result != 0)
            {
                Log($"Error in SetDisplayConfig: {result}");
            }
            else
            {
                Log("Resolution changed successfully!");
            }
        }
        finally
        {
            // free memory
            Marshal.FreeHGlobal(pathInfoBuffer);
            Marshal.FreeHGlobal(modeInfoBuffer);
        }
    }
}

备注:内容来源于stack exchange,提问作者BestYuan

火山引擎 最新活动