QueryDisplayConfig()无法正确初始化pathArray和modeArray

时间:2019-07-17 04:23:30

标签: c# winapi pinvoke

我正在尝试对屏幕模式进行简单的一键式更改(扩展<->断开连接)
但是我的屏幕没有通过QueryDisplayConfig方法分配ID。

(除了您在下面的代码中找到的内容之外,我还使用https://github.com/AArnott/pinvoke中的User32 PInvoke lib)

我尝试过:

  • 使用断点逐步浏览代码,确保每个值都是默认值。
  • 提升VS以管理员权限运行。
  • 要特别确保标记和错误运行正常。
[DllImport("User32.dll")]
public static extern int GetDisplayConfigBufferSizes(uint flags, ref uint numPathArrayElements, ref uint numModeInfoArrayElements);
[DllImport("User32.dll")]
public static extern int QueryDisplayConfig(
    uint flags,
    ref uint numPathArrayElements, DISPLAYCONFIG_PATH_INFO[] pathArray,
    ref uint numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO[] modeInfoArray,
    DISPLAYCONFIG_TOPOLOGY_ID[] currentTopologyId
);

const int QDC_ALL_PATHS = 1;
const int QDC_ONLY_ACTIVE_PATHS = 2;
const int QDC_DATABASE_CURRENT = 4;

public static void CheckDisplays() {
    uint numPathArrayElements = 0;
    uint numModeInfoArrayElements = 0;
    uint filter = QDC_ONLY_ACTIVE_PATHS;

    int bufferError = GetDisplayConfigBufferSizes(filter, ref numPathArrayElements, ref numModeInfoArrayElements);

    DISPLAYCONFIG_PATH_INFO[] pathArray = new DISPLAYCONFIG_PATH_INFO[numPathArrayElements];
    DISPLAYCONFIG_MODE_INFO[] modeArray = new DISPLAYCONFIG_MODE_INFO[numModeInfoArrayElements];

    int queryError = QueryDisplayConfig(filter, ref numPathArrayElements, pathArray, ref numModeInfoArrayElements, modeArray, null);

    Console.WriteLine();
    Console.WriteLine("Elements: " + numPathArrayElements); // Prints the correct amount of connected screens.
    Console.WriteLine("BUFFER ERROR: " + bufferError);      // Prints 0 -- as in Success.
    Console.WriteLine("PATH ERROR: " + queryError);         // Prints 0 -- as in Success.

    for (int i = 0; i < pathArray.Length; i++) {
        if (pathArray[i].sourceInfo.id != 0) { Console.WriteLine($"Path{i} has been initialized correctly!!"); }
        // Every object in the array has default values and IDs of 0.
        // Nothing prints here.
    }
}

应该为每个屏幕分配一个ID和一个正确的模式。

相反,所有内容都具有默认值,而且我似乎被卡住了。

1 个答案:

答案 0 :(得分:2)

您对 QueryDisplayConfig 的声明是错误的:数组必须为 [Out]

这对我有用:

(我只有1个监视器,但是数组中接收到的值与C ++中相同(我从SDK标头转换结构)

当前拓扑ID IntPtr.Zero QDC_ONLY_ACTIVE_PATHS

    [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern int QueryDisplayConfig(uint flags, ref uint numPathArrayElements, [Out] DISPLAYCONFIG_PATH_INFO[] pathArray,
        ref uint modeInfoArrayElements, [Out] DISPLAYCONFIG_MODE_INFO[] modeInfoArray, IntPtr currentTopologyId);