2008-10-12 14 views
6

सेट करने के लिए सी # से विंडोज एपीआई का उपयोग करें, मैं प्राथमिक मॉनिटर सेट करने के लिए विंडोज एपीआई का उपयोग करने की कोशिश कर रहा हूं। ऐसा लगता है कि यह काम नहीं करता है - मेरी स्क्रीन सिर्फ फिसलती है और कुछ भी नहीं होता है।प्राथमिक मॉनीटर

SetPrimary(Screen.AllScreens[1]) 

कोई भी विचार:

public const int DM_ORIENTATION = 0x00000001; 
public const int DM_PAPERSIZE = 0x00000002; 
public const int DM_PAPERLENGTH = 0x00000004; 
public const int DM_PAPERWIDTH = 0x00000008; 
public const int DM_SCALE = 0x00000010; 
public const int DM_POSITION = 0x00000020; 
public const int DM_NUP = 0x00000040; 
public const int DM_DISPLAYORIENTATION = 0x00000080; 
public const int DM_COPIES = 0x00000100; 
public const int DM_DEFAULTSOURCE = 0x00000200; 
public const int DM_PRINTQUALITY = 0x00000400; 
public const int DM_COLOR = 0x00000800; 
public const int DM_DUPLEX = 0x00001000; 
public const int DM_YRESOLUTION = 0x00002000; 
public const int DM_TTOPTION = 0x00004000; 
public const int DM_COLLATE = 0x00008000; 
public const int DM_FORMNAME = 0x00010000; 
public const int DM_LOGPIXELS = 0x00020000; 
public const int DM_BITSPERPEL = 0x00040000; 
public const int DM_PELSWIDTH = 0x00080000; 
public const int DM_PELSHEIGHT = 0x00100000; 
public const int DM_DISPLAYFLAGS = 0x00200000; 
public const int DM_DISPLAYFREQUENCY = 0x00400000; 
public const int DM_ICMMETHOD = 0x00800000; 
public const int DM_ICMINTENT = 0x01000000; 
public const int DM_MEDIATYPE = 0x02000000; 
public const int DM_DITHERTYPE = 0x04000000; 
public const int DM_PANNINGWIDTH = 0x08000000; 
public const int DM_PANNINGHEIGHT = 0x10000000; 
public const int DM_DISPLAYFIXEDOUTPUT = 0x20000000; 

public const int ENUM_CURRENT_SETTINGS = -1; 
public const int CDS_UPDATEREGISTRY = 0x01; 
public const int CDS_TEST = 0x02; 
public const int CDS_SET_PRIMARY = 0x00000010; 

public const long DISP_CHANGE_SUCCESSFUL = 0; 
public const long DISP_CHANGE_RESTART = 1; 
public const long DISP_CHANGE_FAILED = -1; 
public const long DISP_CHANGE_BADMODE = -2; 
public const long DISP_CHANGE_NOTUPDATED = -3; 
public const long DISP_CHANGE_BADFLAGS = -4; 
public const long DISP_CHANGE_BADPARAM = -5; 
public const long DISP_CHANGE_BADDUALVIEW = -6; 

    public static void SetPrimary(Screen screen) 
{ 
    DISPLAY_DEVICE d = new DISPLAY_DEVICE(); 
    DEVMODE dm = new DEVMODE(); 
    d.cb = Marshal.SizeOf(d); 
    uint deviceID = 1; 
    User_32.EnumDisplayDevices(null, deviceID, ref d, 0); // 
    User_32.EnumDisplaySettings(d.DeviceName, 0, ref dm); 
    dm.dmPelsWidth = 2560; 
    dm.dmPelsHeight = 1600; 
    dm.dmPositionX = screen.Bounds.Right; 
    dm.dmFields = DM_POSITION | DM_PELSWIDTH | DM_PELSHEIGHT; 
    User_32.ChangeDisplaySettingsEx(d.DeviceName, ref dm, IntPtr.Zero, CDS_SET_PRIMARY, IntPtr.Zero); 
} 

मैं इस तरह विधि कहते हैं?

उत्तर

3

मैं वास्तव में WinAPI-सामान के साथ मदद नहीं कर सकता लेकिन यदि आप एक Nvidia कार्ड का उपयोग कर रहे हैं आप तो फिर तुम माध्यमिक उत्पादन अपनी प्राथमिक rundll32.exe NvCpl.dll,dtcfg primary 2 आशा का उपयोग कर आप में मदद मिलेगी कर सकता है NVcontrolPanel Api Documentation पर एक नज़र हो सकता है ।

