i'm looking way rotate display of 1 of monitors programmatically. have 2 monitors set on desk mount, , use them in varying orientations when programming or using various other programs, , in order change orientation jump display settings , rotate way (so can have 1 or both in portrait).
call me lazy know thats hardly hassle do, nice have quick little executable on taskbar can run instantly rotate 1 of screens , forth when need to.
i've looked , found various explanations using devmode structs etc, , seems long winded process, there not easier way this? not windows dll has functionailty already?
thanks in advance.
it's not hard achieve using mentioned devmode struct , native calls. i've written little wrapper this:
using system; using system.runtime.interopservices; public class display { public enum orientations { degrees_cw_0 = 0, degrees_cw_90 = 3, degrees_cw_180 = 2, degrees_cw_270 = 1 } public static bool rotate(uint displaynumber, orientations orientation) { if(displaynumber == 0) throw new argumentoutofrangeexception("displaynumber", displaynumber, "first display 1."); bool result = false; display_device d = new display_device(); devmode dm = new devmode(); d.cb = marshal.sizeof(d); if(!nativemethods.enumdisplaydevices(null, displaynumber-1, ref d, 0)) throw new argumentoutofrangeexception("displaynumber", displaynumber, "number greater connected displays."); if (0 != nativemethods.enumdisplaysettings( d.devicename, nativemethods.enum_current_settings, ref dm)) { if ((dm.dmdisplayorientation + (int)orientation) % 2 == 1) // need swap height , width? { int temp = dm.dmpelsheight; dm.dmpelsheight = dm.dmpelswidth; dm.dmpelswidth = temp; } switch (orientation) { case orientations.degrees_cw_90: dm.dmdisplayorientation = nativemethods.dmdo_270; break; case orientations.degrees_cw_180: dm.dmdisplayorientation = nativemethods.dmdo_180; break; case orientations.degrees_cw_270: dm.dmdisplayorientation = nativemethods.dmdo_90; break; case orientations.degrees_cw_0: dm.dmdisplayorientation = nativemethods.dmdo_default; break; default: break; } disp_change ret = nativemethods.changedisplaysettingsex( d.devicename, ref dm, intptr.zero, displaysettingsflags.cds_updateregistry, intptr.zero); result = ret == 0; } return result; } public static void resetallrotations() { try { uint = 0; while (++i <= 64) { rotate(i, orientations.degrees_cw_0); } } catch(argumentoutofrangeexception ex) { // fine, reached last display } } } internal class nativemethods { [dllimport("user32.dll")] internal static extern disp_change changedisplaysettingsex( string lpszdevicename, ref devmode lpdevmode, intptr hwnd, displaysettingsflags dwflags, intptr lparam); [dllimport("user32.dll")] internal static extern bool enumdisplaydevices( string lpdevice, uint idevnum, ref display_device lpdisplaydevice, uint dwflags); [dllimport("user32.dll", charset = charset.ansi)] internal static extern int enumdisplaysettings( string lpszdevicename, int imodenum, ref devmode lpdevmode); public const int dmdo_default = 0; public const int dmdo_90 = 1; public const int dmdo_180 = 2; public const int dmdo_270 = 3; public const int enum_current_settings = -1; } // see: https://msdn.microsoft.com/en-us/library/windows/desktop/dd183565(v=vs.85).aspx [structlayout(layoutkind.explicit, charset = charset.ansi)] internal 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 dm 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; [system.runtime.interopservices.fieldoffset(62)] public short dmduplex; [system.runtime.interopservices.fieldoffset(64)] public short dmyresolution; [system.runtime.interopservices.fieldoffset(66)] public short dmttoption; [system.runtime.interopservices.fieldoffset(68)] public short dmcollate; [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; } // see: https://msdn.microsoft.com/en-us/library/windows/desktop/dd183569(v=vs.85).aspx [structlayout(layoutkind.sequential, charset = charset.ansi)] internal 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; } // see: https://msdn.microsoft.com/de-de/library/windows/desktop/dd162807(v=vs.85).aspx [structlayout(layoutkind.sequential)] internal struct pointl { long x; long y; } internal enum disp_change : int { successful = 0, restart = 1, failed = -1, badmode = -2, notupdated = -3, badflags = -4, badparam = -5, baddualview = -6 } // http://www.pinvoke.net/default.aspx/enums/displaydevicestateflags.html [flags()] internal enum displaydevicestateflags : int { /// <summary>the device part of desktop.</summary> attachedtodesktop = 0x1, multidriver = 0x2, /// <summary>the device part of desktop.</summary> primarydevice = 0x4, /// <summary>represents pseudo device used mirror application drawing remoting or other purposes.</summary> mirroringdriver = 0x8, /// <summary>the device vga compatible.</summary> vgacompatible = 0x10, /// <summary>the device removable; cannot primary display.</summary> removable = 0x20, /// <summary>the device has more display modes output devices support.</summary> modespruned = 0x8000000, remote = 0x4000000, disconnect = 0x2000000 } // http://www.pinvoke.net/default.aspx/user32/changedisplaysettingsflags.html [flags()] internal enum displaysettingsflags : int { 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()] internal enum dm : int { orientation = 0x00000001, papersize = 0x00000002, paperlength = 0x00000004, paperwidth = 0x00000008, scale = 0x00000010, position = 0x00000020, nup = 0x00000040, displayorientation = 0x00000080, copies = 0x00000100, defaultsource = 0x00000200, printquality = 0x00000400, color = 0x00000800, duplex = 0x00001000, yresolution = 0x00002000, ttoption = 0x00004000, collate = 0x00008000, formname = 0x00010000, logpixels = 0x00020000, bitsperpixel = 0x00040000, pelswidth = 0x00080000, pelsheight = 0x00100000, displayflags = 0x00200000, displayfrequency = 0x00400000, icmmethod = 0x00800000, icmintent = 0x01000000, mediatype = 0x02000000, dithertype = 0x04000000, panningwidth = 0x08000000, panningheight = 0x10000000, displayfixedoutput = 0x20000000 }
you can invoke static rotate-function display number want rotate (monitor 1=1, monitor 2=2, etc.) , degree need. this:
display.rotate(1, display.orientations.degrees_cw_180);
there little short-hand function resetallrotations()
reset displays.
regards
Comments
Post a Comment