Как изменить разрешение экрана? - C#
Формулировка задачи:
Есть ли какая-нибудь функция для выставления разрешения экрана, а так же функция, выставляющая ближайшее приемлемое разрешение экрана с нужным соотношением?
Решение задачи: «Как изменить разрешение экрана?»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace LibraryCMS
{
public static class ScreenAPI
{
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumDisplayDevices(
[In] string lpszDeviceName,
[In] uint iDevNum,
[In][Out] ref DISPLAY_DEVICE lpDisplayDevice,
[In] uint dwFlags);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumDisplaySettingsExW(
[In] string lpszDeviceName,
[In] uint iModeNum,
[Out] out DEVMODE lpDevMode,
[In] uint dwFlags);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int ChangeDisplaySettingsExW(
[In] string lpszDeviceName,
[In] ref DEVMODE lpDevMode,
IntPtr hwnd,
[In] uint dwflags,
[In] IntPtr lParam);
[DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32.dll")]
static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
[DllImport("gdi32.dll", SetLastError = true)]
static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
static extern IntPtr CreateBitmap(int nWidth, int nHeight, uint cPlanes, uint cBitsPerPel, IntPtr lpvBits);
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll")]
static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
public struct DISPLAY_DEVICE
{
public uint cb;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] DeviceName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public char[] DeviceString;
public int StateFlags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public char[] DeviceID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public char[] DeviceKey;
}
// for ChangeDisplaySettingsEx:
const uint CDS_UPDATEREGISTRY = 0x1;
const uint CDS_RESET = 0x40000000;
// for EnumDisplaySettingsEx:
const uint ENUM_CURRENT_SETTINGS = uint.MaxValue;
const uint ENUM_REGISTRY_SETTINGS = uint.MaxValue - 1;
public enum DM_ : uint
{
SPECVERSION = 0x0401,
ORIENTATION = 0x00000001,
PAPERSIZE = 0x00000002,
PAPERLENGTH = 0x00000004,
PAPERWIDTH = 0x00000008,
SCALE = 0x00000010,
POSITION = 0x00000020,
NUP = 0x00000040,
DISPLAYORIENTATION = 0x00000080,
COPIES = 0x00000100,
DEFAULTSOURCE = 0x00000200,
PRINTQUALITY = 0x00000400,
COLOR = 0x00000800,
DUPLEX = 0x00001000,
YRESOLUTION = 0x00002000,
TTOPTION = 0x00004000,
COLLATE = 0x00008000,
FORMNAME = 0x00010000,
LOGPIXELS = 0x00020000,
BITSPERPEL = 0x00040000,
PELSWIDTH = 0x00080000,
PELSHEIGHT = 0x00100000,
DISPLAYFLAGS = 0x00200000,
DISPLAYFREQUENCY = 0x00400000,
ICMMETHOD = 0x00800000,
ICMINTENT = 0x01000000,
MEDIATYPE = 0x02000000,
DITHERTYPE = 0x04000000,
PANNINGWIDTH = 0x08000000,
PANNINGHEIGHT = 0x10000000,
DISPLAYFIXEDOUTPUT = 0x20000000
}
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 220)]
public struct DEVMODE
{
[FieldOffset(68)]
public ushort dmSize;
[FieldOffset(72)]
public DM_ dmFields;
[FieldOffset(76)]
public POINTL dmPosition;
[FieldOffset(84)]
public uint dmDisplayOrientation;
[FieldOffset(168)]
public uint dmBitsPerPel;
[FieldOffset(172)]
public uint dmPelsWidth;
[FieldOffset(176)]
public uint dmPelsHeight;
[FieldOffset(180)]
public uint dmDisplayFlags;
[FieldOffset(184)]
public uint dmDisplayFrequency;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINTL
{
public int X;
public int Y;
}
public enum TernaryRasterOperations : uint
{
/// <summary>dest = source</summary>
SRCCOPY = 0x00CC0020,
/// <summary>dest = source OR dest</summary>
SRCPAINT = 0x00EE0086,
/// <summary>dest = source AND dest</summary>
SRCAND = 0x008800C6,
/// <summary>dest = source XOR dest</summary>
SRCINVERT = 0x00660046,
/// <summary>dest = source AND (NOT dest)</summary>
SRCERASE = 0x00440328,
/// <summary>dest = (NOT source)</summary>
NOTSRCCOPY = 0x00330008,
/// <summary>dest = (NOT src) AND (NOT dest)</summary>
NOTSRCERASE = 0x001100A6,
/// <summary>dest = (source AND pattern)</summary>
MERGECOPY = 0x00C000CA,
/// <summary>dest = (NOT source) OR dest</summary>
MERGEPAINT = 0x00BB0226,
/// <summary>dest = pattern</summary>
PATCOPY = 0x00F00021,
/// <summary>dest = DPSnoo</summary>
PATPAINT = 0x00FB0A09,
/// <summary>dest = pattern XOR dest</summary>
PATINVERT = 0x005A0049,
/// <summary>dest = (NOT dest)</summary>
DSTINVERT = 0x00550009,
/// <summary>dest = BLACK</summary>
BLACKNESS = 0x00000042,
/// <summary>dest = WHITE</summary>
WHITENESS = 0x00FF0062
}
public static int GetScreenCount()
{
return System.Windows.Forms.Screen.AllScreens.Length;
}
public static List<DISPLAY_DEVICE> GetAllDisplayDevices()
{
List<DISPLAY_DEVICE> listAllDevices = new List<DISPLAY_DEVICE>();
DISPLAY_DEVICE displayDevice = new DISPLAY_DEVICE();
for (uint i = 0; i < System.Windows.Forms.Screen.AllScreens.Length; i++)
{
displayDevice.cb = 714;
EnumDisplayDevices(System.Windows.Forms.Screen.AllScreens[i].DeviceName, i, ref displayDevice, 0);
listAllDevices.Add(displayDevice);
}
return listAllDevices;
}
public static DEVMODE GetCurrentScreenMode(int screenIndex)
{
DEVMODE devmode = new DEVMODE();
devmode.dmSize = (ushort)Marshal.SizeOf(typeof(DEVMODE));
EnumDisplaySettingsExW(System.Windows.Forms.Screen.AllScreens[screenIndex].DeviceName, ENUM_CURRENT_SETTINGS, out devmode, 0);
return devmode;
}
public static List<DEVMODE> GetAllScreenMode(int screenIndex)
{
List<DEVMODE> listAllScreenMode = new List<DEVMODE>();
uint i = 0;
DEVMODE devmode = new DEVMODE();
devmode.dmSize = (ushort)Marshal.SizeOf(typeof(DEVMODE));
while (EnumDisplaySettingsExW(System.Windows.Forms.Screen.AllScreens[screenIndex].DeviceName, i, out devmode, 0))
{
listAllScreenMode.Add(devmode);
i++;
}
listAllScreenMode.Sort((x, y) => x.dmPelsWidth < y.dmPelsWidth ? -1 : x.dmPelsWidth > y.dmPelsWidth ? 1 : x.dmPelsHeight < y.dmPelsHeight ? -1 : x.dmPelsHeight > y.dmPelsHeight ? 1 : x.dmBitsPerPel < y.dmBitsPerPel ? -1 : x.dmBitsPerPel > y.dmBitsPerPel ? 1 : x.dmDisplayFrequency < y.dmDisplayFrequency ? -1 : x.dmDisplayFrequency > y.dmDisplayFrequency ? 1 : 0);
int k = 0;
while (k < listAllScreenMode.Count - 1)
{
if (listAllScreenMode[k].dmPelsWidth == listAllScreenMode[k + 1].dmPelsWidth && listAllScreenMode[k].dmPelsHeight == listAllScreenMode[k + 1].dmPelsHeight && listAllScreenMode[k].dmBitsPerPel == listAllScreenMode[k + 1].dmBitsPerPel && listAllScreenMode[k].dmDisplayFrequency == listAllScreenMode[k + 1].dmDisplayFrequency)
{
listAllScreenMode.RemoveAt(k);
}
else
{
k++;
}
}
return listAllScreenMode;
}
public static void ChangeDisplaySetting(int screenIndex, DEVMODE devMode)
{
devMode.dmSize = (ushort)Marshal.SizeOf(typeof(DEVMODE));
devMode.dmFields = DM_.BITSPERPEL | DM_.PELSWIDTH | DM_.PELSHEIGHT | DM_.DISPLAYFREQUENCY;
ChangeDisplaySettingsExW(System.Windows.Forms.Screen.AllScreens[screenIndex].DeviceName, ref devMode, IntPtr.Zero, CDS_UPDATEREGISTRY, IntPtr.Zero);
}
}
}