3

documentation for ChangeDisplaySettingsEx के अनुसार, "dmSize सदस्य को DEVMODE संरचना के बाइट्स में, आकार में प्रारंभ किया जाना चाहिए।" इसके अलावा, the EnumDisplaySettings documentation कहता है, "EnumDisplaySettings को कॉल करने से पहले, dmSize सदस्य को आकार (DEVMODE) पर सेट करें, और निजी ड्राइवर डेटा प्राप्त करने के लिए उपलब्ध अतिरिक्त स्थान के बाइट्स में आकार को इंगित करने के लिए dmDriverExtra सदस्य सेट करें"। मुझे यह प्रश्न में दिए गए कोड नमूने में नहीं दिख रहा है; यही कारण है कि यह असफल हो सकता है।

इसके अतिरिक्त, आपको DEVMODE और DISPLAY_DEVICE structs की परिभाषाओं में त्रुटियां हो सकती हैं, जिन्हें प्रश्न में शामिल नहीं किया गया था। Roger Lipscombe's suggestion इसे सी/सी ++ से काम करने के लिए पहले इस प्रकार की समस्या को रद्द करने का एक शानदार तरीका है।

अंत में, ChangeDisplaySettingsEx से वापसी मान की जांच करें और देखें कि क्या यह एक सुराग देता है कि यह विफल क्यों हो सकता है।

4

मैं सी # से दोनों की कोशिश करने के लिए यहां सलाह के बाद सी # से एक ही समस्या में भाग गया। अंततः मुझे पता चला कि माइक्रोसॉफ्ट प्रलेखन की बात स्पष्ट नहीं है कि प्राथमिक मॉनीटर को सेट करने का अनुरोध अनदेखा कर दिया जाएगा (लेकिन ऑपरेशन के साथ सफल होने के साथ रिपोर्ट की गई!) जब तक कि आप मॉनीटर की स्थिति भी सेट न करें (0, 0) DEVMODE संरचना पर। बेशक, इसका मतलब है कि आपको अपने अन्य मॉनीटर की स्थिति को स्थानांतरित करने की भी आवश्यकता है ताकि वे नए प्राथमिक मॉनिटर के सापेक्ष एक ही स्थान पर रह सकें। प्रलेखन के अनुसार (http://msdn.microsoft.com/en-us/library/windows/desktop/dd183413%28v=vs.85%29.aspx), प्रत्येक मॉनिटर के लिए CDS_NORESET ध्वज के साथ ChangeDisplaySettingsEx पर कॉल करें और फिर सबकुछ शून्य के साथ अंतिम कॉल करें।

निम्नलिखित कोड मेरे लिए काम किया:

public static void SetAsPrimaryMonitor(uint id) 
    { 
     var device = new DISPLAY_DEVICE(); 
     var deviceMode = new DEVMODE(); 
     device.cb = Marshal.SizeOf(device); 

     NativeMethods.EnumDisplayDevices(null, id, ref device, 0); 
     NativeMethods.EnumDisplaySettings(device.DeviceName, -1, ref deviceMode); 
     var offsetx = deviceMode.dmPosition.x; 
     var offsety = deviceMode.dmPosition.y; 
     deviceMode.dmPosition.x = 0; 
     deviceMode.dmPosition.y = 0; 

     NativeMethods.ChangeDisplaySettingsEx(
      device.DeviceName, 
      ref deviceMode, 
      (IntPtr)null, 
      (ChangeDisplaySettingsFlags.CDS_SET_PRIMARY | ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | ChangeDisplaySettingsFlags.CDS_NORESET), 
      IntPtr.Zero); 

     device = new DISPLAY_DEVICE(); 
     device.cb = Marshal.SizeOf(device); 

     // Update remaining devices 
     for (uint otherid = 0; NativeMethods.EnumDisplayDevices(null, otherid, ref device, 0); otherid++) 
     { 
      if (device.StateFlags.HasFlag(DisplayDeviceStateFlags.AttachedToDesktop) && otherid != id) 
      { 
       device.cb = Marshal.SizeOf(device); 
       var otherDeviceMode = new DEVMODE(); 

       NativeMethods.EnumDisplaySettings(device.DeviceName, -1, ref otherDeviceMode); 

       otherDeviceMode.dmPosition.x -= offsetx; 
       otherDeviceMode.dmPosition.y -= offsety; 

       NativeMethods.ChangeDisplaySettingsEx(
        device.DeviceName, 
        ref otherDeviceMode, 
        (IntPtr)null, 
        (ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | ChangeDisplaySettingsFlags.CDS_NORESET), 
        IntPtr.Zero); 

      } 

      device.cb = Marshal.SizeOf(device); 
     } 

     // Apply settings 
     NativeMethods.ChangeDisplaySettingsEx(null, IntPtr.Zero, (IntPtr)null, ChangeDisplaySettingsFlags.CDS_NONE, (IntPtr)null); 
    } 

