WinGDI Get All supported Monitor Resolutions
#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