Search code examples
delphiribbontabletscreen-rotation

How to prevent the screen from automatically rotating on a tablet?


In the link below, Microsoft describes two ways to limit rotation of an application screen on a tablet.

http://msdn.microsoft.com/en-ca/library/windows/apps/hh700342.aspx

what's happening is that delphi's (XE3) TRibbon doesn't handle rotation well. it tends to get hung.

as would be expected, the MS web site describes how to do this from MS development products. I don't see how I can do this in my Delphi project.

Method 1:

add this to your appxmanifest file:

<InitialRotationPreference>
    <Rotation Preference="landscape"/>
    <Rotation Preference="landscapeFlipped"/>
</InitialRotationPreference>

I haven't yet found where/how the appxmanifest should be part of the application so I can do this in delphi.

Method 2:

call this with code:

 Windows.Graphics.Display.DisplayProperties.AutoRotationPreferences =
            Windows.Graphics.Display.DisplayOrientations.Landscape;

to migrate this to delphi, I'd need to know API DLL information so I could do something similar.

Any ideas?

Could there be a COM object or DLL that gives us access to this?


Solution

  • Those calls are to disable rotation for a WindowsRT application (FKA Metro) which you cannot build with Delphi (yet). Even a Metropolis app is still a desktop app. There is a solution on the Intel site.

    Based on feedback from X-Ray I cleaned up the code:

    unit MetroDisplayRotation;
    
    (* 
     *  Usage: TMetroDisplayRotation.SetDisplayAutoRotationPreferences(
     *           TMetroDisplayRotation.ORIENTATION_PREFERENCE_LANDSCAPE or 
     *           TMetroDisplayRotation.ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED);
     *)
    
    interface
    
    type
      TMetroDisplayRotation = class
      public const
        ORIENTATION_PREFERENCE_NONE = $0;
        ORIENTATION_PREFERENCE_LANDSCAPE = $1;
        ORIENTATION_PREFERENCE_PORTRAIT = $2;
        ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED = $4;
        ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED = $8;
    
        class procedure SetDisplayAutoRotationPreferences(ORIENTATION_PREFERENCE: Integer);
      end;
    
    implementation
    
    uses
      SysUtils, Windows;
    
    { TMetroDisplayRotation }
    
    class procedure TMetroDisplayRotation.SetDisplayAutoRotationPreferences(
      ORIENTATION_PREFERENCE: Integer);
    type
      TSDARP = procedure(ORIENTATION_PREFERENCE: Integer); stdcall;
    var
      UserHandle: THandle;
      SDARP: TSDARP;
    begin
      UserHandle := GetModuleHandle('User32.dll');
      @SDARP := GetProcAddress(UserHandle, 'SetDisplayAutoRotationPreferences');
      if Assigned(SDARP) then
        SDARP(ORIENTATION_PREFERENCE);
    end;
    
    end.
    

    You will want to make sure you ONLY call this on Windows 8 since that procedure doesn't exist elsewhere.

    Usage: TMetroDisplayRotation.SetDisplayAutoRotationPreferences(TMetroDisplayRotation.ORIENTATION_PREFERENCE_LANDSCAPE or TMetroDisplayRotation.ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED);

    Another BAD option is to disable it for the entire tablet. Just go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AutoRotation in the registry and change Enable to 0.