Set laptop brightness & show Win 10's native OSD

Post your working scripts, libraries and tools
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Set laptop brightness & show Win 10's native OSD

15 Jan 2017, 12:26

Not particularly impressive considering some of the stuff you can find here, but I actually had a need for something like this, wanting to control my laptop's brightness from my phone using Unified Remote.

On Windows 10, it will set the laptop's monitor brightness and show the brightness OSD present there.

Showing the OSD might be a bit iffy, however:
  • On Windows 10, the OSD window responds to a SHELLHOOK message to show the OSD on demand. However, the window to send said message to doesn't exist until it's created by pressing the brightness/volume buttons (the former only available physically), or if an undocumented function provided by the shell over COM is called. To create the window if needed, this tries the latter first and then falls back to quickly muting/unmuting the volume. I suspect with every new Windows 10 service pack major update, the GUIDs needed to call the COM method will change, like how they did for the IPolicyConfig interface and "IVirtualDesktopManagerInternal". The SID and IID is correct for 14393.693.
  • On Windows 8, I'm hoping the behaviour is the same, but I haven't checked
  • On Windows 7, there is no OSD to speak of

To use, paste the contents of the Gist into your file or save the raw contents of the Gist as something like, say, BrightnessSetter.ahk in a default AutoHotkey library folder. And then do something like this:

Code: [Select all] [Download] (BrightnessSetterSample.ahk)GeSHi © Codebox Plus

#include <BrightnessSetter> ; if you saved the class as its own file
BrightnessSetter.SetBrightness(-10)


If an own instance of the BrightnessSetter class is created, then it will monitor the AC insertion state. That's optional, however.

There's really only one method that actually does anything, the SetBrightness method. Its parameters:
  • increment - how much to increase or decrease the current brightness by. If jump is set, then increment is considered to be an absolute value
  • jump - sets the brightness directly instead of working relatively with the current brightness value. False by default
  • showOSD - determines if the OSD should be shown. To match the behaviour of the physical brightness keys, BrightnessSetter shows the OSD regardless of whether the brightness was actually changed. True by default
  • autoDcOrAc - set to -1 if you want BrightnessSetter to determine the power source and set the brightness for the active power source, 0 if you want the brightness value for when battery power is active to be changed, and 1 for the brightness value when a charger is plugged in. -1 by default
  • forceDifferentScheme - by default, BrightnessSetter works on the active power plan. If you want the brightness for a non-active power plan to be set, you can pass a pointer to the appropriate GUID structure for it. Linear Spoon has an excellent post here on using PowerEnumerate to get all the power plans on the system along with their GUIDs. 0 by default to force using the active scheme

Credits:

User avatar
jeeswg
Posts: 4760
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Set laptop brightness & show Win 10's native OSD

27 May 2017, 15:20

Cheers, for this it's really nice.

I use Windows 7, and for some reason GetModuleHandle wasn't working with powrprof.dll, however I rewrote some code without GetModuleHandle and everything was working fine. (I tried x64 and x32 AHK, and I did have Wow64 file system redirection turned off.)

Btw is that what f.lux uses? How do you change the RGB? E.g. reduce the blue?

I used a script with partially transparent black windows to control brightness before(/now), although that of course would darken any printscreens, unless I turned it off temporarily (i.e. a camera flash effect that I wrote), this should give me a much better solution.

Although, this does not affect my television, only my laptop, I think f.lux affects both.

Anyhow, I'll post my working code, and my test attempts:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: Set laptop brightness & show Win 10's native OSD

27 May 2017, 15:40

jeeswg wrote:I use Windows 7, and for some reason GetModuleHandle wasn't working with powrprof.dll, however I rewrote some code without GetModuleHandle and everything was working fine. (I tried x64 and x32 AHK, and I did have Wow64 file system redirection turned off.)


That's odd. I know PowerApplySettingChanges is undocumented and doesn't exist in WIndows 7, but the script should (read: is meant to) fall back to PowerSetActiveScheme... If I somehow get Windows 7 installed in EFI mode, I'll use your script and try and see what I'm doing wrong. Thanks, jeeswg.

