使用QueryDisplayConfig/SetDisplayConfig API修改屏幕分辨率失败,返回错误代码87求助
QueryDisplayConfig/SetDisplayConfig API修改屏幕分辨率失败,返回错误代码87求助
我现在尝试用QueryDisplayConfig和SetDisplayConfig这两个API修改屏幕分辨率,但不管执行什么操作,调用后始终返回错误代码87(查资料得知是参数无效的意思)。我已经按照文档要求,先调用GetDisplayConfigBufferSizes获取缓冲区大小,但问题依然存在,实在搞不清楚哪里出了问题。
(附相关操作截图:)
以下是我完整的测试代码,麻烦帮忙排查下问题所在:
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