ध्यान दें कि दूसरा पैरामीटर के रूप में एक DEVMODE struct साथ ChangeDisplaySettingsEx के लिए एक हस्ताक्षर स्पष्ट रूप से आप IntPtr.Zero में पारित करने के लिए अनुमति नहीं दी जाएगी। अपने आप को एक ही निर्वासन कॉल के लिए दो अलग-अलग हस्ताक्षर बनाएँ, यानी

[DllImport("user32.dll")] 
    public static extern DISP_CHANGE ChangeDisplaySettingsEx(string lpszDeviceName, ref DEVMODE lpDevMode, IntPtr hwnd, ChangeDisplaySettingsFlags dwflags, IntPtr lParam); 

    [DllImport("user32.dll")] 
    public static extern DISP_CHANGE ChangeDisplaySettingsEx(string lpszDeviceName, IntPtr lpDevMode, IntPtr hwnd, ChangeDisplaySettingsFlags dwflags, IntPtr lParam); 
+0

मैं के बारे में इस कोड को बाहर और प्रयोग करने की कोशिश करना चाहता हूँ, लेकिन यह कर सकते हैं आप अन्य मॉनीटर की स्थिति को स्थानांतरित करने की रणनीति के बारे में कुछ टिप्पणी करें? मुझे एमएसडीएन पर पदों का क्या मतलब है और उन्हें एक-दूसरे से कैसे संबंध करने की आवश्यकता है, चाहे वे नकारात्मक या सकारात्मक हो, आदि के बारे में अधिक दस्तावेज नहीं मिला है। आपका उदाहरण सभी अन्य मॉनीटरों को पिछली और ऊपर की पिछली स्थिति से ऊपर की ओर ले जाता है नया प्राथमिक मॉनिटर - ऐसा करने के लिए तर्क क्या है? इसे काफी नहीं देख रहा है। – user1454265

+0

मुझे अनुमान लगाने का अनुमान है - मुझे लगता है कि पूरा 2 डी विमान उचित खेल है, सकारात्मक या नकारात्मक है, और सापेक्ष स्थिति सिर्फ माउस रैपरराउंड के लिए महत्वपूर्ण है? – user1454265

+0

मुझे इस समय @ user1454265 पर कोशिश करने का मौका नहीं है (इसलिए उम्मीद है कि आप जो भी कह रहे हैं, उसे सत्यापित करेंगे), लेकिन मेरी यादें यह है कि प्राथमिक मॉनीटर का शीर्ष बाएं कोने हमेशा होता है (0 , 0), इसलिए मैंने उपर्युक्त इस तरह लिखा था कि जब आप प्राथमिक को बदलते हैं तो मॉनीटर अपनी सापेक्ष स्थिति बनाए रखते हैं (मेरे लिए महत्वपूर्ण है क्योंकि मेरे पास विषम स्थानों में विभिन्न आकारों के तीन मॉनीटर हैं)। – ADBailey

5

यहाँ ADBailey के समाधान के आधार पर पूरा कोड है:

