As part of my continues set of articles about setting up WES, the following shows how to rotate the display from a batch file – don’t get too excited, first we will need to write an application to do it.  The reason that I want to do this from a batch file is that in the end, I want a set of batch files that will install drivers, like the display driver, and do some configuration of the system.   So this is just one step on my adventure.

Note that this Article originally will target Windows 7.  Given time, I will try it on other versions.

I started by looking at the code that I had for Windows CE (see Windows CE: Dynamic Screen Rotation) which was close, but not close enough.

So starting over.   I decided to ignore the recurring note that use of ChangeDisplaySettings() is incompatible on Windows 7 and give it a try.  To keep a long story short, I couldn’t find a reason not to use it.  It may be that the incompatibility is with other features of ChangeDisplaySettings().

My first attempt was simple, get the current settings using EnumDisplaySettings(), change the orientation, and call ChangeDisplaySettings().  That seemed promising at first, I could rotate to 180 degrees and back to 0, but it failed to go to 90 and 270.   This was simple enough to fix though, when rotating, the width and height must be set correctly.

This new version called ChangeDisplaySettings() passing the DEVMODE structure and zero.  If  you give that a try, you will see that it works to dynamically rotate the display.   The problem is that on reboot, the system went back to the original orientation.   Again, a simple fix.   The second parameter can be used to tell the system to save the settings to the registry for future use.

I kept this code simple, because I plan to control its use via batch files.  You may want to do more complex handling of command line arguments.

The following is the entire code.

#include "stdafx.h"
#include <windows.h>

bool RotateDisplay( int angle )
{
    DEVMODE dm;
    long lRet;
    bool RetVal = false;
    bool SwapHW = false;

    // initialize the DEVMODE structure
    ZeroMemory(&dm, sizeof(dm));
    dm.dmSize = sizeof(dm);

    if ( 0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
    {
        // determine new orientaion
        switch (angle)
        {
            case 270:
                if( dm.dmDisplayOrientation == DMDO_180 || dm.dmDisplayOrientation == DMDO_DEFAULT )
                    SwapHW = true;
                dm.dmDisplayOrientation = DMDO_270;
                break;
            case 180:
                if( dm.dmDisplayOrientation == DMDO_90 || dm.dmDisplayOrientation == DMDO_270 )
                    SwapHW = true;
                dm.dmDisplayOrientation = DMDO_180;
                break;
            case 90:
                if( dm.dmDisplayOrientation == DMDO_180 || dm.dmDisplayOrientation == DMDO_DEFAULT )
                    SwapHW = true;
                dm.dmDisplayOrientation = DMDO_90;
                break;
            case 0:
                if( dm.dmDisplayOrientation == DMDO_90 || dm.dmDisplayOrientation == DMDO_270 )
                    SwapHW = true;
                dm.dmDisplayOrientation = DMDO_DEFAULT;
                break;
            default:
                return false;
        }
       
        if( SwapHW )
        {
            // swap height and width
            DWORD dwTemp = dm.dmPelsHeight;
            dm.dmPelsHeight= dm.dmPelsWidth;
            dm.dmPelsWidth = dwTemp;
        }
       
        // Rotate the display
        lRet = ChangeDisplaySettings(&dm, CDS_GLOBAL | CDS_UPDATEREGISTRY );
        if (DISP_CHANGE_SUCCESSFUL == lRet)
        {
            RetVal = true;
        }
    }

    return RetVal;
}


int _tmain(int argc, _TCHAR* argv[])
{
    printf( "DisplaySettings\r\n");
    if( argc > 1 )
    {
        int angle = -1;
        if( wcscmp( argv[1], L"90" ) == 0 )
            angle=90;
        else if( wcscmp( argv[1], L"180" ) == 0 )
            angle=180;
        else if( wcscmp( argv[1], L"270" ) == 0 )
            angle=270;
        else if( wcscmp( argv[1], L"0" ) == 0 )
            angle=0;

        if( angle != -1 )
            RotateDisplay( angle );
    }
    return 0;
}