目前只有C++版的,本人用了两天时间,在经理的提点下完成了C#版的修改。
其中遇到了很多问题一一的解决了,还好时间花费不是太多。比较大的问题有:
1.C++类型与C#类型的转换
2.C++中Union关键字在C#中的表现形式。
3.对Api提供的大量枚举进行分析(这个尤其累)返回的错误码请参照微软 WinError。这个只是个预览版可以初步修改显示器位置罢了。
虽然在Api中存在分辨率,可是不能修改,一修改就报错,目前无解决方案,只能用旧的 ChangeDisplaySettings了。开始上代码
其中遇到了很多问题一一的解决了,还好时间花费不是太多。比较大的问题有:
1.C++类型与C#类型的转换
2.C++中Union关键字在C#中的表现形式。
3.对Api提供的大量枚举进行分析(这个尤其累)返回的错误码请参照微软 WinError。这个只是个预览版可以初步修改显示器位置罢了。
虽然在Api中存在分辨率,可是不能修改,一修改就报错,目前无解决方案,只能用旧的 ChangeDisplaySettings了。开始上代码
解决方案 »
- 【操作WORD问题】无法将类型为“Word.ApplicationClass”的 COM 对象强制转换为接口类型“Word._Application”
- 怎么透过页面操作
- dataGrid 每一行根据条件怎么显示?
- asp.net/aspx/c#/server刷新网页重复添加问题
- asp.net 中如何用c#实现鼠标指向图片不同区域显示不同的提示信息?
- 请教各位大哥C# Winform中的comboboxx如何能够在输入后能够自动下拉定位呢?
- dataset中如何只取指定的数据
- c#对excel的操作!!!
- 关于MemoryMappedFile内存映射
- 请高手帮我看看
- 关于串口通信的问题。
- 将一个Form分成好几个部分,在其中的一个部分画图?为什么不显示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;namespace TestDiaplay
{
public class CommonHelper
{
public static byte[] StrutsToBytesArray(object structObj)
{
//得到结构体的大小
int size = Marshal.SizeOf(structObj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷到分配好的内存空间
Marshal.StructureToPtr(structObj, structPtr, false);
//从内存空间拷到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
}
public static object BytesToStruts(byte[] bytes, Type type)
{
//得到结构体的大小
int size = Marshal.SizeOf(type);
//byte数组长度小于结构体的大小
if (size > bytes.Length)
{
//返回空
return null;
}
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将byte数组拷到分配好的内存空间
Marshal.Copy(bytes, 0, structPtr, size);
//将内存空间转换为目标结构体
object obj = Marshal.PtrToStructure(structPtr, type);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回结构体
return obj;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;namespace TestDiaplay
{
class Program
{
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true)]
public static extern IntPtr LoadLibrary(string lpFileName); [DllImport("kernel32.dll", EntryPoint = "GetProcAddress", SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProceName); struct LUID
{
UInt32 LowPart;
UInt32 HighPart;
} struct POINTL /* ptl */
{
public Int32 x;
public Int32 y;
} struct DISPLAYCONFIG_2DREGION
{
public UInt32 cx;
public UInt32 cy;
} enum DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY
{
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = -1,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = 0,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = 1,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = 2,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO = 3,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI = 4,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI = 5,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS = 6,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN = 8,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI = 9,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL = 10,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED = 11,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL = 12,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED = 13,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE = 14,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = 0x8000000,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = 0xFFFFFFF
} enum DISPLAYCONFIG_ROTATION
{
DISPLAYCONFIG_ROTATION_IDENTITY = 1,
DISPLAYCONFIG_ROTATION_ROTATE90 = 2,
DISPLAYCONFIG_ROTATION_ROTATE180 = 3,
DISPLAYCONFIG_ROTATION_ROTATE270 = 4,
DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFF
} enum DISPLAYCONFIG_SCALING
{
DISPLAYCONFIG_SCALING_IDENTITY = 1,
DISPLAYCONFIG_SCALING_CENTERED = 2,
DISPLAYCONFIG_SCALING_STRETCHED = 3,
DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX = 4,
DISPLAYCONFIG_SCALING_CUSTOM = 5,
DISPLAYCONFIG_SCALING_PREFERRED = 128,
DISPLAYCONFIG_SCALING_FORCE_UINT32 = 0xFFFFFFF
}
struct DISPLAYCONFIG_RATIONAL
{
UInt32 Numerator;
UInt32 Denominator;
} enum DISPLAYCONFIG_SCANLINE_ORDERING
{
DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED = 0,
DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1,
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED = 2,
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED,
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST = 3,
DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32 = 0xFFFFFFF
} enum DISPLAYCONFIG_PIXELFORMAT
{
DISPLAYCONFIG_PIXELFORMAT_8BPP = 1,
DISPLAYCONFIG_PIXELFORMAT_16BPP = 2,
DISPLAYCONFIG_PIXELFORMAT_24BPP = 3,
DISPLAYCONFIG_PIXELFORMAT_32BPP = 4,
DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5,
DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32 = 0xfffffff
}
enum DISPLAYCONFIG_MODE_INFO_TYPE
{
DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1,
DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2,
DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFF
} enum DISPLAYCONFIG_TOPOLOGY_ID
{
DISPLAYCONFIG_TOPOLOGY_INTERNAL = 0x00000001,
DISPLAYCONFIG_TOPOLOGY_CLONE = 0x00000002,
DISPLAYCONFIG_TOPOLOGY_EXTEND = 0x00000004,
DISPLAYCONFIG_TOPOLOGY_EXTERNAL = 0x00000008,
DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32 = 0xFFFFFFF
} [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct DISPLAYCONFIG_PATH_TARGET_INFO
{
LUID adapterId;
UInt32 id;
UInt32 modeInfoIdx;
DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
DISPLAYCONFIG_ROTATION rotation;
DISPLAYCONFIG_SCALING scaling;
DISPLAYCONFIG_RATIONAL refreshRate;
DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
Boolean targetAvailable;
UInt32 statusFlags;
} [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
struct DISPLAYCONFIG_PATH_SOURCE_INFO
{
[FieldOffset(0)]
LUID adapterId;
[FieldOffset(8)]
UInt32 id;
[FieldOffset(12)]
UInt32 modeInfoIdx;
[FieldOffset(16)]
UInt32 statusFlags;
} [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
struct DISPLAYCONFIG_PATH_INFO
{
[FieldOffset(0)]
DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo;
[FieldOffset(20)]
DISPLAYCONFIG_PATH_TARGET_INFO targetInfo;
[FieldOffset(68)]
UInt32 flags;
} struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO
{
public UInt64 pixelRate;
public DISPLAYCONFIG_RATIONAL hSyncFreq;
public DISPLAYCONFIG_RATIONAL vSyncFreq;
public DISPLAYCONFIG_2DREGION activeSize;
public DISPLAYCONFIG_2DREGION totalSize;
public UInt32 videoStandard;
public DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
} [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct DISPLAYCONFIG_TARGET_MODE
{
public DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo;
} [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct DISPLAYCONFIG_SOURCE_MODE
{
public UInt32 width;
public UInt32 height;
public DISPLAYCONFIG_PIXELFORMAT pixelFormat;
public POINTL position;
} [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
struct DISPLAYCONFIG_MODE_INFO
{
[FieldOffset(0)]
public DISPLAYCONFIG_MODE_INFO_TYPE infoType;
[FieldOffset(8)]
public UInt32 id;
[FieldOffset(12)]
public LUID adapterId; [FieldOffset(16)]
public DISPLAYCONFIG_TARGET_MODE targetMode;
[FieldOffset(16)]
public DISPLAYCONFIG_SOURCE_MODE sourceMode; }
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
class DisplayPathInfos
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public DISPLAYCONFIG_PATH_INFO[] DISPLAYCONFIG_PATH_INFO_ARRAY;
} [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
class DisplayConfigModeInfos
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public DISPLAYCONFIG_MODE_INFO[] DISPLAYCONFIG_MODE_INFO_ARRAY;
} static UInt32 QDC_ONLY_ACTIVE_PATHS = 0x00000002;
static UInt32 SDC_TOPOLOGY_INTERNAL = 0x00000001;
static UInt32 SDC_TOPOLOGY_CLONE = 0x00000002;
static UInt32 SDC_TOPOLOGY_EXTEND = 0x00000004;
static UInt32 SDC_TOPOLOGY_EXTERNAL = 0x00000008;
static UInt32 SDC_TOPOLOGY_SUPPLIED = 0x00000010;
static UInt32 SDC_USE_DATABASE_CURRENT = (SDC_TOPOLOGY_INTERNAL | SDC_TOPOLOGY_CLONE | SDC_TOPOLOGY_EXTEND | SDC_TOPOLOGY_EXTERNAL); static UInt32 SDC_USE_SUPPLIED_DISPLAY_CONFIG = 0x00000020;
static UInt32 SDC_VALIDATE = 0x00000040;
static UInt32 SDC_APPLY = 0x00000080;
static UInt32 SDC_NO_OPTIMIZATION = 0x00000100;
static UInt32 SDC_SAVE_TO_DATABASE = 0x00000200;
static UInt32 SDC_ALLOW_CHANGES = 0x00000400;
static UInt32 SDC_PATH_PERSIST_IF_REQUIRED = 0x00000800;
static UInt32 SDC_FORCE_MODE_ENUMERATION = 0x00001000;
static UInt32 SDC_ALLOW_PATH_ORDER_CHANGES = 0x00002000; unsafe delegate UInt32 SETDISPLAYCONFIGFUNC(UInt32 numPathArrayElements,
byte* pathArray,
UInt32 numModeInfoArrayElements,
byte* modeInfoArray,
UInt32 Flags
); delegate UInt32 GETDISPLAYBUFFERSIZESFUNC(
UInt32 Flags,
ref UInt32 pNumPathArrayElements,
ref UInt32 pNumModeInfoArrayElements
); unsafe delegate UInt32 QUERYDISPLAYCONFIGFUNC(
UInt32 Flags,
ref UInt32 pNumPathArrayElements,
byte* pPathInfoArray,
ref UInt32 pNumModeInfoArrayElements,
byte* pModeInfoArray,
IntPtr handler
); static void Main(string[] args)
{
IntPtr hMod = LoadLibrary("user32.dll");
SETDISPLAYCONFIGFUNC SetDisplayConfig = (SETDISPLAYCONFIGFUNC)GetProcAddress<SETDISPLAYCONFIGFUNC>(hMod, "SetDisplayConfig");
GETDISPLAYBUFFERSIZESFUNC GetDisplayConfigBufferSizes = (GETDISPLAYBUFFERSIZESFUNC)GetProcAddress<GETDISPLAYBUFFERSIZESFUNC>(hMod, "GetDisplayConfigBufferSizes");
QUERYDISPLAYCONFIGFUNC QueryDisplayConfig = (QUERYDISPLAYCONFIGFUNC)GetProcAddress<QUERYDISPLAYCONFIGFUNC>(hMod, "QueryDisplayConfig"); if (SetDisplayConfig != null && GetDisplayConfigBufferSizes != null && QueryDisplayConfig != null)
{
UInt32 NumPathArrayElements = 0;
UInt32 NumModeInfoArrayElements = 0;
if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, ref NumPathArrayElements, ref NumModeInfoArrayElements) != 0)
{
throw new Exception("");
} DISPLAYCONFIG_PATH_INFO[] pPathInfoArray = new DISPLAYCONFIG_PATH_INFO[100];
DISPLAYCONFIG_MODE_INFO[] pModeInfoArray = new DISPLAYCONFIG_MODE_INFO[100];
DisplayPathInfos displayPathInfos = new DisplayPathInfos();
displayPathInfos.DISPLAYCONFIG_PATH_INFO_ARRAY = pPathInfoArray; DisplayConfigModeInfos displayConfigModeInfos = new DisplayConfigModeInfos();
displayConfigModeInfos.DISPLAYCONFIG_MODE_INFO_ARRAY = pModeInfoArray; if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, ref NumPathArrayElements, ref NumModeInfoArrayElements) != 0)
{
throw new Exception("");
}
DISPLAYCONFIG_TOPOLOGY_ID topLOGYID = DISPLAYCONFIG_TOPOLOGY_ID.DISPLAYCONFIG_TOPOLOGY_CLONE; byte[] pathArrayBytes = CommonHelper.StrutsToBytesArray(displayPathInfos);
byte[] modeInfoArrayBytes = CommonHelper.StrutsToBytesArray(displayConfigModeInfos); unsafe
{
fixed (byte* bp = &pathArrayBytes[0])
{
fixed (byte* bp2 = &modeInfoArrayBytes[0])
{ if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, ref NumPathArrayElements, bp, ref NumModeInfoArrayElements, bp2, IntPtr.Zero) != 0)
{
throw new Exception("");
}
}
}
} displayPathInfos = (DisplayPathInfos)CommonHelper.BytesToStruts(pathArrayBytes, typeof(DisplayPathInfos));
displayConfigModeInfos = (DisplayConfigModeInfos)CommonHelper.BytesToStruts(modeInfoArrayBytes, typeof(DisplayConfigModeInfos)); displayConfigModeInfos.DISPLAYCONFIG_MODE_INFO_ARRAY[3].sourceMode.position.x = 1920;
displayConfigModeInfos.DISPLAYCONFIG_MODE_INFO_ARRAY[3].sourceMode.position.y = 0; pathArrayBytes = CommonHelper.StrutsToBytesArray(displayPathInfos);
modeInfoArrayBytes = CommonHelper.StrutsToBytesArray(displayConfigModeInfos); unsafe
{
fixed (byte* bp = &pathArrayBytes[0])
{
fixed (byte* bp2 = &modeInfoArrayBytes[0])
{
if (SetDisplayConfig(NumPathArrayElements, bp, NumModeInfoArrayElements, bp2, SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_SAVE_TO_DATABASE) != 0)
{
throw new Exception("");
}
}
}
} }
} private static Delegate GetProcAddress<T>(IntPtr lib, string procName) /* where T : Delegate */
{
var procAddress = GetProcAddress(lib, procName); if (procAddress == IntPtr.Zero)
return null; return System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(procAddress, typeof(T));
} }
}
以下这两句代码是修改位置的,当然这个是根据每台机器显卡接口会变的。
所以具体怎么改需要你自己调整。
注意 x 不能有间距也不能重叠。
displayConfigModeInfos.DISPLAYCONFIG_MODE_INFO_ARRAY[3].sourceMode.position.x = 1920;
displayConfigModeInfos.DISPLAYCONFIG_MODE_INFO_ARRAY[3].sourceMode.position.y = 0;
因为在修改分辨率的时候偶尔会把显示器位置切换错误,所以就要重新纠正显示器位置。这个东西这么冷门么?都没人用。。