;--------------------------------------------------------------------------------------------------------------- ; CHANGELOG: ; ; Dec 16 2021: Initial release by Glisense ltd ; ; Current script is designed for use together with Keyboard Extension® (https://keyboardextension.com) ; ; For the latest version, description and licensing terms go to https://keyboardextension.com/plugins/1533ce10 ; ;--------------------------------------------------------------------------------------------------------------- #NoTrayIcon ; Hide tray icon #Persistent ; Keep the script permanently running until it gets terminated info := GetAllDisplaysFrequencies() Names := AhkToJSON(info[1]) Values := AhkToJSON(info[2]) ; MsgBox, % Names . "`n" . Values GetAllDisplaysFrequencies() { static DISPLAY_DEVICE_ATTACHED_TO_DESKTOP := 1 Names := [] Frequencies := [] VarSetCapacity(DISPLAY_DEVICE, size := 8 + 416 * (A_IsUnicode ? 2 : 1)) DeviceNameOffset := &DISPLAY_DEVICE + 4 NumPut(size, DISPLAY_DEVICE) AW := A_IsUnicode ? "W" : "A" i := 0 while DllCall("EnumDisplayDevices", "Ptr", 0, "UInt", A_Index - 1, "Ptr", &DISPLAY_DEVICE, "UInt", 0) { if !(NumGet(DeviceNameOffset + (32 + 128)*(A_IsUnicode ? 2 : 1), "UInt") & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) continue ; MsgBox, % StrGet(DeviceNameOffset) Names.Push({id: ++i, value: StrGet(DeviceNameOffset + (32 + 128)*(A_IsUnicode ? 2 : 1) + 4)}) Frequencies.Push({id: i, value: GetDisplayFrequency(DeviceNameOffset)}) } Return [Names, Frequencies] } GetDisplayFrequency(pName := 0) { static DM_DISPLAYFREQUENCY := 0x400000, ENUM_CURRENT_SETTINGS := -1 size := A_IsUnicode ? 220 : 156 dmSizeOffset := A_IsUnicode ? 68 : 36 dmDisplayFrequencyOffset := A_IsUnicode ? 184 : 120 VarSetCapacity(DEVMODE, size, 0) NumPut(size, &DEVMODE + dmSizeOffset) NumPut(DM_DISPLAYFREQUENCY, &DEVMODE + dmSizeOffset + 4) DllCall("EnumDisplaySettings", "Ptr", pName, "UInt", ENUM_CURRENT_SETTINGS, "Ptr", &DEVMODE) Return NumGet(&DEVMODE + dmDisplayFrequencyOffset, "UInt") } AhkToJSON(obj, indent := "") { static Doc, JS if !Doc { Doc := ComObjCreate("htmlfile") Doc.write("") JS := Doc.parentWindow ( Doc.documentMode < 9 && JS.execScript() ) } if indent|1 { if IsObject( obj ) { isArray := true for key in obj { if IsObject(key) throw Exception("Invalid key") if !( key = A_Index || isArray := false ) break } for k, v in obj str .= ( A_Index = 1 ? "" : "," ) . ( isArray ? "" : %A_ThisFunc%(k, true) . ":" ) . %A_ThisFunc%(v, true) Return isArray ? "[" str "]" : "{" str "}" } else if !(obj*1 = "" || RegExMatch(obj, "^-?0(?=[^.])|\s")) Return obj for k, v in [["\", "\\"], [A_Tab, "\t"], ["""", "\"""], ["/", "\/"], ["`n", "\n"], ["`r", "\r"], [Chr(12), "\f"], [Chr(8), "\b"]] obj := StrReplace( obj, v[1], v[2] ) Return """" obj """" } sObj := %A_ThisFunc%(obj, true) Return JS.eval("JSON.stringify(" . sObj . ",'','" . indent . "')") }