Someone asked me today about rotating, or turning, the display on a Windows CE device.
MSDN actually has a nice example of how to do this at Creating a Project for the Screen Rotation Application.  But the example application takes some study to convert it to something really useful. It rotates the display 90 degrees each time the application is run, handy but not that useful because that isn’t really how applications typically rotate the display. Instead applications tend to know the angle that the display should be and rotate to that angle.
So, I thought I would share my revisions to this code. My function, ScreenRotate(), takes an angle in degrees and rotates the display. I chose degrees instead of the pre-defined macros like DMDO_90 for a couple of reasons; I can’t remember those macros names and I find it easier to remember the actual degrees, like 90 better.
ScreenRotate() checks the angle to ensure that it is a multiple of 90 degrees, then converts the angle to one of those DMDO macro values. The DMDO macro values are actually bits: 0 == 0 degrees, 1 == 90 degrees, 2 == 180 degrees and 4 == 270 degrees. I eliminated the check to see what angle the display is currently rotated to, I suppose it could add value if you add code to check if the requested angle is the current display rotation. I also removed the success messages because I am not a big fan of software that pats itself on the back for doing what it is expected to do.
ScreenRotate() looks like:
BOOL ScreenRotate( int NewAngleDegrees )
{
DEVMODE DevMode;
int CurrentAngle;
int RotationAngles;
int NewAngle;

if( NewAngleDegrees % 90 )
{
RETAILMSG( 1, (TEXT("ScreenRotate Invalid Angle %d\n"), NewAngleDegrees ));
RETAILMSG( 1, (TEXT("Angle must be a multiple of 90 degrees\n")));
return FALSE;
}

NewAngleDegrees %= 360;
NewAngle = NewAngleDegrees / 90;
if( NewAngle == 3 )
NewAngle = 0x4;

//
// Check for rotation support by getting the rotation angles supported.
//

memset (&DevMode, 0, sizeof (DevMode));
DevMode.dmSize   = sizeof (DevMode);
DevMode.dmFields = DM_DISPLAYQUERYORIENTATION;

if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL))
{
RETAILMSG(1, (L"ChangeDisplaySettingsEx failed to get the supported rotation angles.\n"));
return FALSE;
}
RotationAngles = DevMode.dmDisplayOrientation;

if (NewAngle == 0 || NewAngle & RotationAngles)
{
memset(&DevMode, 0, sizeof (DevMode));
DevMode.dmSize               = sizeof (DevMode);
DevMode.dmFields             = DM_DISPLAYORIENTATION;
DevMode.dmDisplayOrientation = NewAngle;

if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_RESET, NULL))
{
RETAILMSG(1, (L"ChangeDisplaySettingsEx failed to change the rotation angle to %d\n", NewAngle));
}
}

return TRUE;
}
Then I tested ScreenRotate() with the following calls:
ScreenRotate( 180 );
ScreenRotate( 0 );
ScreenRotate( 45 );
ScreenRotate( 90 );
ScreenRotate( 270 );
ScreenRotate( 720 );
Of course rotating to 45 degrees fails as expected, but the rest all of which are multiples of 90 degrees work as expected.