Btw is that what f.lux uses? How do you change the RGB? E.g. reduce the blue?


AFAIK, that's gamma/colour correction territory. jNizM's https://github.com/jNizM/Class_Monitor will allow you to do just that.

Non-AHK open source f.lux alternatives:

https://github.com/jonls/redshift
https://github.com/Tyrrrz/LightBulb
User avatar
jeeswg
Posts: 4760
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Set laptop brightness & show Win 10's native OSD

27 May 2017, 15:54

The problem I'm having is with GetModuleHandle, which may have little or nothing do to with this script as a whole, in case you had any ideas why it wasn't working. Clearly though when I called the dll directly it worked.

I tested PowerSetActiveScheme and it worked, I didn't try PowerApplySettingChanges. [EDIT:] Out of interest, I just tested PowerApplySettingChanges, it didn't work, as expected.

Thanks very much re. the 3 f.lux links.
Last edited by jeeswg on 27 May 2017, 16:04, edited 1 time in total.
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: Set laptop brightness & show Win 10's native OSD

27 May 2017, 16:01

jeeswg wrote:The problem I'm having is with GetModuleHandle, which may have little or nothing do to with this script as a whole, in case you had any ideas why it wasn't working. Clearly though when I called the dll directly it worked.


Sorry, I get what you mean now. I guess some other DLL loaded by Windows automatically loads powrprof.dll on (my) Windows 10 system(s), which is why I assumed using GetModuleHandle would be universally OK. Using LoadLibrary should sort it. I'll make the changes soon.
User avatar
jeeswg
Posts: 4760
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Set laptop brightness & show Win 10's native OSD

27 May 2017, 16:06

Ahh, GetModuleHandle / LoadLibrary. Bit embarrassing, I guess I was kinda confused by the two, because I don't use them that often, yes that sounds likely. I thought GetModuleHandle was loading the module, yeah getting the module (handle) v. loading the library.
User avatar
jamesbermudean
Posts: 4
Joined: 06 Oct 2017, 15:27

Re: Set laptop brightness & show Win 10's native OSD

11 Oct 2017, 15:03

Hello, I am newbie here, but I have been using AutoHotkey since some years ago.
I was looking for a way to control my laptop's brightness, and your script seems to be the solution.
I am getting an error (Call to nonexistent function), and I have read that powrprof.dll is not loaded, but I don't know how to load it or fix it.
Any help would be much appreciated (I'm using Windows 10, x64, updated to last version).
Thank you so much :)

qwerty12 wrote:
poetofpiano wrote:But for some reason that script doesn’t work for me. I followed the instructions for that script at https://www.reddit.com/r/AutoHotkey/com ... ss_script/ and it just doesn’t work.


