问题
Is it possible to change the orientation of the Windows 8.1 or Windows 7 desktops through C# program.. like from landscape to portrait if i select it from my application.?
I know we can get the information of width and height of the screens from Screen class in System.Windows.Forms namespace.
But, Is there any API which i can call to change the orientation.
回答1:
There is one solution provided in MSDN
I have used the same piece of code for WPF. Below is the code
View.xaml
<Window x:Class="ScreenOrientation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Horizontal" MaxHeight="55px" VerticalAlignment="Top">
<Label Content="Change Orientation" Margin="5"></Label>
<Button Content="Rotate Clock Wise" Margin="5" x:Name="BtnClockwise" Click="BtnClockwise_OnClick"></Button>
<Button Content="Rotate Anti Clock Wise" Margin="5" x:Name="BtnAntiClock" Click="BtnAntiClock_OnClick"></Button>
</StackPanel>
</Window>
Code Behind
public partial class MainWindow : Window
{
private int[] orientationValues = new int[4]{NativeMethods.DMDO_DEFAULT,
NativeMethods.DMDO_90,
NativeMethods.DMDO_180,
NativeMethods.DMDO_270};
public MainWindow()
{
InitializeComponent();
}
private void BtnClockwise_OnClick(object sender, RoutedEventArgs e)
{
// obtain current settings
DEVMODE dm = NativeMethods.CreateDevmode();
GetSettings(ref dm);
// swap height and width
int temp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = temp;
// set the orientation value to what's next anti-clockwise
int index = Array.IndexOf(orientationValues, (object)dm.dmDisplayOrientation);
int newIndex = (index == 3) ? 0 : index + 1;
dm.dmDisplayOrientation = orientationValues[newIndex];
// switch to new settings
ChangeSettings(dm);
}
private void BtnAntiClock_OnClick(object sender, RoutedEventArgs e)
{
// obtain current settings
DEVMODE dm = NativeMethods.CreateDevmode();
GetSettings(ref dm);
// swap height and width
int temp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = temp;
// set the orientation value to what's next anti-clockwise
int index = Array.IndexOf(orientationValues, (object)dm.dmDisplayOrientation);
int newIndex = (index == 3) ? 0 : index + 1;
dm.dmDisplayOrientation = orientationValues[newIndex];
// switch to new settings
ChangeSettings(dm);
}
private int GetSettings(ref DEVMODE dm)
{
// helper to obtain current settings
return GetSettings(ref dm, NativeMethods.ENUM_CURRENT_SETTINGS);
}
private int GetSettings(ref DEVMODE dm, int iModeNum)
{
// helper to wrap EnumDisplaySettings Win32 API
return NativeMethods.EnumDisplaySettings(null, iModeNum, ref dm);
}
private void ChangeSettings(DEVMODE dm)
{
// helper to wrap ChangeDisplaySettings Win32 API
int iRet = NativeMethods.ChangeDisplaySettings(ref dm, 0);
switch (iRet)
{
case NativeMethods.DISP_CHANGE_SUCCESSFUL:
break;
case NativeMethods.DISP_CHANGE_RESTART:
MessageBox.Show("Please restart your system");
break;
case NativeMethods.DISP_CHANGE_FAILED:
MessageBox.Show("ChangeDisplaySettigns API failed");
break;
case NativeMethods.DISP_CHANGE_BADDUALVIEW:
MessageBox.Show("The settings change was unsuccessful because system is DualView capable.");
break;
case NativeMethods.DISP_CHANGE_BADFLAGS:
MessageBox.Show("An invalid set of flags was passed in.");
break;
case NativeMethods.DISP_CHANGE_BADPARAM:
MessageBox.Show("An invalid parameter was passed in. This can include an invalid flag or combination of flags.");
break;
case NativeMethods.DISP_CHANGE_NOTUPDATED:
MessageBox.Show("Unable to write settings to the registry.");
break;
default:
MessageBox.Show("Unknown return value from ChangeDisplaySettings API");
break;
}
}
}
The DEVMOD Struct
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public int dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string dmFormName;
public short dmLogPixels;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
};
public class NativeMethods
{
// PInvoke declaration for EnumDisplaySettings Win32 API
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern int EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);
// PInvoke declaration for ChangeDisplaySettings Win32 API
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern int ChangeDisplaySettings(ref DEVMODE lpDevMode, int dwFlags);
// helper for creating an initialized DEVMODE structure
public static DEVMODE CreateDevmode()
{
DEVMODE dm = new DEVMODE();
dm.dmDeviceName = new String(new char[32]);
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
return dm;
}
// constants
public const int ENUM_CURRENT_SETTINGS = -1;
public const int DISP_CHANGE_SUCCESSFUL = 0;
public const int DISP_CHANGE_BADDUALVIEW = -6;
public const int DISP_CHANGE_BADFLAGS = -4;
public const int DISP_CHANGE_BADMODE = -2;
public const int DISP_CHANGE_BADPARAM = -5;
public const int DISP_CHANGE_FAILED = -1;
public const int DISP_CHANGE_NOTUPDATED = -3;
public const int DISP_CHANGE_RESTART = 1;
public const int DMDO_DEFAULT = 0;
public const int DMDO_90 = 1;
public const int DMDO_180 = 2;
public const int DMDO_270 = 3;
}
来源:https://stackoverflow.com/questions/28144735/change-orientation-of-windows-8-1-desktop-from-c-sharp-wpf