The required API functions are available with all versions of Windows.
system_path = %A_WinDir%\system if ( A_OSType != WIN32_WINDOWS ) system_path = %system_path%32 id_image_list := IL_Create( 1, 0, 0 ) IL_Add( id_image_list, system_path "\shell32.dll", 131 ) Gui, Add, ListView, x5 y5 w280 h200 grid gChangeDisplayMode, |width|height|quality (bits)|frequency (Hz) Gui, Show, x50 y50 w290 h210, Change Display Mode LV_SetImageList( id_image_list, 1 ) Gui, +LastFound struct_devicemode_size = 156 VarSetCapacity( device_mode, struct_devicemode_size, 0 ) EncodeInteger( struct_devicemode_size, 2, &device_mode, 36 ) ; ENUM_CURRENT_SETTINGS success := DllCall( "EnumDisplaySettings", "uint", 0, "uint", -1, "uint", &device_mode ) current?width := DecodeInteger( "uint4", &device_mode, 108, false ) current?height := DecodeInteger( "uint4", &device_mode, 112, false ) current?quality := DecodeInteger( "uint4", &device_mode, 104, false ) current?frequency := DecodeInteger( "uint4", &device_mode, 120, false ) loop, { success := DllCall( "EnumDisplaySettings", "uint", 0, "uint", A_Index-1, "uint", &device_mode ) if ( ErrorLevel or !success ) break mode?width := DecodeInteger( "uint4", &device_mode, 108, false ) mode?height := DecodeInteger( "uint4", &device_mode, 112, false ) mode?quality := DecodeInteger( "uint4", &device_mode, 104, false ) mode?frequency := DecodeInteger( "uint4", &device_mode, 120, false ) if ( mode?width = current?width and mode?height = current?height and mode?quality = current?quality and mode?frequency = current?frequency ) options = Focus Icon1 Select else options = Icon0 LV_Add( options, "", mode?width, mode?height, mode?quality, mode?frequency ) } loop, 5 LV_ModifyCol( A_Index, "AutoHdr Integer" ) LV_ModifyCol( 2, "Sort" ) current?index := LV_GetNext() ; LVM_ENSUREVISIBLE SendMessage, 0x1000+19, current?index-1, false, SysListView321 return GuiClose: ExitApp ChangeDisplayMode: if ( A_GuiEvent != "DoubleClick" ) return ; DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY EncodeInteger( 0x00040000|0x00080000|0x00100000|0x00400000, 4, &device_mode, 40 ) LV_GetText( value, A_EventInfo, 4 ) EncodeInteger( value, 4, &device_mode, 104 ) LV_GetText( value, A_EventInfo, 2 ) EncodeInteger( value, 4, &device_mode, 108 ) LV_GetText( value, A_EventInfo, 3 ) EncodeInteger( value, 4, &device_mode, 112 ) LV_GetText( value, A_EventInfo, 5 ) EncodeInteger( value, 4, &device_mode, 120 ) ; 0 = change mode dynamically ; 2 = test if mode is valid ; 1 = 0+update user profile in registry result := DllCall( "ChangeDisplaySettings", "uint", &device_mode, "uint", 0 ) if ( ErrorLevel ) MsgBox, [ChangeDisplaySettings] failure: EL = %ErrorLevel% else { if ( result = 0 ) { LV_Modify( current?index, "Icon0" ) current?index := A_EventInfo LV_Modify( current?index, "Icon1" ) result = DISP_CHANGE_SUCCESSFUL } else if ( result = 1 ) result = DISP_CHANGE_RESTART else if ( result = -1 ) result = DISP_CHANGE_FAILED else if ( result = -2 ) result = DISP_CHANGE_BADMODE else if ( result = -3 ) result = DISP_CHANGE_NOTUPDATED else if ( result = -4 ) result = DISP_CHANGE_BADFLAGS else if ( result = -5 ) result = DISP_CHANGE_BADPARAM else if ( result = -6 ) result = DISP_CHANGE_BADDUALVIEW MsgBox, 0, Change Display Mode, %result%, 2 } return DecodeInteger( p_type, p_address, p_offset, p_hex=true ) { old_FormatInteger := A_FormatInteger if ( p_hex ) SetFormat, Integer, hex else SetFormat, Integer, dec sign := InStr( p_type, "u", false )^1 StringRight, size, p_type, 1 loop, %size% value += ( *( ( p_address+p_offset )+( A_Index-1 ) ) << ( 8*( A_Index-1 ) ) ) if ( sign and size <= 4 and *( p_address+p_offset+( size-1 ) ) & 0x80 ) value := -( ( ~value+1 ) & ( ( 2**( 8*size ) )-1 ) ) SetFormat, Integer, %old_FormatInteger% return, value } EncodeInteger( p_value, p_size, p_address, p_offset ) { loop, %p_size% DllCall( "RtlFillMemory" , "uint", p_address+p_offset+A_Index-1 , "uint", 1 , "uchar", ( p_value >> ( 8*( A_Index-1 ) ) ) & 0xFF ) }