Most/all of the screen brightness AHK scripts I've found using IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS seem to assume that the supported brightness is always a multiple of 10, between 0 and 100. This is not the case with all notebooks, like my SAMSUNG, for example. This following script first gets the supported and current screen brightness before adjusting it up/down.
I forget the exact script I modified this from, but most of them used the same basic code for controlling IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS. I've just extended it to query IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS and IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS. Sorry for not giving credit where due.
Like I said, it's a bit of a hack, and could certainly be optimized.
Current hotkeys are set for my SAMSUNG brightness keys. Adjust as needed.
#NoEnv #AllowSameLineComments #SingleInstance force #InstallKeybdHook ;#NoTrayIcon SetWorkingDir %A_ScriptDir% SendMode, Input SC108:: ; SAMSUNG brightness up FN key MoveBrightness(1) return SC109:: ; SAMSUNG brightness down FN key MoveBrightness(-1) return ;#a:: ;MoveBrightness(1) ;return ;#z:: ;MoveBrightness(-1) ;return ;############################################################################ ; Functions ;############################################################################ MoveBrightness(IndexMove) { VarSetCapacity(SupportedBrightness, 256, 0) VarSetCapacity(SupportedBrightnessSize, 4, 0) VarSetCapacity(BrightnessSize, 4, 0) VarSetCapacity(Brightness, 3, 0) hLCD := DllCall("CreateFile" , Str, "\\.\LCD" , UInt, 0x80000000 | 0x40000000 ;Read | Write , UInt, 0x1 | 0x2 ; File Read | File Write , UInt, 0 , UInt, 0x3 ; open any existing file , UInt, 0 , UInt, 0) if hLCD != -1 { DevVideo := 0x00000023, BuffMethod := 0, Fileacces := 0 NumPut(0x03, Brightness, 0, "UChar") ; 0x01 = Set AC, 0x02 = Set DC, 0x03 = Set both NumPut(0x00, Brightness, 1, "UChar") ; The AC brightness level NumPut(0x00, Brightness, 2, "UChar") ; The DC brightness level DllCall("DeviceIoControl" , UInt, hLCD , UInt, (DevVideo<<16 | 0x126<<2 | BuffMethod<<14 | Fileacces) ; IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS , UInt, 0 , UInt, 0 , UInt, &Brightness , UInt, 3 , UInt, &BrightnessSize , UInt, 0) DllCall("DeviceIoControl" , UInt, hLCD , UInt, (DevVideo<<16 | 0x125<<2 | BuffMethod<<14 | Fileacces) ; IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS , UInt, 0 , UInt, 0 , UInt, &SupportedBrightness , UInt, 256 , UInt, &SupportedBrightnessSize , UInt, 0) ACBrightness := NumGet(Brightness, 1, "UChar") ACIndex := 0 DCBrightness := NumGet(Brightness, 2, "UChar") DCIndex := 0 BufferSize := NumGet(SupportedBrightnessSize, 0, "UInt") MaxIndex := BufferSize-1 Loop, %BufferSize% { ThisIndex := A_Index-1 ThisBrightness := NumGet(SupportedBrightness, ThisIndex, "UChar") if ACBrightness = %ThisBrightness% ACIndex := ThisIndex if DCBrightness = %ThisBrightness% DCIndex := ThisIndex } if DCIndex >= %ACIndex% BrightnessIndex := DCIndex else BrightnessIndex := ACIndex BrightnessIndex += IndexMove if BrightnessIndex > %MaxIndex% BrightnessIndex := MaxIndex if BrightnessIndex < 0 BrightnessIndex := 0 NewBrightness := NumGet(SupportedBrightness, BrightnessIndex, "UChar") NumPut(0x03, Brightness, 0, "UChar") ; 0x01 = Set AC, 0x02 = Set DC, 0x03 = Set both NumPut(NewBrightness, Brightness, 1, "UChar") ; The AC brightness level NumPut(NewBrightness, Brightness, 2, "UChar") ; The DC brightness level DllCall("DeviceIoControl" , UInt, hLCD , UInt, (DevVideo<<16 | 0x127<<2 | BuffMethod<<14 | Fileacces) ; IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS , UInt, &Brightness , UInt, 3 , UInt, 0 , UInt, 0 , UInt, 0 , Uint, 0) DllCall("CloseHandle", UInt, hLCD) } }