Checking for Screen Rotation Support Using NetCF

Yesterday, the Windows Mobile team posted a handy tip titled "How to check if screen can be rotated".  This got me interested in checking for screen rotation support from managed code.

In V1, the structure to be marshalled is not pretty.  Since the fixed size character arrays are not at the end of the structure (and since we will not be needing their values in this example), the easiest way to get them marshalled is to flatten the arrays.  This will get much nicer in V2 (I'll revisit this example when the next public V2 beta is available).

Though the structure (DeviceMode) included here is rather large, we will be using only three fields:
DeviceMode.Size                 - the size of the structureDeviceMode.Fields               - the fields being usedDeviceMode.DisplayOrientation   - where we will receive the results

Example
using System;using System.Runtime.InteropServices;using System.Windows.Forms;

class ScreenRotationCheck
{
    public static void Main()
    {
        String msg;
        Boolean rotationSupported = false;

        // prepare the DeviceMode structure
        DeviceMode devMode = new DeviceMode();
        devMode.Size = (Int16)Marshal.SizeOf(devMode);
        devMode.Fields = DisplayQueryOrientation;
      
        // ask the operating system if it supports screen rotation
        Int32 result = ChangeDisplaySettingsEx(null,        // primary display
                                             ref devMode,
                                             IntPtr.Zero,   // reserved must be 0
                                             ChangeDisplaySettingsTest,
                                             IntPtr.Zero);
        if(0 == result)
        {
            // ChangeDisplaySettingsEx call succeeded,
            //  we can check the results of our query
           
            // non-zero value in DisplayOrientation means
            //  rotation is supported
            if(0 != devMode.DisplayOrientation)
            {
                rotationSupported = true;
            }
           
            // format the message to display
            msg = String.Format("Screen rotation supported: {0}",
                                rotationSupported);
        }
        else
        {
            msg = String.Format("ChangeDisplaySettingsEx failed with error code: {0}",
                                result);
        }

        // display our findings
        MessageBox.Show(msg, "Screen rotation check");
    }   

    // DeviceMode field value(s)
    private static Int32 DisplayQueryOrientation = 0x01000000;

    // ChangeDisplaySettingsEx flags value(s)
    private static Int32 ChangeDisplaySettingsTest = 2;

    // pinvoke(s)
    [DllImport("coredll.dll", SetLastError=true)]
    private extern static Int32 ChangeDisplaySettingsEx(String deviceName,
                                                    ref DeviceMode deviceMode,
                                                    IntPtr hwnd,
                                                    Int32 flags,
                                                    IntPtr param);
}

// managed version of the DEVMODE structure
struct DeviceMode
{
    // these 32 elements are DEVMODE.dmDeviceName
    public char DeviceName0;
    public char DeviceName1;
    public char DeviceName2;
    public char DeviceName3;
    public char DeviceName4;
    public char DeviceName5;
    public char DeviceName6;
    public char DeviceName7;
    public char DeviceName8;
    public char DeviceName9;
    public char DeviceName10;
    public char DeviceName11;
    public char DeviceName12;
    public char DeviceName13;
    public char DeviceName14;
    public char DeviceName15;
    public char DeviceName16;
    public char DeviceName17;
    public char DeviceName18;
    public char DeviceName19;
    public char DeviceName20;
    public char DeviceName21;
    public char DeviceName22;
    public char DeviceName23;
    public char DeviceName24;
    public char DeviceName25;
    public char DeviceName26;
    public char DeviceName27;
    public char DeviceName28;
    public char DeviceName29;
    public char DeviceName30;
    public char DeviceName31;

    public Int16 SpecVersion;
    public Int16 DriverVersion;
    public Int16 Size;
    public Int16 DriverExtra;
    public Int32 Fields;
    public Int16 Orientation;
    public Int16 PaperSize;
    public Int16 PaperLength;
    public Int16 PaperWidth;
    public Int16 Scale;
    public Int16 Copies;
    public Int16 DefaultSource;
    public Int16 PrintQuality;
    public Int16 Color;
    public Int16 Duplex;
    public Int16 YResolution;
    public Int16 TTOption;
    public Int16 Collate;

    // these 32 elements are DEVMODE.dmFormName
    public char FormName0;
    public char FormName1;
    public char FormName2;
    public char FormName3;
    public char FormName4;
    public char FormName5;
    public char FormName6;
    public char FormName7;
    public char FormName8;
    public char FormName9;
    public char FormName10;
    public char FormName11;
    public char FormName12;
    public char FormName13;
    public char FormName14;
    public char FormName15;
    public char FormName16;
    public char FormName17;
    public char FormName18;
    public char FormName19;
    public char FormName20;
    public char FormName21;
    public char FormName22;
    public char FormName23;
    public char FormName24;
    public char FormName25;
    public char FormName26;
    public char FormName27;
    public char FormName28;
    public char FormName29;
    public char FormName30;
    public char FormName31;

    public Int16 LogPixels;
    public Int32 BitsPerPel;
    public Int32 PelsWidth;
    public Int32 PelsHeight;
    public Int32 DisplayFlags;
    public Int32 DisplayFrequency;
    public Int32 DisplayOrientation;
}

From the documentation on ChangeDisplaySettingsEx, when querying display orientation support:

"The supported screen orientations are returned in lpDevMode.dmDisplayOrientation.  A value of just DMO_0 indicates that screen rotation is not supported."

Based on the above, receiving the default orientation value (DMOD_0 == 0) in DeviceMode.DisplayOrientation indicates that the device does not support rotation.  Any value other than 0 means rotation is supported.

Enjoy!
-- DK

Disclaimer(s):
This posting is provided "AS IS" with no warranties, and confers no rights.
Some of the information contained within this post may be in relation to beta software. Any and all details are subject to change.