Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

Laptop Screen Brightness


  • Please log in to reply
6 replies to this topic
jkiel
  • Guests
  • Last active:
  • Joined: --
Not wanting to take the time to understand Autohotkey variable scopes, this is a bit of a hack.

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)
	
	}

}


jkiel
  • Guests
  • Last active:
  • Joined: --
One problem with this method:

It appears that, while IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS still works on most systems, it is deprecated, and on many it will not return the full brightness settings array. So, where you should have 8 levels, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS will only return 6, or none at all.

For this reason, it looks like I'd need to use WmiMonitorBrightness and WmiMonitorBrightnessMethods.WmiSetBrightness to query and set the brightness. WmiMonitorBrightness isn't a problem, I understand how to do that in AHK, but WmiSetBrightness is. I can't wrap my head around how to call that method from AHK.

If anyone knows how, please help me out over here.

  • Guests
  • Last active:
  • Joined: --

It appears that, while IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS still works on most systems, it is deprecated, and on many it will not return the full brightness settings array. So, where you should have 8 levels, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS will only return 6, or none at all.


Sorry, meant to say "IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS" here, not "IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS".

Sherman
  • Members
  • 52 posts
  • Last active:
  • Joined: 06 Jan 2013

Did you ever figure this out and get the code updated?



torman
  • Members
  • 1 posts
  • Last active: Apr 09 2013 07:19 PM
  • Joined: 05 Apr 2013

i jkiel,

I'm looking to modify this script slightly so that I can specify a number between 0 and 100 as mentioned by Microsoft here:

http://msdn.microsof...6(v=vs.85).aspx

 

I had an EeePc with a program someone wrote that managed to change the brightness in 1% increments, and windows 8 natively does that on my HP. So now I'm trying to get this type of thing to work on a Lenovo and a Dell.

 

I'm a bit of a coding noob, but from what I see you query the array of supported values and just increment the index from one supported value to the next.

 

I'd like to ignore whatever is "supported" and just pass values of 0 to 100 to see how it reacts. Any idea how I could modify your script to do that?

 

Thanks for the help and the great script!!

 

- Tor



aakif
  • Members
  • 1 posts
  • Last active: Apr 10 2013 06:21 PM
  • Joined: 10 Apr 2013

hello friend...you solved my problem..thanks, and appreciation!!!

 

I also have a Series 3 Samsung Notebook.

And your script works as is on my laptop.

 

PLEASE PLEASE help me with Brightness toggle as well.

Until Windows 7 things used to work. I had to install Samsung Easy Settings. Pressing Fn+F12 and it turned launched a Wifi and Bluetooth Toggle utility.

 

Can you help me configure Fn+F12 to toggle WiFi

and Fn+F_ for Bluetooh?

 

PLEASE JKIEL, It would be a great favour from your side.

 

 

Regards.



chaz
  • Members
  • 192 posts
  • Last active: Oct 01 2015 02:42 AM
  • Joined: 26 Mar 2013

Works for me. My Acer Aspire One netbook has an FN key on the left side of the keyboard and backlight up/down on the arrow keys, but in order to use them it requires both hands. With this I have set the function to the AppsKey & Left/Right (AppsKey is the modifier) so I can reach it with one hand.

 

It appears that, while IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS still works on most systems, it is deprecated, and on many it will not return the full brightness settings array. So, where you should have 8 levels, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS will only return 6, or none at all.

Originally my backlight had 10 levels and this does too, so no problems there.

 

 

Like so:

AppsKey & Right::MoveBrightness(1)
AppsKey & Left::MoveBrightness(-1)
AppsKey::Send {AppsKey}		;<<Without this the AppsKey wouldn't function.

Of course you need to have the MoveBrightness() function at the bottom of the script or included with #Include.


Find me at the other forum as timeFlies.