public class MonitorChanger 
{ 
    public static void SetAsPrimaryMonitor(uint id) 
    { 
     var device = new DISPLAY_DEVICE(); 
     var deviceMode = new DEVMODE(); 
     device.cb = Marshal.SizeOf(device); 

     NativeMethods.EnumDisplayDevices(null, id, ref device, 0); 
     NativeMethods.EnumDisplaySettings(device.DeviceName, -1, ref deviceMode); 
     var offsetx = deviceMode.dmPosition.x; 
     var offsety = deviceMode.dmPosition.y; 
     deviceMode.dmPosition.x = 0; 
     deviceMode.dmPosition.y = 0; 

     NativeMethods.ChangeDisplaySettingsEx(
      device.DeviceName, 
      ref deviceMode, 
      (IntPtr)null, 
      (ChangeDisplaySettingsFlags.CDS_SET_PRIMARY | ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | ChangeDisplaySettingsFlags.CDS_NORESET), 
      IntPtr.Zero); 

     device = new DISPLAY_DEVICE(); 
     device.cb = Marshal.SizeOf(device); 

     // Update remaining devices 
     for (uint otherid = 0; NativeMethods.EnumDisplayDevices(null, otherid, ref device, 0); otherid++) 
     { 
      if (device.StateFlags.HasFlag(DisplayDeviceStateFlags.AttachedToDesktop) && otherid != id) 
      { 
       device.cb = Marshal.SizeOf(device); 
       var otherDeviceMode = new DEVMODE(); 

       NativeMethods.EnumDisplaySettings(device.DeviceName, -1, ref otherDeviceMode); 

       otherDeviceMode.dmPosition.x -= offsetx; 
       otherDeviceMode.dmPosition.y -= offsety; 

       NativeMethods.ChangeDisplaySettingsEx(
        device.DeviceName, 
        ref otherDeviceMode, 
        (IntPtr)null, 
        (ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | ChangeDisplaySettingsFlags.CDS_NORESET), 
        IntPtr.Zero); 

      } 

      device.cb = Marshal.SizeOf(device); 
     } 

     // Apply settings 
     NativeMethods.ChangeDisplaySettingsEx(null, IntPtr.Zero, (IntPtr)null, ChangeDisplaySettingsFlags.CDS_NONE, (IntPtr)null); 
    } 
} 

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)] 
public struct DEVMODE 
{ 
    public const int CCHDEVICENAME = 32; 
    public const int CCHFORMNAME = 32; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)] 
    [System.Runtime.InteropServices.FieldOffset(0)] 
    public string dmDeviceName; 
    [System.Runtime.InteropServices.FieldOffset(32)] 
    public Int16 dmSpecVersion; 
    [System.Runtime.InteropServices.FieldOffset(34)] 
    public Int16 dmDriverVersion; 
    [System.Runtime.InteropServices.FieldOffset(36)] 
    public Int16 dmSize; 
    [System.Runtime.InteropServices.FieldOffset(38)] 
    public Int16 dmDriverExtra; 
    [System.Runtime.InteropServices.FieldOffset(40)] 
    public UInt32 dmFields; 

    [System.Runtime.InteropServices.FieldOffset(44)] 
    Int16 dmOrientation; 
    [System.Runtime.InteropServices.FieldOffset(46)] 
    Int16 dmPaperSize; 
    [System.Runtime.InteropServices.FieldOffset(48)] 
    Int16 dmPaperLength; 
    [System.Runtime.InteropServices.FieldOffset(50)] 
    Int16 dmPaperWidth; 
    [System.Runtime.InteropServices.FieldOffset(52)] 
    Int16 dmScale; 
    [System.Runtime.InteropServices.FieldOffset(54)] 
    Int16 dmCopies; 
    [System.Runtime.InteropServices.FieldOffset(56)] 
    Int16 dmDefaultSource; 
    [System.Runtime.InteropServices.FieldOffset(58)] 
    Int16 dmPrintQuality; 

    [System.Runtime.InteropServices.FieldOffset(44)] 
    public POINTL dmPosition; 
    [System.Runtime.InteropServices.FieldOffset(52)] 
    public Int32 dmDisplayOrientation; 
    [System.Runtime.InteropServices.FieldOffset(56)] 
    public Int32 dmDisplayFixedOutput; 

    [System.Runtime.InteropServices.FieldOffset(60)] 
    public short dmColor; // See note below! 
    [System.Runtime.InteropServices.FieldOffset(62)] 
    public short dmDuplex; // See note below! 
    [System.Runtime.InteropServices.FieldOffset(64)] 
    public short dmYResolution; 
    [System.Runtime.InteropServices.FieldOffset(66)] 
    public short dmTTOption; 
    [System.Runtime.InteropServices.FieldOffset(68)] 
    public short dmCollate; // See note below! 
    [System.Runtime.InteropServices.FieldOffset(72)] 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)] 
    public string dmFormName; 
    [System.Runtime.InteropServices.FieldOffset(102)] 
    public Int16 dmLogPixels; 
    [System.Runtime.InteropServices.FieldOffset(104)] 
    public Int32 dmBitsPerPel; 
    [System.Runtime.InteropServices.FieldOffset(108)] 
    public Int32 dmPelsWidth; 
    [System.Runtime.InteropServices.FieldOffset(112)] 
    public Int32 dmPelsHeight; 
    [System.Runtime.InteropServices.FieldOffset(116)] 
    public Int32 dmDisplayFlags; 
    [System.Runtime.InteropServices.FieldOffset(116)] 
    public Int32 dmNup; 
    [System.Runtime.InteropServices.FieldOffset(120)] 
    public Int32 dmDisplayFrequency; 
} 

