问题描述
- C# 请教这个设置多显示器复制扩展的类怎么调用?麻烦各位了!
-
#region Copyright (C) 2005-2011 Team MediaPortal// Copyright (C) 2005-2011 Team MediaPortal// http://www.team-mediaportal.com// // MediaPortal is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation either version 2 of the License or// (at your option) any later version.// // MediaPortal is distributed in the hope that it will be useful// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with MediaPortal. If not see <http://www.gnu.org/licenses/>.#endregion#region usingusing System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;#endregionnamespace ImageViewer{ public class W7RefreshRateHelper { #region consts private const uint SIZE_OF_DISPLAYCONFIG_PATH_INFO = 72; private const uint SIZE_OF_DISPLAYCONFIG_MODE_INFO = 64; private const uint QDC_ALL_PATHS = 1; private const uint DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2; private const uint DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1; public const uint SDC_TOPOLOGY_INTERNAL = 0x00000001; public const uint SDC_TOPOLOGY_CLONE = 0x00000002; public const uint SDC_TOPOLOGY_EXTEND = 0x00000004; public const uint SDC_TOPOLOGY_EXTERNAL = 0x00000008; public const uint SDC_TOPOLOGY_SUPPLIED = 0x00000010; public const uint SDC_USE_DATABASE_CURRENT = (SDC_TOPOLOGY_INTERNAL | SDC_TOPOLOGY_CLONE | SDC_TOPOLOGY_EXTEND | SDC_TOPOLOGY_EXTERNAL); private const uint SDC_USE_SUPPLIED_DISPLAY_CONFIG = 0x00000020; private const uint SDC_VALIDATE = 0x00000040; private const uint SDC_APPLY = 0x00000080; private const uint SDC_ALLOW_CHANGES = 0x00000400; private const uint SDC_NO_OPTIMIZATION = 0x00000100; private const uint SDC_SAVE_TO_DATABASE = 0x00000200; private const uint SDC_PATH_PERSIST_IF_REQUIRED = 0x00000800; private const uint SDC_FORCE_MODE_ENUMERATION = 0x00001000; private const uint SDC_ALLOW_PATH_ORDER_CHANGES = 0x00002000; #endregion #region DLL imports [DllImport(""user32.dll"" CharSet = CharSet.Unicode)] private static extern long GetDisplayConfigBufferSizes([In] uint flags [Out] out uint numPathArrayElements [Out] out uint numModeArrayElements); [DllImport(""user32.dll"" CharSet = CharSet.Unicode)] private static extern long QueryDisplayConfig([In] uint flags ref uint numPathArrayElements IntPtr pathArray ref uint numModeArrayElements IntPtr modeArray IntPtr currentTopologyId); [DllImport(""user32.dll"" CharSet = CharSet.Unicode)] private static extern long SetDisplayConfig(uint numPathArrayElements IntPtr pathArray uint numModeArrayElements IntPtr modeArray uint flags); #endregion #region private members private static int GetModeInfoOffsetForDisplayId(uint displayIndex IntPtr pModeArray uint uNumModeArrayElements) { int offset; int modeInfoType; // there are always two mode infos per display (target and source) offset = (int)(displayIndex * SIZE_OF_DISPLAYCONFIG_MODE_INFO * 2); // out of bounds sanity check if (offset + SIZE_OF_DISPLAYCONFIG_MODE_INFO >= uNumModeArrayElements * SIZE_OF_DISPLAYCONFIG_MODE_INFO) { return -1; } // check which one of the two mode infos for the display is the target modeInfoType = Marshal.ReadInt32(pModeArray offset); if (modeInfoType == DISPLAYCONFIG_MODE_INFO_TYPE_TARGET) { return offset; } else { offset += (int)SIZE_OF_DISPLAYCONFIG_MODE_INFO; } modeInfoType = Marshal.ReadInt32(pModeArray offset); if (modeInfoType == DISPLAYCONFIG_MODE_INFO_TYPE_TARGET) { return offset; } // no target mode info found this should never happen else { return -1; } } #endregion #region public members public static double GetRefreshRate(uint displayIndex) { uint uNumPathArrayElements = 0; uint uNumModeArrayElements = 0; IntPtr pPathArray = IntPtr.Zero; IntPtr pModeArray = IntPtr.Zero; IntPtr pCurrentTopologyId = IntPtr.Zero; long result; UInt32 numerator; UInt32 denominator; double refreshRate; // get size of buffers for QueryDisplayConfig result = GetDisplayConfigBufferSizes(QDC_ALL_PATHS out uNumPathArrayElements out uNumModeArrayElements); if (result != 0) { // Log.Error(""W7RefreshRateHelper.GetRefreshRate: GetDisplayConfigBufferSizes(...) returned {0}"" result); return 0; } // allocate memory or QueryDisplayConfig buffers pPathArray = Marshal.AllocHGlobal((Int32)(uNumPathArrayElements * SIZE_OF_DISPLAYCONFIG_PATH_INFO)); pModeArray = Marshal.AllocHGlobal((Int32)(uNumModeArrayElements * SIZE_OF_DISPLAYCONFIG_MODE_INFO)); // get display configuration result = QueryDisplayConfig(QDC_ALL_PATHS ref uNumPathArrayElements pPathArray ref uNumModeArrayElements pModeArray pCurrentTopologyId); // if failed log error message and free memory if (result != 0) { // Log.Error(""W7RefreshRateHelper.GetRefreshRate: QueryDisplayConfig(...) returned {0}"" result); Marshal.FreeHGlobal(pPathArray); Marshal.FreeHGlobal(pModeArray); return 0; } // get offset for a display's target mode info int offset = GetModeInfoOffsetForDisplayId(displayIndex pModeArray uNumModeArrayElements); // if failed log error message and free memory if (offset == -1) { //Log.Error(""W7RefreshRateHelper.GetRefreshRate: Couldn't find a target mode info for display {0}"" displayIndex); Marshal.FreeHGlobal(pPathArray); Marshal.FreeHGlobal(pModeArray); return 0; } // get refresh rate numerator = (UInt32)Marshal.ReadInt32(pModeArray offset + 32); denominator = (UInt32)Marshal.ReadInt32(pModeArray offset + 36); refreshRate = (double)numerator / (double)denominator; //Log.Debug(""W7RefreshRateHelper.GetRefreshRate: QueryDisplayConfig returned {0}/{1}"" numerator denominator); // free memory and return refresh rate Marshal.FreeHGlobal(pPathArray); Marshal.FreeHGlobal(pModeArray); return refreshRate; } public static bool SetRefreshRate(uint displayIndex double refreshRate) { uint uNumPathArrayElements = 0; uint uNumModeArrayElements = 0; IntPtr pPathArray = IntPtr.Zero; IntPtr pModeArray = IntPtr.Zero; IntPtr pCurrentTopologyId = IntPtr.Zero; long result; UInt32 numerator; UInt32 denominator; UInt32 scanLineOrdering; UInt32 flags; // get size of buffers for QueryDisplayConfig result = GetDisplayConfigBufferSizes(QDC_ALL_PATHS out uNumPathArrayElements out uNumModeArrayElements); if (result != 0) { // Log.Error(""W7RefreshRateHelper.GetRefreshRate: GetDisplayConfigBufferSizes(...) returned {0}"" result); return false; } // allocate memory or QueryDisplayConfig buffers pPathArray = Marshal.AllocHGlobal((Int32)(uNumPathArrayElements * SIZE_OF_DISPLAYCONFIG_PATH_INFO)); pModeArray = Marshal.AllocHGlobal((Int32)(uNumModeArrayElements * SIZE_OF_DISPLAYCONFIG_MODE_INFO)); // get display configuration result = QueryDisplayConfig(QDC_ALL_PATHS ref uNumPathArrayElements pPathArray ref uNumModeArrayElements pModeArray pCurrentTopologyId); // if failed log error message and free memory if (result != 0) { // Log.Error(""W7RefreshRateHelper.GetRefreshRate: QueryDisplayConfig(...) returned {0}"" result); Marshal.FreeHGlobal(pPathArray); Marshal.FreeHGlobal(pModeArray); return false; } // get offset for a display's target mode info int offset = GetModeInfoOffsetForDisplayId(displayIndex pModeArray uNumModeArrayElements); // if failed log error message and free memory if (offset == -1) { //Log.Error(""W7RefreshRateHelper.GetRefreshRate: Couldn't find a target mode info for display {0}"" displayIndex); Marshal.FreeHGlobal(pPathArray); Marshal.FreeHGlobal(pModeArray); return false; } // TODO: refactor to private method // set proper numerator and denominator for refresh rate UInt32 newRefreshRate = (uint)(refreshRate * 1000); switch (newRefreshRate) { case 23976: numerator = 24000; denominator = 1001; scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE; break; case 24000: numerator = 24000; denominator = 1000; scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE; break; case 25000: numerator = 25000; denominator = 1000; scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE; break; case 30000: numerator = 30000; denominator = 1000; scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE; break; case 50000: numerator = 50000; denominator = 1000; scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE; break; case 59940: numerator = 60000; denominator = 1001; scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE; break; case 60000: numerator = 60000; denominator = 1000; scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE; break; default: numerator = (uint)(newRefreshRate / 1000); denominator = 1; scanLineOrdering = DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE; break; } // set refresh rate parameters in display config Marshal.WriteInt32(pModeArray offset + 32 (int)numerator); Marshal.WriteInt32(pModeArray offset + 36 (int)denominator); Marshal.WriteInt32(pModeArray offset + 56 (int)scanLineOrdering); // validate new refresh rate flags = SDC_VALIDATE | SDC_USE_SUPPLIED_DISPLAY_CONFIG; result = SetDisplayConfig(uNumPathArrayElements pPathArray uNumModeArrayElements pModeArray flags); // adding SDC_ALLOW_CHANGES to flags if validation failed if (result != 0) { //Log.Debug(""W7RefreshRateHelper.SetDisplayConfig(...): SDC_VALIDATE of {0}/{1} failed"" numerator denominator); flags = SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_ALLOW_CHANGES; } else { //Log.Debug(""W7RefreshRateHelper.SetDisplayConfig(...): SDC_VALIDATE of {0}/{1} succesful"" numerator denominator); flags = SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG; } // configuring display result = SetDisplayConfig(uNumPathArrayElements pPathArray uNumModeArrayElements pModeArray flags); // if failed log error message and free memory if (result != 0) { //Log.Error(""W7RefreshRateHelper.SetDisplayConfig(...): SDC_APPLY returned {0}"" result); Marshal.FreeHGlobal(pPathArray); Marshal.FreeHGlobal(pModeArray); return false; } // refresh rate change successful Marshal.FreeHGlobal(pPathArray); Marshal.FreeHGlobal(pModeArray); return true; } public static bool SetScreen(uint displayModel) { return SetDisplayConfig(0 IntPtr.Zero 0 IntPtr.Zero SDC_APPLY | displayModel) == 0; } #endregion }}
解决方案
因为这个类里面的方法都是静态的,所以你可以直接使用类似ImageViewer.W7RefreshRateHelper.SetScreen(1)的方式调用,不需要实例化。
解决方案二:
怎么调用看什么需求
通用的调用无非是实例化类 然后用类名.方法名
由于方法是静态方法 可以不用实例化 直接调用
时间: 2024-10-06 11:14:12