Replace the copied class with this one (or just save it as BrightnessSetter.ahk and do the usual library thing if you'd prefer):



The version you have is an old one, where it assumes powrprof.dll is always loaded (thanks to jeeswg, I found out it wasn't)...

EDIT: You're welcome, poetofpiano! Thanks for being the fourth person to use the script! :-)
pneumatic
Posts: 146
Joined: 05 Dec 2016, 01:51

Re: Set laptop brightness & show Win 10's native OSD

23 Mar 2018, 12:29

Thank you qwerty12 for taking the time to make this class.

I would like to add a couple of extra conditions to it:

1. Detect if the user's system supports this method of brightness control in the first place, and if not, do nothing. Should I simply modify line 48 as follows?

Code: [Select all] [Download] GeSHi © Codebox Plus

if (jump && BrightnessSetter._GetCurrentBrightness(currSchemeGuid, AC, currBrightness := 0))


2. If the current brightness is already set to the requested value, do nothing. Should I modify line 52 as follows?

Code: [Select all] [Download] GeSHi © Codebox Plus

if (jump || !((currBrightness == maxBrightness && increment > 0) || (currBrightness == minBrightness && increment < minBrightness) || (currBrightness == jump)))


Thanks
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: Set laptop brightness & show Win 10's native OSD

23 Mar 2018, 20:04

jamesbermudean wrote:Hello, I am newbie here, but I have been using AutoHotkey since some years ago.
I was looking for a way to control my laptop's brightness, and your script seems to be the solution.
I am getting an error (Call to nonexistent function), and I have read that powrprof.dll is not loaded, but I don't know how to load it or fix it.
Any help would be much appreciated (I'm using Windows 10, x64, updated to last version).
Thank you so much :)


I doubt you have a need for this any more (and I am sorry for the fact I am getting back to you now) but while I happily admit my sentences and explanations can suck, honestly the most basic instructions would be "paste the contents of the gist into a new AHK script at the end, add something like BrightnessSetter.SetBrightness(-10) at the top and run the script to see if this actually works for you" (of course, the brightness should be quite high in the first place to see the result!)

If it does, just tack your preferred hotkey on

pneumatic wrote:1. Detect if the user's system supports this method of brightness control in the first place, and if not, do nothing. Should I simply modify line 48 as follows?


The Power control panel does this to find out if the power management subsystem is running on a device where it can change the brightness:

Code: [Select all] [Download] GeSHi © Codebox Plus

VarSetCapacity(SystemPowerCapabilities, 76)
if (!DllCall("powrprof\GetPwrCapabilities", "Ptr", &SystemPowerCapabilities) || !NumGet(SystemPowerCapabilities, 10, "UChar")) ; VideoDim[Not]Present
return


2. If the current brightness is already set to the requested value, do nothing. Should I modify line 52 as follows?


Personally, I would keep that if statement the same (the increment stuff that follows makes sure the new brightness value is within bounds for jump and non-jump functionality) but make the following changes:

if (jump || BrightnessSetter._GetCurrentBrightness(currSchemeGuid, AC, currBrightness)) {

into

Code: [Select all] [Download] GeSHi © Codebox Plus

if (BrightnessSetter._GetCurrentBrightness(currSchemeGuid, AC, currBrightness)) {


(short-circuit evaluation will prevent the current brightness value from being obtained if jump == True)

and just turn

if (DllCall(AC ? PowerWriteACValueIndex : PowerWriteDCValueIndex, "Ptr", 0, "Ptr", currSchemeGuid, "Ptr", BrightnessSetter._GUID_VIDEO_SUBGROUP(), "Ptr", BrightnessSetter._GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS(), "UInt", increment, "UInt") == 0) {

into

Code: [Select all] [Download] GeSHi © Codebox Plus

if (increment != currBrightness && DllCall(AC ? PowerWriteACValueIndex : PowerWriteDCValueIndex, "Ptr", 0, "Ptr", currSchemeGuid, "Ptr", BrightnessSetter._GUID_VIDEO_SUBGROUP(), "Ptr", BrightnessSetter._GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS(), "UInt", increment, "UInt") == 0) {


(and move the if showOSD block into the PowerWriteACValueIndex one to stop the brightness OSD from showing even if the brightness wasn't changed)

AHK has had MIN/MAX functions now for a while, which could make that function a bit smaller but I'm too tired for that now. Though I did fix the broken jump functionality, which I could swear it did work when I put out the script, and a small possible memory leak)

Helgef wrote:cool, works fine on my win7 laptop, thanks for sharing :clap:.

Cheers.


Thanks, I only tried this on 10 :-)
Last edited by qwerty12 on 25 Mar 2018, 12:56, edited 1 time in total.
Helgef
Posts: 3092
Joined: 17 Jul 2016, 01:02
Contact:

Re: Set laptop brightness & show Win 10's native OSD

25 Mar 2018, 07:12

cool, works fine on my win7 laptop, thanks for sharing :clap:.

Cheers.
crumbl3d
Posts: 3
Joined: 23 Jun 2018, 17:01
GitHub: crumbl3d

Re: Set laptop brightness & show Win 10's native OSD

25 Jun 2018, 15:56

This does not seem to work with x86 AHK at least on x64 OS. I am making a script that could eventually be compiled to both x86 and x64 but while x64 runs fine x86 just shows the OSD and nothing changes.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 14 guests