2010-10-14 24 views
5

Sto cercando di creare un'applicazione per scollegare un monitor secondario dalle finestre di Windows (lunga storia).Applicazione C++ per scollegare il monitor secondario

Ecco il codice di esempio di Microsoft che ho usato come base: http://support.microsoft.com/kb/308216/en-us

Ecco il mio codice:

#include <iostream> 
#include <windows.h> 

void DetachDisplay() 
{ 
    BOOL   FoundSecondaryDisp = FALSE; 
    DWORD   DispNum = 0; 
    DISPLAY_DEVICE DisplayDevice; 
    LONG   Result; 
    TCHAR   szTemp[200]; 
    int    i = 0; 
    DEVMODE defaultMode; 

    // initialize DisplayDevice 
    ZeroMemory(&DisplayDevice, sizeof(DisplayDevice)); 
    DisplayDevice.cb = sizeof(DisplayDevice); 

    // get all display devices 
    while (EnumDisplayDevices(NULL, DispNum, &DisplayDevice, 0)) 
     { 
     ZeroMemory(&defaultMode, sizeof(DEVMODE)); 
     defaultMode.dmSize = sizeof(DEVMODE); 
     if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName, ENUM_REGISTRY_SETTINGS, &defaultMode)) 
        OutputDebugString("Store default failed\n"); 

     if ((DisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) && 
      !(DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) 
      { 
      DEVMODE DevMode; 
      ZeroMemory(&DevMode, sizeof(DevMode)); 
      DevMode.dmSize = sizeof(DevMode); 
      DevMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION 
         | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ; 
      Result = ChangeDisplaySettingsEx((LPSTR)DisplayDevice.DeviceName, &DevMode, NULL, CDS_UPDATEREGISTRY, NULL); 
      //Result = ChangeDisplaySettingsEx((LPSTR)DisplayDevice.DeviceName, &DevMode, NULL, CDS_UPDATEREGISTRY, NULL); 
      ChangeDisplaySettingsEx (NULL, NULL, NULL, 0, NULL); 


      //The code below shows how to re-attach the secondary displays to the desktop 

      //ChangeDisplaySettingsEx((LPSTR)DisplayDevice.DeviceName, &defaultMode, NULL, CDS_UPDATEREGISTRY, NULL); 
      //ChangeDisplaySettingsEx((LPSTR)DisplayDevice.DeviceName, &defaultMode, NULL, CDS_UPDATEREGISTRY, NULL); 

      } 

     // Reinit DisplayDevice just to be extra clean 

     ZeroMemory(&DisplayDevice, sizeof(DisplayDevice)); 
     DisplayDevice.cb = sizeof(DisplayDevice); 
     DispNum++; 
     } // end while for all display devices 
} 

int main() 
{ 
    DetachDisplay(); 
    return 0; 
} 

Tuttavia, quando ho compilare ed eseguire tutto quello che ottiene è lo schermo per sfarfallio come se stia cambiando le risoluzioni ma in realtà non fa nulla di significativo (noto che il mouse si è mosso ... ma a parte questo niente).

Forse qualcun altro ha già creato un'utilità per eseguire questa esatta funzionalità, che funzionerebbe altrettanto bene se può essere richiamata dalla riga di comando.

Pensieri?

risposta

0

Il frammento di codice sopra in realtà stacca il dispositivo di visualizzazione secondario , non monitora. Lo stesso dispositivo di visualizzazione può contenere più monitor. Non ho ancora avuto successo con questo problema

2

È possibile utilizzare SetDisplayConfig per eseguire questa operazione in Windows 7. L'esempio seguente disattiva tutte le schermate secondarie.

UINT32 NumPathArrayElements = 0; 
UINT32 NumModeInfoArrayElements = 0; 
LONG error = GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS,&NumPathArrayElements,&NumModeInfoArrayElements); 
std::vector<DISPLAYCONFIG_PATH_INFO> PathInfoArray(NumPathArrayElements); 
std::vector<DISPLAYCONFIG_MODE_INFO> ModeInfoArray(NumModeInfoArrayElements); 
error = QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS,&NumPathArrayElements, &PathInfoArray[0],&NumModeInfoArrayElements, &ModeInfoArray[0],NULL); 

for(unsigned int i=0;i<PathInfoArray.size();++i){ 
    if(PathInfoArray[i].sourceInfo.modeInfoIdx<ModeInfoArray.size()){ 
     int modeIndex=PathInfoArray[i].sourceInfo.modeInfoIdx; 
     _POINTL pos=ModeInfoArray[modeIndex].sourceMode.position; 
     if(pos.x!=0 || pos.y!=0){ 
      PathInfoArray[i].flags=0; 
      break; 
     } 
    } 
} 
error = SetDisplayConfig(NumPathArrayElements, &PathInfoArray[0],NumModeInfoArrayElements, &ModeInfoArray[0],(SDC_APPLY | SDC_ALLOW_CHANGES | SDC_USE_SUPPLIED_DISPLAY_CONFIG)); 

Per un po 'più di informazioni sulle funzioni utilizzate: http://msdn.microsoft.com/en-us/library/ff539596%28v=VS.85%29.aspx

1

So che questo è un filo vecchio modo, ma mi è venuto su di essa mentre la ricerca di mio problema: Alla ricerca di un metodo per visualizzare un non- desktop interattivo su un dispositivo di visualizzazione secondario staccato mentre la sessione di console (e quindi WinSta0) è bloccata su Windows 7.

risposta alla domanda iniziale:

Quando si rimuove un dispositivo di visualizzazione:

