.NET 4.x Получение разрешений экрана - C#
Формулировка задачи:
Я пробовал получить разрешения экрана, и написал такой код:
импорт функций WinAPI
Код получения разрешения экрана:
в коде я удалил повторяющиеся элементы. Данный код пишет все доступные разрешения экрана, а монитор 16:9. Возможно ли сделать так, чтобы он выводил поддерживаемые рекомендуемые разрешения экрана, как в стандартном менеджере где его менять (Windows 8.1)
[DllImport("user32.dll")]
public static extern bool EnumDisplaySettings(
string deviceName, int modeNum, ref DEVMODE devMode);
const int ENUM_CURRENT_SETTINGS = -1;
const int ENUM_REGISTRY_SETTINGS = -2;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
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 ScreenOrientation dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int 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;
} DEVMODE vDevMode = new DEVMODE();
int i = 0;
while (EnumDisplaySettings(null, i, ref vDevMode))
{
ScreenResolutin.Items.Add(vDevMode.dmPelsWidth.ToString() + "x" + vDevMode.dmPelsHeight.ToString());
i++;
}
var items = ScreenResolutin.Items.Cast<string>().Distinct().ToArray();
// Очищаем comboBox
ScreenResolutin.Items.Clear();
// Добавляем элементы
ScreenResolutin.Items.AddRange(items);Решение задачи: «.NET 4.x Получение разрешений экрана»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ListResolutions
{
class Program
{
static void Main(string[] args)
{
var vDevModes = Monitor.GetDevmodes();
Console.WriteLine(vDevModes.Count);
foreach (var vDevMode in vDevModes)
{
Console.WriteLine("Width:{0} Height:{1} Color:{2} Frequency:{3}",
vDevMode.dmPelsWidth,
vDevMode.dmPelsHeight,
1 << vDevMode.dmBitsPerPel, vDevMode.dmDisplayFrequency
);
}
Console.WriteLine();
Console.WriteLine("Recommended parameters: ");
var best = vDevModes[vDevModes.Count - 1];
double proportions = (double) best.dmPelsWidth/best.dmPelsHeight;
var results = vDevModes.Where(d => Math.Abs(((double) d.dmPelsWidth/d.dmPelsHeight) - proportions) <= double.Epsilon)
.GroupBy(d => d.dmPelsWidth*d.dmPelsHeight)
.Select(g => g.OrderByDescending(d => d.dmBitsPerPel).ThenBy(d => d.dmDisplayFrequency).First());
foreach (var vDevMode in results)
{
Console.WriteLine("Width:{0} Height:{1} Color:{2} Frequency:{3}",
vDevMode.dmPelsWidth,
vDevMode.dmPelsHeight,
1 << vDevMode.dmBitsPerPel, vDevMode.dmDisplayFrequency
);
}
}
}
public static class Monitor
{
[DllImport("user32.dll")]
public static extern bool EnumDisplaySettings(
string deviceName, int modeNum, ref DEVMODE devMode);
const int ENUM_CURRENT_SETTINGS = -1;
const int ENUM_REGISTRY_SETTINGS = -2;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
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 ScreenOrientation dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int 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;
}
private static readonly Lazy<IReadOnlyList<DEVMODE>> DevModes = new Lazy<IReadOnlyList<DEVMODE>>(ValueFactory);
private static IReadOnlyList<DEVMODE> ValueFactory()
{
var list = new List<DEVMODE>(100);
var vDevMode = new DEVMODE();
for (int i = 0; EnumDisplaySettings(null, i, ref vDevMode); i++)
{
list.Add(vDevMode);
}
list.Sort((d1, d2) =>
{
int color = d1.dmBitsPerPel.CompareTo(d2.dmBitsPerPel);
if (color != 0)
return color;
var resolution = (d1.dmPelsWidth*d1.dmPelsHeight).CompareTo(d2.dmPelsWidth*d2.dmPelsHeight);
if (resolution != 0)
return resolution;
return d1.dmDisplayFrequency.CompareTo(d2.dmDisplayFrequency);
});
return list.AsReadOnly();
}
public static IReadOnlyList<DEVMODE> GetDevmodes()
{
return DevModes.Value;
}
}
}