title: Programmatically rotate monitor
body: <p>I'm working on making a utility script that does a whole bunch of things.  One of the things I want to do is to rotate a display; I have multiple monitors, and I want the main one to rotate.  I know this sort of thing usually works through <code>win32api</code> and I found a few functions there that seem helpful, but I'm struggling with the implementation.</p>
  
  <p><em>Everything between this line and the next is out of date, see below second line for up to date description of solution attempts</em></p>
  
  <hr>
  
  <p>After burying my face in the docs, I'm afraid I still don't have much of an idea on how to move forward aside from that it will likely involve <code>win32api.ChangeDisplaySettingsEx()</code>.  I know I need to give that function a pointer to a <code>DEVMODE</code> object (not even sure how to do C pointers in python), which I think I can get from <code>win32api.EnumDisplaySettingsEx()</code>.   So if I try,</p>
  
  <pre><code>&gt;&gt;&gt; import win32api as win32
  &gt;&gt;&gt; a = win32.EnumDisplayDevices()
  &gt;&gt;&gt; type(a)
  </code></pre>
  
  <p>I should get something that involves <code>DEVMODE</code> pointer or whatever, but instead I get </p>
  
  <pre><code>&gt;&gt;&gt; type(a)
  &lt;type 'PyDISPLAY_DEVICE'&gt;
  </code></pre>
  
  <p>And I have no idea what to do with that, but I think <a href="http://msdn.microsoft.com/en-us/library/aa932948.aspx" rel="nofollow">this is the structure</a></p>
  
  <p>So, how do I get a <code>DEVMODE</code> ojbect I can give to <code>ChangeDisplaySettingsEx()</code> so that I can rotate one of my displays?  Thanks in advance.</p>
  
  <p>I'm running Python 2.7 on Windows 7</p>
  
  <p><strong>EDIT:</strong>  If I acutally use the correct function, it still doesn't work.  Could this be the Python module be not complete?</p>
  
  <pre><code>&gt;&gt;&gt; a = win32.EnumDisplaySettings()
  &gt;&gt;&gt; type(a)
  &lt;type 'PyDEVMODEA'&gt;
  &gt;&gt;&gt; a.dmSize
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  AttributeError: 'PyDEVMODEA' object has no attribute 'dmSize'
  &gt;&gt;&gt; a.dmScale
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  AttributeError: 'PyDEVMODEA' object has no attribute 'dmScale'
  &gt;&gt;&gt; a.dmDisplayOrientation
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  AttributeError: 'PyDEVMODEA' object has no attribute 'dmDisplayOrientation'
  </code></pre>
  
  <p>Now, I noticed that this is giving me a <code>DEVMODEA</code> object instead of <code>DEVMODE</code>, but <a href="http://msdn.microsoft.com/en-us/library/dd942189.aspx" rel="nofollow">this page</a> says they're the same.  What could be the issue here?</p>
  
  <p><strong>EDIT:</strong> Now that I'm using the correct attribute names, I can get a valid <code>DEVMODEA</code> object:</p>
  
  <pre><code>&gt;&gt;&gt; a = win32.EnumDisplaySettings()
  &gt;&gt;&gt; a.Size
  124L
  &gt;&gt;&gt; a.DisplayOrientation
  0L
  </code></pre>
  
  <p>And change the orientation in the object:</p>
  
  <pre><code>&gt;&gt;&gt; a.DisplayOrientation = 90L
  &gt;&gt;&gt; a.DisplayOrientation
  90L
  </code></pre>
  
  <p>I can then attempt to "apply" these changes by giving this <code>DEVMODEA</code> object to <code>ChangeDisplaySettingsEx()</code></p>
  
  <pre><code>&gt;&gt;&gt; win32.ChangeDisplaySettingsEx(a.DeviceName, a, 0)
  -5L
  </code></pre>
  
  <p><strike>This does nothing.  Unfortnately, <a href="http://msdn.microsoft.com/en-us/library/aa923082.aspx" rel="nofollow">the docs</a> aren't very useful in helping me interpret the return value.  I'm assuming <code>-5L</code> is some sort of error code since it didn't work, but I have no way of knowing which one.  What does this return value mean and how do I get my new <code>DEVMODEA</code> object to "apply"</strike></p>
  
  <p>I've worked out that <code>-5L</code> return value indicates a bad parameter.  Specifically, its angry at the first field.  If I replace that with <code>DISPLAY_DEVICE.DeviceName</code>, I get a <code>-2L</code> result.  This corresponds to a bad mode (whatever that is).  This happens even if I give <code>ChangeDisplaySettingsEx()</code> exactly what <code>EnumDisplaySettings()</code> puts out.</p>
  
  <hr>
  
  <p>So my progress so far:</p>
  
  <pre><code>&gt;&gt;&gt; import win32api as win32
  &gt;&gt;&gt; import win32con
  &gt;&gt;&gt; a = win32.EnumDisplaySettings()
  &gt;&gt;&gt; a.DisplayOrientation
  0L
  &gt;&gt;&gt; a.DisplayOrientation = win32con.DMDO_90
  &gt;&gt;&gt; a.DisplayOrientation
  1L
  &gt;&gt;&gt; a.PelsWidth, a.PelsHeight = a.PelsHeight, a.PelsWidth
  &gt;&gt;&gt; a.Fields = a.Fields &amp; win32con.DM_DISPLAYORIENTATION
  &gt;&gt;&gt; name = win32.EnumDisplayDevices().DeviceName
  &gt;&gt;&gt; name
  '\\\\.\\DISPLAY1'
  &gt;&gt;&gt; win32.ChangeDisplaySettingsEx(name, a)
  -2L
  </code></pre>
  
  <hr>
  
  <p>Most recent attempt (6/4, 10:50am EST)</p>
  
  <pre><code>Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32
  Type "help", "copyright", "credits" or "license" for more information.
  &gt;&gt;&gt; import win32api as win32
  &gt;&gt;&gt; import win32con
  &gt;&gt;&gt;
  &gt;&gt;&gt; device = win32.EnumDisplayDevices(None, 1)
  &gt;&gt;&gt; print "Rotate device {} ({})".format(device.DeviceString, device.DeviceName)
  Rotate device Intel(R) HD Graphics 4000 (\\.\DISPLAY2)
  &gt;&gt;&gt;
  &gt;&gt;&gt; dm = win32.EnumDisplaySettings(device.DeviceName, win32con.ENUM_CURRENT_SETTINGS)
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  pywintypes.error: (0, 'EnumDisplaySettings', 'No error message is available')
  &gt;&gt;&gt;
  &gt;&gt;&gt; dm = win32.EnumDisplaySettings(device.DeviceName)
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  pywintypes.error: (123, 'EnumDisplaySettings', 'The filename, directory name, or volume label syntax is incorrect.')
  &gt;&gt;&gt;
  &gt;&gt;&gt; dm = win32.EnumDisplaySettings(device.DeviceName, win32con.ENUM_CURRENT_SETTINGS)
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  pywintypes.error: (123, 'EnumDisplaySettings', 'The filename, directory name, or volume label syntax is incorrect.')
  &gt;&gt;&gt;
  </code></pre>
  
  <p>Notice how the first and third attempt to create <code>dm</code> fail <em>with different errors despite being the same code</em>.  </p>