Created
September 30, 2017 00:30
-
-
Save talyian/6dccaf523c9a9cda9a32ab73d76e98e7 to your computer and use it in GitHub Desktop.
WinGDI Get All supported Monitor Resolutions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#nowarn "9" | |
open System | |
open System.Runtime.InteropServices | |
[<StructLayout(LayoutKind.Sequential)>] | |
type DEVMODEInfo = struct | |
[<MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)>] | |
[<DefaultValue>] val mutable dmDeviceName : string | |
[<DefaultValue>] val mutable dmSpecVersion: int16; | |
[<DefaultValue>] val mutable dmDriverVersion: int16; | |
[<DefaultValue>] val mutable dmSize: int16; | |
[<DefaultValue>] val mutable dmDriverExtra: int16; | |
[<DefaultValue>] val mutable dmFields: int; | |
// [<DefaultValue>] val mutable dmOrientation: int16; | |
// [<DefaultValue>] val mutable dmPaperSize: int16; | |
// [<DefaultValue>] val mutable dmPaperLength: int16; | |
// [<DefaultValue>] val mutable dmPaperWidth: int16; | |
// [<DefaultValue>] val mutable dmScale: int16; | |
// [<DefaultValue>] val mutable dmCopies: int16; | |
// [<DefaultValue>] val mutable dmDefaultSource: int16; | |
// [<DefaultValue>] val mutable dmPrintQuality: int16; | |
[<DefaultValue>] val mutable dmPositionX: int; | |
[<DefaultValue>] val mutable dmPositionY: int; | |
[<DefaultValue>] val mutable dmDisplayOrientation: int; | |
[<DefaultValue>] val mutable dmDisplayFixedOutput: int; | |
[<DefaultValue>] val mutable dmColor: int16; | |
[<DefaultValue>] val mutable dmDuplex: int16; | |
[<DefaultValue>] val mutable dmYResolution: int16; | |
[<DefaultValue>] val mutable dmTTOption: int16; | |
[<DefaultValue>] val mutable dmCollate: int16; | |
[<MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)>] | |
[<DefaultValue>] val mutable dmFormName : string; | |
[<DefaultValue>] val mutable dmLogPixels: int16; | |
[<DefaultValue>] val mutable dmBitsPerPel: int16; | |
[<DefaultValue>] val mutable dmPelsWidth: int; | |
[<DefaultValue>] val mutable dmPelsHeight: int; | |
[<DefaultValue>] val mutable dmDisplayFlags: int; | |
[<DefaultValue>] val mutable dmDisplayFrequency: int; | |
[<DefaultValue>] val mutable dmICMMethod: int; | |
[<DefaultValue>] val mutable dmICMIntent: int; | |
[<DefaultValue>] val mutable dmMediaType: int; | |
[<DefaultValue>] val mutable dmDitherType: int; | |
[<DefaultValue>] val mutable dmReserved1: int; | |
[<DefaultValue>] val mutable dmReserved2: int; | |
[<DefaultValue>] val mutable dmPanningWidth: int; | |
[<DefaultValue>] val mutable dmPanningHeight: int; | |
new (device: string, form: string) = { } | |
end | |
[<StructLayout(LayoutKind.Sequential)>] | |
type DisplayDeviceInfo = struct | |
static member size = Marshal.SizeOf<DisplayDeviceInfo>() | |
[<DefaultValue>] val mutable cb: int; | |
[<MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)>] | |
[<DefaultValue>] val mutable deviceName : string | |
[<MarshalAs(UnmanagedType.ByValArray, SizeConst=128)>] | |
[<DefaultValue>] val mutable deviceString : char[] | |
[<DefaultValue>] val mutable stateFlags: int; | |
[<MarshalAs(UnmanagedType.ByValArray, SizeConst=128)>] | |
[<DefaultValue>] val mutable deviceID : char[] | |
[<MarshalAs(UnmanagedType.ByValArray, SizeConst=128)>] | |
[<DefaultValue>] val mutable deviceKey : char[] | |
end | |
[<DllImport("User32.dll")>] | |
extern bool EnumDisplaySettings(string displayName, int mode, DEVMODEInfo& output); | |
[<DllImport("User32.dll")>] | |
extern bool EnumDisplayDevices(string device, int devNum, DisplayDeviceInfo& displayDevice, int flags); | |
let getdevice name i = | |
let mutable device = DisplayDeviceInfo(cb=DisplayDeviceInfo.size) | |
match EnumDisplayDevices(name, i, &device, 1) with | false -> None | _ -> Some(device) | |
[<Flags>] | |
type MonitorFlags = | |
| Active = 1 | |
| MultiDriver = 2 | |
| Primary = 4 | |
| MirroringDriver = 8 | |
| VGACompatible = 16 | |
| Removable = 32 | |
| ModesPruned = 0x8000000 | |
| Remote = 0x4000000 | |
| Disconnect = 0x2000000 | |
type DisplayOrientation = | |
| Default = 0 | |
| Rotate90 = 1 | |
| Rotate180 = 2 | |
| Rotate270 = 3 | |
type DisplayFixedOutput = | |
| Default = 0 | |
| Stretch = 1 | |
| Center = 2 | |
type DisplayMode(dm : DEVMODEInfo) = | |
member val Name = dm.dmDeviceName | |
member val Height = dm.dmPelsHeight | |
member val Width = dm.dmPelsWidth | |
member val BitsPerPel = dm.dmBitsPerPel | |
member val FPS = dm.dmDisplayFrequency | |
member val Orientation : DisplayOrientation = enum dm.dmDisplayOrientation | |
member val FixedOutput : DisplayFixedOutput = enum dm.dmDisplayFixedOutput | |
override this.ToString() = | |
String.concat ", " [for p in typeof<DisplayMode>.GetProperties() -> sprintf "%s: %O" p.Name (p.GetValue(this, null))] | |
let getDisplayInfo display index = | |
let mutable dm = | |
DEVMODEInfo( | |
dmDeviceName = String.replicate 30 " ", | |
dmFormName = String.replicate 30 " ", | |
dmSize = int16 sizeof<DEVMODEInfo>) | |
match EnumDisplaySettings(display, index, &dm) with | false -> None | _ -> Some(DisplayMode(dm)) | |
type Monitor(name, flags) = | |
member val Name : string = name | |
member val Flags : MonitorFlags = enum flags | |
type DisplayDevice(name, flags) = | |
member val Name : string = name | |
member val Flags : MonitorFlags = enum flags | |
member this.Monitors | |
with get () = List.unfold (fun i -> getdevice name i |> Option.map (fun dw -> (Monitor(dw.deviceName, dw.stateFlags), i + 1))) 0 | |
member this.Modes | |
with get() = List.unfold (fun i -> getDisplayInfo name i |> Option.map (fun dw -> (dw, i + 1))) 0 | |
static member All | |
with get() = List.unfold (fun i -> getdevice null i |> Option.map (fun dw -> (DisplayDevice(dw), i + 1))) 0 | |
new(info : DisplayDeviceInfo) = DisplayDevice(info.deviceName, info.stateFlags) | |
for dv in DisplayDevice.All do | |
printfn "%O %A" dv.Name dv.Flags | |
for m in dv.Monitors do | |
printfn " %A %A" m.Name m.Flags | |
for m in dv.Modes do | |
printfn "%O" m |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment