-
-
Save qwerty12/4b3f41eb61724cd9e8f2bb5cc15c33c2 to your computer and use it in GitHub Desktop.
| class BrightnessSetter { | |
| ; qwerty12 - 27/05/17 | |
| ; https://github.com/qwerty12/AutoHotkeyScripts/tree/master/LaptopBrightnessSetter | |
| static _WM_POWERBROADCAST := 0x218, _osdHwnd := 0, hPowrprofMod := DllCall("LoadLibrary", "Str", "powrprof.dll", "Ptr") | |
| __New() { | |
| if (BrightnessSetter.IsOnAc(AC)) | |
| this._AC := AC | |
| if ((this.pwrAcNotifyHandle := DllCall("RegisterPowerSettingNotification", "Ptr", A_ScriptHwnd, "Ptr", BrightnessSetter._GUID_ACDC_POWER_SOURCE(), "UInt", DEVICE_NOTIFY_WINDOW_HANDLE := 0x00000000, "Ptr"))) ; Sadly the callback passed to *PowerSettingRegister*Notification runs on a new threadl | |
| OnMessage(this._WM_POWERBROADCAST, ((this.pwrBroadcastFunc := ObjBindMethod(this, "_On_WM_POWERBROADCAST")))) | |
| } | |
| __Delete() { | |
| if (this.pwrAcNotifyHandle) { | |
| OnMessage(BrightnessSetter._WM_POWERBROADCAST, this.pwrBroadcastFunc, 0) | |
| ,DllCall("UnregisterPowerSettingNotification", "Ptr", this.pwrAcNotifyHandle) | |
| ,this.pwrAcNotifyHandle := 0 | |
| ,this.pwrBroadcastFunc := "" | |
| } | |
| } | |
| SetBrightness(increment, jump := False, showOSD := True, autoDcOrAc := -1, ptrAnotherScheme := 0) | |
| { | |
| static PowerGetActiveScheme := DllCall("GetProcAddress", "Ptr", BrightnessSetter.hPowrprofMod, "AStr", "PowerGetActiveScheme", "Ptr") | |
| ,PowerSetActiveScheme := DllCall("GetProcAddress", "Ptr", BrightnessSetter.hPowrprofMod, "AStr", "PowerSetActiveScheme", "Ptr") | |
| ,PowerWriteACValueIndex := DllCall("GetProcAddress", "Ptr", BrightnessSetter.hPowrprofMod, "AStr", "PowerWriteACValueIndex", "Ptr") | |
| ,PowerWriteDCValueIndex := DllCall("GetProcAddress", "Ptr", BrightnessSetter.hPowrprofMod, "AStr", "PowerWriteDCValueIndex", "Ptr") | |
| ,PowerApplySettingChanges := DllCall("GetProcAddress", "Ptr", BrightnessSetter.hPowrprofMod, "AStr", "PowerApplySettingChanges", "Ptr") | |
| if (increment == 0 && !jump) { | |
| if (showOSD) | |
| BrightnessSetter._ShowBrightnessOSD() | |
| return | |
| } | |
| if (!ptrAnotherScheme ? DllCall(PowerGetActiveScheme, "Ptr", 0, "Ptr*", currSchemeGuid, "UInt") == 0 : DllCall("powrprof\PowerDuplicateScheme", "Ptr", 0, "Ptr", ptrAnotherScheme, "Ptr*", currSchemeGuid, "UInt") == 0) { | |
| if (autoDcOrAc == -1) { | |
| if (this != BrightnessSetter) { | |
| AC := this._AC | |
| } else { | |
| if (!BrightnessSetter.IsOnAc(AC)) { | |
| DllCall("LocalFree", "Ptr", currSchemeGuid, "Ptr") | |
| return | |
| } | |
| } | |
| } else { | |
| AC := !!autoDcOrAc | |
| } | |
| currBrightness := 0 | |
| if (jump || BrightnessSetter._GetCurrentBrightness(currSchemeGuid, AC, currBrightness)) { | |
| maxBrightness := BrightnessSetter.GetMaxBrightness() | |
| ,minBrightness := BrightnessSetter.GetMinBrightness() | |
| if (jump || !((currBrightness == maxBrightness && increment > 0) || (currBrightness == minBrightness && increment < minBrightness))) { | |
| if (currBrightness + increment > maxBrightness) | |
| increment := maxBrightness | |
| else if (currBrightness + increment < minBrightness) | |
| increment := minBrightness | |
| else | |
| increment += currBrightness | |
| 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) { | |
| ; PowerApplySettingChanges is undocumented and exists only in Windows 8+. Since both the Power control panel and the brightness slider use this, we'll do the same, but fallback to PowerSetActiveScheme if on Windows 7 or something | |
| if (!PowerApplySettingChanges || DllCall(PowerApplySettingChanges, "Ptr", BrightnessSetter._GUID_VIDEO_SUBGROUP(), "Ptr", BrightnessSetter._GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS(), "UInt") != 0) | |
| DllCall(PowerSetActiveScheme, "Ptr", 0, "Ptr", currSchemeGuid, "UInt") | |
| } | |
| } | |
| if (showOSD) | |
| BrightnessSetter._ShowBrightnessOSD() | |
| } | |
| DllCall("LocalFree", "Ptr", currSchemeGuid, "Ptr") | |
| } | |
| } | |
| IsOnAc(ByRef acStatus) | |
| { | |
| static SystemPowerStatus | |
| if (!VarSetCapacity(SystemPowerStatus)) | |
| VarSetCapacity(SystemPowerStatus, 12) | |
| if (DllCall("GetSystemPowerStatus", "Ptr", &SystemPowerStatus)) { | |
| acStatus := NumGet(SystemPowerStatus, 0, "UChar") == 1 | |
| return True | |
| } | |
| return False | |
| } | |
| GetDefaultBrightnessIncrement() | |
| { | |
| static ret := 10 | |
| DllCall("powrprof\PowerReadValueIncrement", "Ptr", BrightnessSetter._GUID_VIDEO_SUBGROUP(), "Ptr", BrightnessSetter._GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS(), "UInt*", ret, "UInt") | |
| return ret | |
| } | |
| GetMinBrightness() | |
| { | |
| static ret := -1 | |
| if (ret == -1) | |
| if (DllCall("powrprof\PowerReadValueMin", "Ptr", BrightnessSetter._GUID_VIDEO_SUBGROUP(), "Ptr", BrightnessSetter._GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS(), "UInt*", ret, "UInt")) | |
| ret := 0 | |
| return ret | |
| } | |
| GetMaxBrightness() | |
| { | |
| static ret := -1 | |
| if (ret == -1) | |
| if (DllCall("powrprof\PowerReadValueMax", "Ptr", BrightnessSetter._GUID_VIDEO_SUBGROUP(), "Ptr", BrightnessSetter._GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS(), "UInt*", ret, "UInt")) | |
| ret := 100 | |
| return ret | |
| } | |
| _GetCurrentBrightness(schemeGuid, AC, ByRef currBrightness) | |
| { | |
| static PowerReadACValueIndex := DllCall("GetProcAddress", "Ptr", BrightnessSetter.hPowrprofMod, "AStr", "PowerReadACValueIndex", "Ptr") | |
| ,PowerReadDCValueIndex := DllCall("GetProcAddress", "Ptr", BrightnessSetter.hPowrprofMod, "AStr", "PowerReadDCValueIndex", "Ptr") | |
| return DllCall(AC ? PowerReadACValueIndex : PowerReadDCValueIndex, "Ptr", 0, "Ptr", schemeGuid, "Ptr", BrightnessSetter._GUID_VIDEO_SUBGROUP(), "Ptr", BrightnessSetter._GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS(), "UInt*", currBrightness, "UInt") == 0 | |
| } | |
| _ShowBrightnessOSD() | |
| { | |
| static PostMessagePtr := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "user32.dll", "Ptr"), "AStr", A_IsUnicode ? "PostMessageW" : "PostMessageA", "Ptr") | |
| ,WM_SHELLHOOK := DllCall("RegisterWindowMessage", "Str", "SHELLHOOK", "UInt") | |
| if A_OSVersion in WIN_VISTA,WIN_7 | |
| return | |
| BrightnessSetter._RealiseOSDWindowIfNeeded() | |
| ; Thanks to YashMaster @ https://github.com/YashMaster/Tweaky/blob/master/Tweaky/BrightnessHandler.h for realising this could be done: | |
| if (BrightnessSetter._osdHwnd) | |
| DllCall(PostMessagePtr, "Ptr", BrightnessSetter._osdHwnd, "UInt", WM_SHELLHOOK, "Ptr", 0x37, "Ptr", 0) | |
| } | |
| _RealiseOSDWindowIfNeeded() | |
| { | |
| static IsWindow := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "user32.dll", "Ptr"), "AStr", "IsWindow", "Ptr") | |
| if (!DllCall(IsWindow, "Ptr", BrightnessSetter._osdHwnd) && !BrightnessSetter._FindAndSetOSDWindow()) { | |
| BrightnessSetter._osdHwnd := 0 | |
| try if ((shellProvider := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{00000000-0000-0000-C000-000000000046}"))) { | |
| try if ((flyoutDisp := ComObjQuery(shellProvider, "{41f9d2fb-7834-4ab6-8b1b-73e74064b465}", "{41f9d2fb-7834-4ab6-8b1b-73e74064b465}"))) { | |
| DllCall(NumGet(NumGet(flyoutDisp+0)+3*A_PtrSize), "Ptr", flyoutDisp, "Int", 0, "UInt", 0) | |
| ,ObjRelease(flyoutDisp) | |
| } | |
| ObjRelease(shellProvider) | |
| if (BrightnessSetter._FindAndSetOSDWindow()) | |
| return | |
| } | |
| ; who knows if the SID & IID above will work for future versions of Windows 10 (or Windows 8). Fall back to this if needs must | |
| Loop 2 { | |
| SendEvent {Volume_Mute 2} | |
| if (BrightnessSetter._FindAndSetOSDWindow()) | |
| return | |
| Sleep 100 | |
| } | |
| } | |
| } | |
| _FindAndSetOSDWindow() | |
| { | |
| static FindWindow := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "user32.dll", "Ptr"), "AStr", A_IsUnicode ? "FindWindowW" : "FindWindowA", "Ptr") | |
| return !!((BrightnessSetter._osdHwnd := DllCall(FindWindow, "Str", "NativeHWNDHost", "Str", "", "Ptr"))) | |
| } | |
| _On_WM_POWERBROADCAST(wParam, lParam) | |
| { | |
| ;OutputDebug % &this | |
| if (wParam == 0x8013 && lParam && NumGet(lParam+0, 0, "UInt") == NumGet(BrightnessSetter._GUID_ACDC_POWER_SOURCE()+0, 0, "UInt")) { ; PBT_POWERSETTINGCHANGE and a lazy comparison | |
| this._AC := NumGet(lParam+0, 20, "UChar") == 0 | |
| return True | |
| } | |
| } | |
| _GUID_VIDEO_SUBGROUP() | |
| { | |
| static GUID_VIDEO_SUBGROUP__ | |
| if (!VarSetCapacity(GUID_VIDEO_SUBGROUP__)) { | |
| VarSetCapacity(GUID_VIDEO_SUBGROUP__, 16) | |
| ,NumPut(0x7516B95F, GUID_VIDEO_SUBGROUP__, 0, "UInt"), NumPut(0x4464F776, GUID_VIDEO_SUBGROUP__, 4, "UInt") | |
| ,NumPut(0x1606538C, GUID_VIDEO_SUBGROUP__, 8, "UInt"), NumPut(0x99CC407F, GUID_VIDEO_SUBGROUP__, 12, "UInt") | |
| } | |
| return &GUID_VIDEO_SUBGROUP__ | |
| } | |
| _GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS() | |
| { | |
| static GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS__ | |
| if (!VarSetCapacity(GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS__)) { | |
| VarSetCapacity(GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS__, 16) | |
| ,NumPut(0xADED5E82, GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS__, 0, "UInt"), NumPut(0x4619B909, GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS__, 4, "UInt") | |
| ,NumPut(0xD7F54999, GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS__, 8, "UInt"), NumPut(0xCB0BAC1D, GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS__, 12, "UInt") | |
| } | |
| return &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS__ | |
| } | |
| _GUID_ACDC_POWER_SOURCE() | |
| { | |
| static GUID_ACDC_POWER_SOURCE_ | |
| if (!VarSetCapacity(GUID_ACDC_POWER_SOURCE_)) { | |
| VarSetCapacity(GUID_ACDC_POWER_SOURCE_, 16) | |
| ,NumPut(0x5D3E9A59, GUID_ACDC_POWER_SOURCE_, 0, "UInt"), NumPut(0x4B00E9D5, GUID_ACDC_POWER_SOURCE_, 4, "UInt") | |
| ,NumPut(0x34FFBDA6, GUID_ACDC_POWER_SOURCE_, 8, "UInt"), NumPut(0x486551FF, GUID_ACDC_POWER_SOURCE_, 12, "UInt") | |
| } | |
| return &GUID_ACDC_POWER_SOURCE_ | |
| } | |
| } | |
| BrightnessSetter_new() { | |
| return new BrightnessSetter() | |
| } |
Hi @Minibus93 , You're most welcome! I'm really glad to hear it's working awesome for you! :)
If you have a quick moment, could you help me test one thing on your laptop to confirm?
When you press and hold down F1 (or Shift + F1), does the brightness adjust continuously and smoothly (like volume control keys do), or does it step slowly one increment at a time?
On my laptop (an Acer Predator Helios 300 - 2021 Model - i7 10th Gen), holding down F1 / Shift + F1 feels very slow now (taking input step-by-step rather than smoothly ramping up/down). It used to be fast in the past, so I'm trying to figure out whether a recent Windows update (few months back) slowed down WMI brightness inputs globally, or if it's just specific to my Acer Predator hardware/drivers. Because even if I use the laptop official keymaps which are fn + left/right key, they are actually too slow from the starting of the laptop. But this script previously fixed this issue (Maybe I've changed my motherboard that can also be the issue I don't know).
If you could test it on your laptop and let me know that in your laptop does it goes smoothly increase/decrease of brightness or like with steps (slowly) as I said above, that would be super helpful! Thanks again!
@Arora-Sir yes of course I can test it, however it may have to wait a few days as I'm currently on vacation and only have my mac with me so I don't have access to my windows pc, but I will indeed test it :D
Thank you @Minibus93, waiting for your reply then ππ
Hi! Thanks for the reply and thanks for fixing the script, it's just so awesome!