DEVMODE.dmPelsWidth = 0; 
DEVMODE.dmPelsHeight = 0; 
DEVMODE.dmFields = DM_POSITION | DM_PELSWIDTH | DM_PELSHEIGHT; 
ChangeDisplaySettingsEx(....  

Se si sta staccando un display, la seconda chiamata a ChangeDisplaySettings(Ex) è necessario se si specifica CDS_RESET insieme CDS_UPDATEREGISTRY nella chiamata originale. Tuttavia, se si collega un display, sembra che sia necessaria la seconda chiamata a ChangeDisplaySettings (o, almeno, non ho trovato un modo per aggirarlo).

Fornisco il seguente codice C# di lavoro. Ecco uno script PowerShell da utilizzare con esso

param(
    [Parameter(Mandatory=$true, Position = 0)] [string]$Function, 
    [Parameter(Mandatory=$false, Position = 1)] [int]$DeviceID 
) 
clear-host 
add-type -TypeDefinition (Get-Content -Path .\Display.cs | Out-String) 
Switch ($Function) { 
    'Enum' {[MyNamespace.Display]::EnumDisplayDevices()} 
    'Detach' {[MyNamespace.Display]::DetachDisplayDevice($DeviceID)} 
    'Attach' {[MyNamespace.Display]::AttachDisplayDevice($DeviceID)} 
    Default { write-host 'There is no "' $Function '" function available!' } 
} 
+0

sarei sicuramente interessato a vedere quello che il codice C# si avvicinò con. –

+0

Nathan, ho dovuto spogliare un sacco di commenti, ma l'ho pubblicato qui in fondo. È stato scritto per essere utilizzato con PowerShell. Includo in questo post un piccolo esempio. Godere. – Frobozz

1
using System; 
using System.Runtime.InteropServices; 

namespace MyNamespace 
{ 
public class Win32 
{ 
    public struct POINTL 
    { 
     public Int32 x; 
     public Int32 y; 
    } 

    public struct RECT 
    { 
     public long left; 
     public long top; 
     public long right; 
     public long bottom; 
    } 

    [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; 
    } 

    [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 DmFlags 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; 
    } 

    [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 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct SECURITY_ATTRIBUTES 
    { 
     public int nLength; 
     public IntPtr lpSecurityDescriptor; 
     public int bInheritHandle; 
    } 

    [Flags] 
    public enum ACCESS_MASK : uint 
    { 
     DELETE = 0x00010000, 
     READ_CONTROL = 0x00020000, 
     WRITE_DAC = 0x00040000, 
     WRITE_OWNER = 0x00080000, 
     SYNCHRONIZE = 0x00100000, 

     STANDARD_RIGHTS_REQUIRED = 0x000F0000, 

     STANDARD_RIGHTS_READ = 0x00020000, 
     STANDARD_RIGHTS_WRITE = 0x00020000, 
     STANDARD_RIGHTS_EXECUTE = 0x00020000, 

     STANDARD_RIGHTS_ALL = 0x001F0000, 

     SPECIFIC_RIGHTS_ALL = 0x0000FFFF, 

     ACCESS_SYSTEM_SECURITY = 0x01000000, 

     MAXIMUM_ALLOWED = 0x02000000, 

     GENERIC_READ = 0x80000000, 
     GENERIC_WRITE = 0x40000000, 
     GENERIC_EXECUTE = 0x20000000, 
     GENERIC_ALL = 0x10000000, 

     DESKTOP_READOBJECTS = 0x00000001, 
     DESKTOP_CREATEWINDOW = 0x00000002, 
     DESKTOP_CREATEMENU = 0x00000004, 
     DESKTOP_HOOKCONTROL = 0x00000008, 
     DESKTOP_JOURNALRECORD = 0x00000010, 
     DESKTOP_JOURNALPLAYBACK = 0x00000020, 
     DESKTOP_ENUMERATE = 0x00000040, 
     DESKTOP_WRITEOBJECTS = 0x00000080, 
     DESKTOP_SWITCHDESKTOP = 0x00000100, 

     WINSTA_ENUMDESKTOPS = 0x00000001, 
     WINSTA_READATTRIBUTES = 0x00000002, 
     WINSTA_ACCESSCLIPBOARD = 0x00000004, 
     WINSTA_CREATEDESKTOP = 0x00000008, 
     WINSTA_WRITEATTRIBUTES = 0x00000010, 
     WINSTA_ACCESSGLOBALATOMS = 0x00000020, 
     WINSTA_EXITWINDOWS = 0x00000040, 
     WINSTA_ENUMERATE = 0x00000100, 
     WINSTA_READSCREEN = 0x00000200, 

     WINSTA_ALL_ACCESS = 0x0000037F 
    } 

    [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 
    } 

    [Flags()] 
    public enum DISP_CHANGE : int 
    { 
     SUCCESSFUL = 0, 
     RESTART = 1, 
     FAILED = -1, 
     BADMODE = -2, 
     NOTUPDATED = -3, 
     BADFLAGS = -4, 
     BADPARAM = -5, 
     BADDUALVIEW = -6 
    } 

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

    [DllImport("kernel32.dll")] 
    public static extern uint GetLastError(); 

    [DllImport("user32.dll", EntryPoint = "CreateWindowStation", CharSet = CharSet.Unicode, SetLastError = true)] 
    public static extern IntPtr CreateWindowStation(
     [MarshalAs(UnmanagedType.LPWStr)] string name, 
     [MarshalAs(UnmanagedType.U4)] uint dwFlags, 
     [MarshalAs(UnmanagedType.U4)] ACCESS_MASK desiredAccess, 
     [MarshalAs(UnmanagedType.LPStr)] ref SECURITY_ATTRIBUTES attributes 
    ); 
    [DllImport("user32.dll", EntryPoint = "CreateWindowStation", CharSet = CharSet.Unicode, SetLastError = true)] 
    public static extern IntPtr CreateWindowStation(
     [MarshalAs(UnmanagedType.LPWStr)] string name, 
     [MarshalAs(UnmanagedType.U4)] uint dwFlags, 
     [MarshalAs(UnmanagedType.U4)] ACCESS_MASK desiredAccess, 
     [MarshalAs(UnmanagedType.U4)] uint attributes 
    ); 

    [DllImport("user32.dll", EntryPoint = "CreateDesktop", CharSet = CharSet.Unicode, SetLastError = true)] 
    public static extern IntPtr CreateDesktop(
     [MarshalAs(UnmanagedType.LPWStr)] string desktopName, 
     [MarshalAs(UnmanagedType.LPWStr)] string device, // must be null. 
     [MarshalAs(UnmanagedType.LPWStr)] string deviceMode, // must be null, 
     [MarshalAs(UnmanagedType.U4)] int flags, // use 0 
     [MarshalAs(UnmanagedType.U4)] ACCESS_MASK accessMask, 
     [MarshalAs(UnmanagedType.LPStruct)] ref SECURITY_ATTRIBUTES attributes 
    ); 
    [DllImport("user32.dll", EntryPoint = "CreateDesktop", CharSet = CharSet.Unicode, SetLastError = true)] 
    public static extern IntPtr CreateDesktop(
     [MarshalAs(UnmanagedType.LPWStr)] string desktopName, 
     [MarshalAs(UnmanagedType.LPWStr)] string device, // must be null. 
     [MarshalAs(UnmanagedType.LPWStr)] string deviceMode, // must be null, 
     [MarshalAs(UnmanagedType.U4)] int flags, // use 0 
     [MarshalAs(UnmanagedType.U4)] ACCESS_MASK accessMask, 
     [MarshalAs(UnmanagedType.U4)] uint attributes 
    ); 

    [DllImport("user32.dll", EntryPoint = "CloseDesktop", CharSet = CharSet.Unicode, SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool CloseDesktop(IntPtr handle); 

    [DllImport("user32.dll")] 
    public static extern IntPtr OpenWindowStation(
     [MarshalAs(UnmanagedType.LPWStr)]string name, 
     [MarshalAs(UnmanagedType.Bool)] bool fInherit, 
     [MarshalAs(UnmanagedType.U4)] uint desiredAccess 
    ); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool SetProcessWindowStation(IntPtr hWinSta); 

    [DllImport("user32.dll")] 
    public static extern IntPtr GetProcessWindowStation(); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool CloseWindowStation(IntPtr hWinSta); 

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

    [DllImport("user32.dll")] 
    public static extern int EnumDisplaySettingsEx(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode, uint dwFlags); 

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

    [DllImport("user32.dll")] 
    public static extern IntPtr GetDC(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC); 

    [DllImport("user32.dll")] 
    public static extern int DrawText(IntPtr hDC, string lpString, int nCount, ref RECT lpRect, uint uFormat); 

    [DllImport("user32.dll")] 
    static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); 

    public const int ENUM_CURRENT_SETTINGS = -1; 
    public const int ENUM_REGISTRY_SETTINGS = -2; 
    public const int CWF_CREATE_ONLY = 1; 
    public const int DF_ALLOWOTHERACCOUNTHOOK = 1; 
    public const int DT_TOP = 0x00000000; 
    public const int DT_LEFT = 0x00000000; 
    public const int DT_CENTER = 0x00000001; 
    public const int DT_RIGHT = 0x00000002; 
    public const int DT_VCENTER = 0x00000004; 
    public const int DT_BOTTOM = 0x00000008; 
    public const int DT_WORDBREAK = 0x00000010; 
    public const int DT_SINGLELINE = 0x00000020; 
    public const int DT_EXPANDTABS = 0x00000040; 
    public const int DT_TABSTOP = 0x00000080; 
    public const int DT_NOCLIP = 0x00000100; 
    public const int DT_EXTERNALLEADING = 0x00000200; 
    public const int DT_CALCRECT = 0x00000400; 
    public const int DT_NOPREFIX = 0x00000800; 
    public const int DT_INTERNAL = 0x00001000; 

} 
public class Gdi32 
{ 
    [Flags()] 
    public enum DeviceCap : int 
    { 
     DRIVERVERSION = 0, 
     TECHNOLOGY = 2, 
     HORZSIZE = 4, 
     VERTSIZE = 6, 
     HORZRES = 8, 
     VERTRES = 10, 
     BITSPIXEL = 12, 
     PLANES = 14, 
     NUMBRUSHES = 16, 
     NUMPENS = 18, 
     NUMMARKERS = 20, 
     NUMFONTS = 22, 
     NUMCOLORS = 24, 
     PDEVICESIZE = 26, 
     CURVECAPS = 28, 
     LINECAPS = 30, 
     POLYGONALCAPS = 32, 
     TEXTCAPS = 34, 
     CLIPCAPS = 36, 
     RASTERCAPS = 38, 
     ASPECTX = 40, 
     ASPECTY = 42, 
     ASPECTXY = 44, 
     SHADEBLENDCAPS = 45, 
     LOGPIXELSX = 88, 
     LOGPIXELSY = 90, 
     SIZEPALETTE = 104, 
     NUMRESERVED = 106, 
     COLORRES = 108, 
     PHYSICALWIDTH = 110, 
     PHYSICALHEIGHT = 111, 
     PHYSICALOFFSETX = 112, 
     PHYSICALOFFSETY = 113, 
     SCALINGFACTORX = 114, 
     SCALINGFACTORY = 115, 
     VREFRESH = 116, 
     DESKTOPVERTRES = 117, 
     DESKTOPHORZRES = 118, 
     BLTALIGNMENT = 119 
    } 

    [DllImport("gdi32.dll")] 
    public static extern int GetDeviceCaps(IntPtr hdc, int nIndex); 

    [DllImport("gdi32.dll")] 
    public static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData); 

    [DllImport("gdi32.dll", EntryPoint = "DeleteDC")] 
    public static extern bool DeleteDC([In] IntPtr hdc); 

    [DllImport("gdi32.dll")] 
    public static extern int SetTextColor(IntPtr hdc, int crColor); 

    [DllImport("gdi32.dll")] 
    public static extern int SetBkColor(IntPtr hdc, int crColor); 

} 
public class Display 
{ 
    public static void EnumDisplayDevices() 
    { 
     uint deviceID = 0; 
     Win32.DISPLAY_DEVICE d = new Win32.DISPLAY_DEVICE(); 
     d.cb = Marshal.SizeOf(d); 
     Win32.DEVMODE dm = GetDevMode(); 
     while (Win32.EnumDisplayDevices(null, deviceID, ref d, 1)) 
     { 

      // Print Device Information 
      Console.WriteLine("\nDeviceID: {5} \nDeviceName: {0} \nDeviceString: {1}\nDeviceID (GUID): {2}\nDeviceKey {3}\nStateFlags {4}\n", 
       d.DeviceName, d.DeviceString, d.DeviceID, d.DeviceKey, d.StateFlags, deviceID); 
      deviceID++; 

     } 
    } 

    private static Win32.DEVMODE GetDevMode() 
    { 
     Win32.DEVMODE dm = new Win32.DEVMODE(); 
     dm.dmDeviceName = new String(new char[32]); 
     dm.dmFormName = new String(new char[32]); 
     dm.dmSize = (short)Marshal.SizeOf(dm); 
     return dm; 
    } 

    public static bool DetachDisplayDevice(uint deviceID) 
    { 
     bool rval = false; 
     Win32.DEVMODE dm = GetDevMode(); 
     Win32.DISPLAY_DEVICE d = new Win32.DISPLAY_DEVICE(); 
     d.cb = Marshal.SizeOf(d); 

     // Get the display device 
     if (!Win32.EnumDisplayDevices(null, deviceID, ref d, 0)) 
     { 
      Console.WriteLine("Device not found!"); 
      return false; 
     } 

     // Test that the display is actually attached to the desktop - bail if it is not 
     if ((d.StateFlags & Win32.DisplayDeviceStateFlags.AttachedToDesktop) == 0) 
     { 
      Console.WriteLine("Display Device {0} is not attached to this desktop!", d.DeviceName); 
      return false; 
     } 

     // Get current device settings 
     if (0 == Win32.EnumDisplaySettingsEx(d.DeviceName, Win32.ENUM_CURRENT_SETTINGS, ref dm, 0)) 
     { 
      Console.WriteLine("Settings for {0} could not be enumerated!", d.DeviceName); 
      return false; 
     } 

     // Prepare for detach 
     dm.dmPelsWidth = 0; 
     dm.dmPelsHeight = 0; 
     dm.dmFields = Win32.DmFlags.DM_POSITION | Win32.DmFlags.DM_PELSWIDTH | Win32.DmFlags.DM_PELSHEIGHT; 
     //dm.dmFields = (int) (DmFlags.DM_POSITION); 

     // Test the change 
     int iRet = Win32.ChangeDisplaySettingsEx(d.DeviceName, ref dm, IntPtr.Zero, Win32.ChangeDisplaySettingsFlags.CDS_TEST, IntPtr.Zero); 
     if (iRet == (int)Win32.DISP_CHANGE.FAILED) 
     { 
      Console.WriteLine("Unable To Process Your Request."); 
      return false; 
     } 

     // Now do it for real 
     iRet = Win32.ChangeDisplaySettingsEx(
      d.DeviceName, 
      ref dm, 
      IntPtr.Zero, 
      Win32.ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | Win32.ChangeDisplaySettingsFlags.CDS_RESET, 
      IntPtr.Zero 
      ); 
     //Win32.ChangeDisplaySettingsEx((string) null, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero); // Not needed for detach with CDS_RESET set. 

     switch (iRet) 
     { 
      case (int)Win32.DISP_CHANGE.SUCCESSFUL: 
       { 
        Console.WriteLine("Detached display: {0} \n", d.DeviceName); 
        rval = true; 
        break; 
       } 
      case (int)Win32.DISP_CHANGE.RESTART: 
       { 
        Console.WriteLine("A reboot is required for the change to take affect.\n"); 
        break; 
       } 
      default: 
       { 
        Console.WriteLine("Failed! Return value: {0}\n", iRet); 
        break; 
       } 
     } 
     return rval; 
    } 

    public static bool AttachDisplayDevice(uint deviceID) 
    { 
     bool rval = false; 
     Win32.DEVMODE dm = GetDevMode(); 
     Win32.DISPLAY_DEVICE d = new Win32.DISPLAY_DEVICE(); 
     d.cb = Marshal.SizeOf(d); 
     int nWidth; 
     IntPtr hdc; 

     // Get current device context width 
     hdc = Win32.GetDC(IntPtr.Zero); 
     nWidth = Gdi32.GetDeviceCaps(hdc, (int)Gdi32.DeviceCap.HORZRES); 
     Win32.ReleaseDC(IntPtr.Zero, hdc); 


     // Get the display device 
     if (!Win32.EnumDisplayDevices(null, deviceID, ref d, 0)) 
     { 
      Console.WriteLine("Device not found!"); 
      return false; 
     } 

     // Test that the display is NOT actually attached to the desktop - bail if it is 
     if ((d.StateFlags & Win32.DisplayDeviceStateFlags.AttachedToDesktop) != 0) 
     { 
      Console.WriteLine("Display Device {0} is already attached to this desktop!", d.DeviceName); 
      return false; 
     } 

     // Get current device settings 
     if (0 == Win32.EnumDisplaySettingsEx(d.DeviceName, Win32.ENUM_REGISTRY_SETTINGS, ref dm, 0)) 
     { 
      Console.WriteLine("Settings for {0} could not be enumerated!", d.DeviceName); 
      return false; 
     } 

     // Prepare for attach 
     dm.dmPosition.x += nWidth; 
     dm.dmFields = Win32.DmFlags.DM_POSITION; 

     // Test the change 
     int iRet = Win32.ChangeDisplaySettingsEx(d.DeviceName, ref dm, IntPtr.Zero, Win32.ChangeDisplaySettingsFlags.CDS_TEST, IntPtr.Zero); 
     if (iRet == (int)Win32.DISP_CHANGE.FAILED) 
     { 
      Console.WriteLine("Unable To Process Your Request."); 
      return false; 
     } 

     // Now do it for real 
     iRet = Win32.ChangeDisplaySettingsEx(
      d.DeviceName, 
      ref dm, 
      IntPtr.Zero, 
      Win32.ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | Win32.ChangeDisplaySettingsFlags.CDS_NORESET, 
      IntPtr.Zero 
      ); 
     Win32.ChangeDisplaySettingsEx((string)null, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero); 

     switch (iRet) 
     { 
      case (int)Win32.DISP_CHANGE.SUCCESSFUL: 
       { 
        Console.WriteLine("Attached display: {0} \n", d.DeviceName); 
        rval = true; 
        break; 
       } 
      case (int)Win32.DISP_CHANGE.RESTART: 
       { 
        Console.WriteLine("A reboot is required for the change to take affect.\n"); 
        break; 
       } 
      default: 
       { 
        Console.WriteLine("Failed! Return value: {0}\n", iRet); 
        break; 
       } 
     } 
     return rval; 
    } 
} 
} 
+0

dopo aver copiato tutte le cose 'pinvoke' insieme e in modo orribile, ho preso il tuo codice. 'DetachDisplayDevice' funziona in modo impeccabile ma non riesco a far funzionare' AttachDisplayDevice'. 'ChangeDisplaySettingsEx' restituisce' Win32.DISP_CHANGE.FAILED' per me tutto il tempo, non importa quello che ho impostato per 'DEVMODE'. Hai incontrato anche questo problema? Avete qualche soluzione? – MadddinTribleD

Problemi correlati