Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set the monitor orientation in Windows 7?

I want to write some fun code to flip the orientation upside down on Windows 7. See screen shot of the option I want to control.


Monitor Orientation


Here is the code I have:

class Program
{
    public const long WM_PAINT=0x0F;
    public const long WM_DISPLAYCHANGE=0x7E;

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
    public struct DEVMODE // taken from Win API
    {
        ...
        public System.Windows.Forms.ScreenOrientation dmDisplayOrientation;
    }

    [DllImport("user32.dll", CharSet=CharSet.Auto)]
    public static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);
    [DllImport("user32.dll", CharSet=CharSet.Ansi)]
    public static extern int ChangeDisplaySettings(ref DEVMODE lpDevMode, int dwFlags);
    [DllImport("User32.Dll")]
    public static extern long PostMessage(IntPtr hWnd, long wMsg, long wParam, long lParam);


    static void Main(string[] args)
    {

        ScreenOrientation ori=ScreenOrientation.Angle0;
        DEVMODE mode=new DEVMODE()
        {
            dmSize=(short)Marshal.SizeOf(typeof(DEVMODE)),
            dmDriverExtra=0,
            dmDeviceName=new string(new char[32]),
            dmFormName=new string(new char[32]),
        };

        try
        {
            EnumDisplaySettings(null, -1, ref mode);
            if((mode.dmFields&0x80)>0)
            {
                ori=mode.dmDisplayOrientation;
            }

            mode.dmDisplayOrientation=ScreenOrientation.Angle270;
            int temp=mode.dmPelsWidth;
            mode.dmPelsWidth=mode.dmPelsHeight;
            mode.dmPelsHeight=temp;
            int ret=ChangeDisplaySettings(ref mode, 0);
            PostMessage(Process.GetCurrentProcess().Handle, WM_DISPLAYCHANGE, 0, 0);
            ...
        }
        catch
        {
        }
    }
}

which runs, but does not produce any affects.

Reference code: http://justlikeamagic.com/2009/05/21/changing-display-settings-programmatically/ and http://msdn.microsoft.com/en-us/library/ms812499.aspx#tbconchgscrn_chngingdisplay

like image 277
John Alexiou Avatar asked Jun 18 '12 17:06

John Alexiou


People also ask

How do I fix my monitor orientation?

Select the Start button, then type settings. Select Settings > System > Display, and choose a screen orientation from the drop-down list next to Display orientation.

Why can't I change my display orientation?

Checking screen rotation settings Use the Windows key + A keyboard shortcut to open Action Center. Click the Expand button. Click the Rotation lock to turn it off. Quick Tip: You can also control this option under Scale and layout on Settings > System > Display.


2 Answers

On Windows 7, ChangeDisplaySetting has a known compatibility issue. The workaround is to call the WDK function: SetDisplayConfig.

http://social.msdn.microsoft.com/Forums/en/windowsuidevelopment/thread/5bc2396d-1e0e-44fb-b73b-95f8dfc45684

like image 105
Robert Harvey Avatar answered Sep 28 '22 03:09

Robert Harvey


I have started something.

Please have a look: MultiMonitorHelper

It includes necessary structures for Win7, so that you could call SetDisplayConfig and other functions.

An actual example, how to rotate monitor 90 degrees:

        int numPathArrayElements;
        int numModeInfoArrayElements;

        const QueryDisplayFlags pathType = QueryDisplayFlags.OnlyActivePaths;

        // query active paths from the current computer.
        // note that 0 is equal to SUCCESS!
        // TODO; HARDCODE MAGIC VALUES AWAY.
        if (CCDWrapper.GetDisplayConfigBufferSizes(pathType, out numPathArrayElements,
                                                   out numModeInfoArrayElements) == 0)
        {
            var pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements];
            var modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements];

            // TODO; FALLBACK MECHANISM THAT HANDLES DIFFERENT VALUES FOR ZERO.
            if (CCDWrapper.QueryDisplayConfig(
                pathType,
                ref numPathArrayElements, pathInfoArray,
                ref numModeInfoArrayElements,
                modeInfoArray, IntPtr.Zero) == 0)
            {

                pathInfoArray[0].targetInfo.rotation = DisplayConfigRotation.Rotate90;
                CCDWrapper.SetDisplayConfig((uint) numPathArrayElements, pathInfoArray, (uint) numModeInfoArrayElements,
                                            modeInfoArray, SdcFlags.Apply | SdcFlags.UseSuppliedDisplayConfig);
            }
         }

it's raw right now, meaning there is no "C# style" API right now, but none the less, you can use those structures.

like image 44
Erti-Chris Eelmaa Avatar answered Sep 28 '22 03:09

Erti-Chris Eelmaa