2013-04-18 3 views
0

새로운 win7 CCD API를 둘러싼 괜찮은 (아무 것도 아님) 핀 포장 래퍼를 찾지 못했습니다. api는 여기에서 찾을 수 있습니다. http://msdn.microsoft.com/en-us/library/windows/hardware/hh406259(v=vs.85).aspxWindows7 디스플레이 API와 통신하기

구조체/메서드 호출을 변환하는 데 몇 시간을 소비하여 C#에서 사용할 수 있습니다.

여기에 최초의 "초안"입니다 :

using System; 
using System.Runtime.InteropServices; 

namespace CONVERTING_CCD 
{ 
    /// <summary> 
    /// This class takes care of wrapping "Connecting and Configuring Displays(CCD) Win32 API" 
    /// Author Erti-Chris Eelmaa || easter199 at hotmail dot com 
    /// </summary> 
    public class CCDWrapper 
    { 
     [StructLayout(LayoutKind.Sequential)] 
     public struct LUID 
     { 
      public uint LowPart; 
      public uint HighPart; 
     } 

     [Flags] 
     public enum DisplayConfigVideoOutputTechnology : uint 
     { 
      Other = 4294967295, // -1 
      Hd15 = 0, 
      Svideo = 1, 
      CompositeVideo = 2, 
      ComponentVideo = 3, 
      Dvi = 4, 
      Hdmi = 5, 
      Lvds = 6, 
      DJpn = 8, 
      Sdi = 9, 
      DisplayportExternal = 10, 
      DisplayportEmbedded = 11, 
      UdiExternal = 12, 
      UdiEmbedded = 13, 
      Sdtvdongle = 14, 
      Internal = 0x80000000, 
      ForceUint32 = 0xFFFFFFFF 
     } 

     #region SdcFlags enum 

     [Flags] 
     public enum SdcFlags : uint 
     { 
      Zero = 0, 

      TopologyInternal = 0x00000001, 
      TopologyClone = 0x00000002, 
      TopologyExtend = 0x00000004, 
      TopologyExternal = 0x00000008, 
      TopologySupplied = 0x00000010, 

      UseSuppliedDisplayConfig = 0x00000020, 
      Validate = 0x00000040, 
      Apply = 0x00000080, 
      NoOptimization = 0x00000100, 
      SaveToDatabase = 0x00000200, 
      AllowChanges = 0x00000400, 
      PathPersistIfRequired = 0x00000800, 
      ForceModeEnumeration = 0x00001000, 
      AllowPathOrderChanges = 0x00002000, 

      UseDatabaseCurrent = TopologyInternal | TopologyClone | TopologyExtend | TopologyExternal 
     } 

     [Flags] 
     public enum DisplayConfigFlags : uint 
     { 
      Zero = 0x0, 
      PathActive = 0x00000001 
     } 

     [Flags] 
     public enum DisplayConfigSourceStatus 
     { 
      Zero = 0x0, 
      InUse = 0x00000001 
     } 

     [Flags] 
     public enum DisplayConfigTargetStatus : uint 
     { 
      Zero = 0x0, 

      InUse       = 0x00000001, 
      FORCIBLE      = 0x00000002, 
      ForcedAvailabilityBoot  = 0x00000004, 
      ForcedAvailabilityPath  = 0x00000008, 
      ForcedAvailabilitySystem  = 0x00000010, 
     } 

     [Flags] 
     public enum DisplayConfigRotation : uint 
     { 
      Zero = 0x0, 

      Identity = 1, 
      Rotate90 = 2, 
      Rotate180 = 3, 
      Rotate270 = 4, 
      ForceUint32 = 0xFFFFFFFF 
     } 

     [Flags] 
     public enum DisplayConfigPixelFormat : uint 
     { 
      Zero = 0x0, 

      Pixelformat8Bpp = 1, 
      Pixelformat16Bpp = 2, 
      Pixelformat24Bpp = 3, 
      Pixelformat32Bpp = 4, 
      PixelformatNongdi = 5, 
      PixelformatForceUint32 = 0xffffffff 
     } 

     [Flags] 
     public enum DisplayConfigScaling : uint 
     { 
      Zero = 0x0, 

      Identity = 1, 
      Centered = 2, 
      Stretched = 3, 
      Aspectratiocenteredmax = 4, 
      Custom = 5, 
      Preferred = 128, 
      ForceUint32 = 0xFFFFFFFF 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct DisplayConfigRational 
     { 
      public uint numerator; 
      public uint denominator; 
     } 