public enum DISP_CHANGE : int 
{ 
    Successful = 0, 
    Restart = 1, 
    Failed = -1, 
    BadMode = -2, 
    NotUpdated = -3, 
    BadFlags = -4, 
    BadParam = -5, 
    BadDualView = -6 
} 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
public struct DISPLAY_DEVICE 
{ 
    [MarshalAs(UnmanagedType.U4)] 
    public int cb; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
    public string DeviceName; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
    public string DeviceString; 
    [MarshalAs(UnmanagedType.U4)] 
    public DisplayDeviceStateFlags StateFlags; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
    public string DeviceID; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
    public string DeviceKey; 
} 

[Flags()] 
public enum DisplayDeviceStateFlags : int 
{ 
    /// <summary>The device is part of the desktop.</summary> 
    AttachedToDesktop = 0x1, 
    MultiDriver = 0x2, 
    /// <summary>The device is part of the desktop.</summary> 
    PrimaryDevice = 0x4, 
    /// <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary> 
    MirroringDriver = 0x8, 
    /// <summary>The device is VGA compatible.</summary> 
    VGACompatible = 0x10, 
    /// <summary>The device is removable; it cannot be the primary display.</summary> 
    Removable = 0x20, 
    /// <summary>The device has more display modes than its output devices support.</summary> 
    ModesPruned = 0x8000000, 
    Remote = 0x4000000, 
    Disconnect = 0x2000000, 
} 

[Flags()] 
public enum ChangeDisplaySettingsFlags : uint 
{ 
    CDS_NONE = 0, 
    CDS_UPDATEREGISTRY = 0x00000001, 
    CDS_TEST = 0x00000002, 
    CDS_FULLSCREEN = 0x00000004, 
    CDS_GLOBAL = 0x00000008, 
    CDS_SET_PRIMARY = 0x00000010, 
    CDS_VIDEOPARAMETERS = 0x00000020, 
    CDS_ENABLE_UNSAFE_MODES = 0x00000100, 
    CDS_DISABLE_UNSAFE_MODES = 0x00000200, 
    CDS_RESET = 0x40000000, 
    CDS_RESET_EX = 0x20000000, 
    CDS_NORESET = 0x10000000 
} 

public class NativeMethods 
{ 
    [DllImport("user32.dll")] 
    public static extern DISP_CHANGE ChangeDisplaySettingsEx(string lpszDeviceName, ref DEVMODE lpDevMode, IntPtr hwnd, ChangeDisplaySettingsFlags dwflags, IntPtr lParam); 

    [DllImport("user32.dll")] 
    // A signature for ChangeDisplaySettingsEx with a DEVMODE struct as the second parameter won't allow you to pass in IntPtr.Zero, so create an overload 
    public static extern DISP_CHANGE ChangeDisplaySettingsEx(string lpszDeviceName, IntPtr lpDevMode, IntPtr hwnd, ChangeDisplaySettingsFlags dwflags, IntPtr lParam); 

    [DllImport("user32.dll")] 
    public static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags); 

    [DllImport("user32.dll")] 
    public static extern bool EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode); 
} 

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

बहुत बहुत धन्यवाद एडीबीले और व्लादिमीर। मैं इसका इस्तेमाल हमारे स्कूल इंस्टॉलेशन (टीचर पीसी + स्केलर-> बीमर) के लिए कर सकता हूं, यहां सभी के लिए कोड है: https://github.com/Grunge/setDisplayRes ग्रीटिंग्स और धन्यवाद – grunge

संबंधित मुद्दे