     [Flags] 
     public enum DisplayConfigScanLineOrdering : uint 
     { 
      Unspecified = 0, 
      Progressive = 1, 
      Interlaced = 2, 
      InterlacedUpperfieldfirst = Interlaced, 
      InterlacedLowerfieldfirst = 3, 
      ForceUint32 = 0xFFFFFFFF 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct DisplayConfigPathInfo 
     { 
      public DisplayConfigPathSourceInfo sourceInfo; 
      public DisplayConfigPathTargetInfo targetInfo; 
      public uint flags; 
     } 

     [Flags] 
     public enum DisplayConfigModeInfoType : uint 
     { 
      Zero = 0, 

      Source = 1, 
      Target = 2, 
      ForceUint32 = 0xFFFFFFFF 
     } 

     [StructLayout(LayoutKind.Explicit)] 
     public struct DisplayConfigModeInfo 
     { 
      [FieldOffset((0))] 
      public DisplayConfigModeInfoType infoType; 

      [FieldOffset(4)] 
      public uint id; 

      [FieldOffset(8)] 
      public LUID adapterId; 

      [FieldOffset(16)] 
      public DisplayConfigTargetMode targetMode; 

      [FieldOffset(16)] 
      public DisplayConfigSourceMode sourceMode; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct DisplayConfig2DRegion 
     { 
      public uint cx; 
      public uint cy; 
     } 

     [Flags] 
     public enum D3DmdtVideoSignalStandard : uint 
     { 
      Uninitialized = 0, 
      VesaDmt = 1, 
      VesaGtf = 2, 
      VesaCvt = 3, 
      Ibm = 4, 
      Apple = 5, 
      NtscM = 6, 
      NtscJ = 7, 
      Ntsc443 = 8, 
      PalB = 9, 
      PalB1 = 10, 
      PalG = 11, 
      PalH = 12, 
      PalI = 13, 
      PalD = 14, 
      PalN = 15, 
      PalNc = 16, 
      SecamB = 17, 
      SecamD = 18, 
      SecamG = 19, 
      SecamH = 20, 
      SecamK = 21, 
      SecamK1 = 22, 
      SecamL = 23, 
      SecamL1 = 24, 
      Eia861 = 25, 
      Eia861A = 26, 
      Eia861B = 27, 
      PalK = 28, 
      PalK1 = 29, 
      PalL = 30, 
      PalM = 31, 
      Other = 255 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct DisplayConfigVideoSignalInfo 
     { 
      public long pixelRate; 
      public DisplayConfigRational hSyncFreq; 
      public DisplayConfigRational vSyncFreq; 
      public DisplayConfig2DRegion activeSize; 
      public DisplayConfig2DRegion totalSize; 

      public D3DmdtVideoSignalStandard videoStandard; 
      public DisplayConfigScanLineOrdering ScanLineOrdering; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct DisplayConfigTargetMode 
     { 
      public DisplayConfigVideoSignalInfo targetVideoSignalInfo; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct PointL 
     { 
      public int x; 
      public int y; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct DisplayConfigSourceMode 
     { 
      public uint width; 
      public uint height; 
      public DisplayConfigPixelFormat pixelFormat; 
      public PointL position; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct DisplayConfigPathSourceInfo 
     { 
      public LUID adapterId; 
      public uint id; 
      public uint modeInfoIdx; 

      public DisplayConfigSourceStatus statusFlags; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct DisplayConfigPathTargetInfo 
     { 
      public LUID adapterId; 
      public uint id; 
      public uint modeInfoIdx; 
      public DisplayConfigVideoOutputTechnology outputTechnology; 
      public DisplayConfigRotation rotation; 
      public DisplayConfigScaling scaling; 
      public DisplayConfigRational refreshRate; 
      public DisplayConfigScanLineOrdering scanLineOrdering; 

      public bool targetAvailable; 
      public DisplayConfigTargetStatus statusFlags; 
     } 

     [Flags] 
     public enum QueryDisplayFlags : uint 
     { 
      Zero = 0x0, 

      AllPaths = 0x00000001, 
      OnlyActivePaths = 0x00000002, 
      DatabaseCurrent = 0x00000004 
     } 

     [Flags] 
     public enum DisplayConfigTopologyId : uint 
     { 
      Zero = 0x0, 

      Internal = 0x00000001, 
      Clone = 0x00000002, 
      Extend = 0x00000004, 
      External = 0x00000008, 
      ForceUint32 = 0xFFFFFFFF 
     } 


     #endregion 

     [DllImport("User32.dll")] 
     public static extern int SetDisplayConfig(uint numPathArrayElements, out DisplayConfigPathInfo pathArray, 
                uint numModeInfoArrayElements, out DisplayConfigModeInfo modeInfoArray, 
                SdcFlags flags); 

     [DllImport("User32.dll")] 
     public static extern int QueryDisplayConfig(QueryDisplayFlags flags, ref int numPathArrayElements, 
               ref DisplayConfigPathInfo[] pathInfoArray, 
               ref int modeInfoArrayElements, 
               ref DisplayConfigModeInfo[] modeInfoArray, 
               IntPtr z); 

     [DllImport("User32.dll")] 
     public static extern int GetDisplayConfigBufferSizes(QueryDisplayFlags flags, out int numPathArrayElements, out int numModeInfoArrayElements); 
    } 
} 

내가 거의 다하고, 그리고이 완료 때, 나는 pinvoke.net을 보내드립니다. 지금 당장 문제가 있습니다. 즉, QueryDisplayConfig()를 호출하면 null 참조 예외가 발생하여 아무 것도 말해주지 않습니다. 나는 앞뒤로 모든 것을 다시 확인하는 데 몇 시간을 보냈다. 구조물의 크기는 적절해야한다는

static void Main(string[] args) 
{ 
    int numPathArrayElements; 
    int numModeInfoArrayElements; 

    // query active paths from the current computer. 
    if (CCDWrapper.GetDisplayConfigBufferSizes(CCDWrapper.QueryDisplayFlags.OnlyActivePaths, out numPathArrayElements, 
                out numModeInfoArrayElements) == 0) 
    { 
     // 0 is success. 
     var pathInfoArray = new CCDWrapper.DisplayConfigPathInfo[numPathArrayElements]; 
     var modeInfoArray = new CCDWrapper.DisplayConfigModeInfo[numModeInfoArrayElements]; 
     CCDWrapper.DisplayConfigTopologyId currentTopologyId; // don't use it right now. 

     var first = Marshal.SizeOf(new CCDWrapper.DisplayConfigPathInfo()); 
     var second = Marshal.SizeOf(new CCDWrapper.DisplayConfigModeInfo()); 

     var status = CCDWrapper.QueryDisplayConfig(CCDWrapper.QueryDisplayFlags.OnlyActivePaths, 
           ref numPathArrayElements, ref pathInfoArray, ref numModeInfoArrayElements, 
           ref modeInfoArray, IntPtr.Zero); 

    } 
} 

주 :

var first = Marshal.SizeOf(new CCDWrapper.DisplayConfigPathInfo()); 
var second = Marshal.SizeOf(new CCDWrapper.DisplayConfigModeInfo()); 

제 => 72 초 => 64

여기서

실제 코드 사용이고 C++에서 확인 :

int first = sizeof(DISPLAYCONFIG_PATH_INFO); 
int second = sizeof(DISPLAYCONFIG_MODE_INFO); 

그것은 나에게 같은 결과를 준다.

+1

일부 유사한 코드가 여기에 있습니다 : 그것은 유용 할 수 있습니다 http://sources.team-mediaportal.com/svn/public/trunk/mediaportal/Core/Player/Windows7Helper.cs 확인 그들이 무엇을 할. –

+0

연결된 화면의 전원이 켜져 있는지 여부를 알 수있는 깃발이 있습니까? 그리고 네가 그 곳의 완전한 근원을 가지고 있다면? (나는 그것이 오래되었다는 것을 알고 있습니다 ^^) –

+0

제 질문에 대한 대답은 yes입니다 :'targetInfo.targetAvailable'. 당신이 저를 구해 주셨습니다, 당신의 코드는 상업적 용도로 사용 가능합니까? –

답변

1

SetDisplayConfig 및 QueryDisplayConfig 선언에서 배열을 처리하는 것이 잘못되었습니다. 이러한 변경을 시도해보십시오

[DllImport("User32.dll")] 
public static extern int SetDisplayConfig(
    uint numPathArrayElements, 
    [In] DisplayConfigPathInfo[] pathArray, 
    uint numModeInfoArrayElements, 
    [In] DisplayConfigModeInfo[] modeInfoArray, 
    SdcFlags flags 
); 

[DllImport("User32.dll")] 
public static extern int QueryDisplayConfig(
    QueryDisplayFlags flags, 
    ref int numPathArrayElements, 
    [Out] DisplayConfigPathInfo[] pathInfoArray, 
    ref int modeInfoArrayElements, 
    [Out] DisplayConfigModeInfo[] modeInfoArray, 
    IntPtr z 
); 
+0

아, 고맙습니다. –