Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

Screen Brightness question


  • Please log in to reply
13 replies to this topic
AWK Programmer
  • Guests
  • Last active:
  • Joined: --
Hi all,

I'm currently making use of dxva2.dll in an ahk project to change monitor brightness. Currently I don't have the ability to get or set the brightness through the Monitor handle, though I have been able to create one so far. Here is what I'm working on:
; Initialize Monitor handle
VarSetCapacity(ptZero, 8, 0)
hMonitor := DllCall("MonitorFromPoint"
	, UInt, ptZero		; point on monitor
	, UInt, 1)		; flag to return primary monitor
MsgBox, hMonitor: %hMonitor%

; Find number of Physical Monitors
DllCall("dxva2\GetNumberOfPhysicalMonitorsFromHMONITOR"
	, UInt, hMonitor
	, UIntP, numMonitor)
MsgBox, numMonitor: %numMonitor%

; Get Physical Monitor from handle
work := DllCall("dxva2\GetPhysicalMonitorsFromHMONITOR"
	, UInt, hMonitor	; monitor handle
	, UInt, numMonitor	; monitor array size
	, Str, arrayMonitor)	; point to array with monitor
; Problem here, finding Physical Monitor
hPhysicalMonitor := NumGet(arrayMonitor, 0, "UInt")
MsgBox, work: %work%

if hMonitor <> -1
{
	work := DllCall("dxva2\GetMonitorBrightness"
		, UInt, hPhysicalMonitor
		, UIntP, minBright
		, UIntP, curBright
		, UIntP, maxBright)
	MsgBox, Work: %work%`nErrorLevel: %ErrorLevel%`nLastError: %A_LastError%
	MsgBox, Min: %minBright%`nMax: %maxBright%`nCurrent: %curBright%
}
I researched it quite a bit on MSDN, and it is quite nice in comparison to what I had found here on the forum: http://www.autohotke...040.html#447040

So basically I would like to use GetMonitorBrightness to find what the current brightness is (in addition to the minimum and maximum values) and then input the brightness using SetMonitorBrightness. However, in order to do that I need to have a Physical Monitor rather than a simple Monitor Handle, as you can see I have received.

Based on the above code, I receive these messages:
hMonitor: 65537
numMonitor: 1 (only one monitor found based on the handle)
work: 1 (able to get a physical monitor array from the handle)
work: 0 (not able to use the physical monitor handle to get brightness)
errorlevel: 0 (not an error?)
lasterror: -1071241847 (don't understand this)
min: 0
max: 0
current: 0 (none of these values are found)

Here are many of the links that I have used to figure most of it out:
SetMonitorBrightness
http://msdn.microsof...2(v=VS.85).aspx

GetMonitorBrightness
http://msdn.microsof...9(v=VS.85).aspx

PHYSICAL_MONITOR
http://msdn.microsof...7(v=VS.85).aspx

GetPhysicalMonitorsFromHMONITOR
http://msdn.microsof...0(v=VS.85).aspx

GetNumberOfPhysicalMonitorsFromHMONITOR
http://msdn.microsof...8(v=VS.85).aspx

MonitorFromPoint
http://msdn.microsof...062(VS.85).aspx

Other Monitor Functions
http://msdn.microsof...4(v=VS.85).aspx

Any ideas or something I should clarify further?

AWK_Programmer
  • Members
  • 8 posts
  • Last active: Dec 12 2012 03:42 AM
  • Joined: 27 May 2011
Not sure why my post isn't showing up.

I'm currently making use of dxva2.dll in an ahk project to change monitor brightness. Currently I don't have the ability to get or set the brightness through the Monitor handle, though I have been able to create one so far. Here is what I'm working on:
; Initialize Monitor handle
VarSetCapacity(ptZero, 8, 0)
hMonitor := DllCall("MonitorFromPoint"
	, UInt, ptZero		; point on monitor
	, UInt, 1)		; flag to return primary monitor
MsgBox, hMonitor: %hMonitor%

; Find number of Physical Monitors
DllCall("dxva2\GetNumberOfPhysicalMonitorsFromHMONITOR"
	, UInt, hMonitor
	, UIntP, numMonitor)
MsgBox, numMonitor: %numMonitor%

; Get Physical Monitor from handle
work := DllCall("dxva2\GetPhysicalMonitorsFromHMONITOR"
	, UInt, hMonitor	; monitor handle
	, UInt, numMonitor	; monitor array size
	, Str, arrayMonitor)	; point to array with monitor
; Problem here, finding Physical Monitor
hPhysicalMonitor := NumGet(arrayMonitor, 0, "UInt")
MsgBox, work: %work%

if hMonitor <> -1
{
	work := DllCall("dxva2\GetMonitorBrightness"
		, UInt, hPhysicalMonitor
		, UIntP, minBright
		, UIntP, curBright
		, UIntP, maxBright)
	MsgBox, Work: %work%`nErrorLevel: %ErrorLevel%`nLastError: %A_LastError%
	MsgBox, Min: %minBright%`nMax: %maxBright%`nCurrent: %curBright%
}
I researched it quite a bit on MSDN, and it is quite nice in comparison to what I had found here on the forum: http://www.autohotke...040.html#447040

So basically I would like to use GetMonitorBrightness to find what the current brightness is (in addition to the minimum and maximum values) and then input the brightness using SetMonitorBrightness. However, in order to do that I need to have a Physical Monitor rather than a simple Monitor Handle, as you can see I have received.

Based on the above code, I receive these messages:
hMonitor: 65537
numMonitor: 1 (only one monitor found based on the handle)
work: 1 (able to get a physical monitor array from the handle)
work: 0 (not able to use the physical monitor handle to get brightness)
errorlevel: 0 (not an error?)
lasterror: -1071241847 (don't understand this)
min: 0
max: 0
current: 0 (none of these values are found)

AWK_Programmer
  • Members
  • 8 posts
  • Last active: Dec 12 2012 03:42 AM
  • Joined: 27 May 2011
Here are many of the links that I have used to figure most of it out:
SetMonitorBrightness
http://msdn.microsof...2(v=VS.85).aspx
GetMonitorBrightness
http://msdn.microsof...9(v=VS.85).aspx
PHYSICAL_MONITOR
http://msdn.microsof...7(v=VS.85).aspx
GetPhysicalMonitorsFromHMONITOR
http://msdn.microsof...0(v=VS.85).aspx
GetNumberOfPhysicalMonitorsFromHMONITOR
http://msdn.microsof...8(v=VS.85).aspx
MonitorFromPoint
http://msdn.microsof...062(VS.85).aspx
Other Monitor Functions
http://msdn.microsof...4(v=VS.85).aspx

Any ideas or something I should clarify further?

AWK_Programmer
  • Members
  • 8 posts
  • Last active: Dec 12 2012 03:42 AM
  • Joined: 27 May 2011
I have been testing it in AHK_L at the suggestion of users on IRC, although it doesn't seem to do much.

Solar
  • Members
  • 345 posts
  • Last active: Jan 15 2012 08:11 PM
  • Joined: 03 May 2009
MonitorFromPoint expects an 8 byte point structure. Therefore, an unsigned integer won't work. Try this:

; Initialize Monitor handle
hMonitor := DllCall("MonitorFromPoint"
   , "int64", 0 ; point on monitor
   , "uint", 1) ; flag to return primary monitor on failure


AWK_Programmer
  • Members
  • 8 posts
  • Last active: Dec 12 2012 03:42 AM
  • Joined: 27 May 2011
Great. That's a start, I'm still not getting the physical monitor handle, which for some reason is what I require to call get and set monitor brightness functions.

Solar
  • Members
  • 345 posts
  • Last active: Jan 15 2012 08:11 PM
  • Joined: 03 May 2009
; Initialize Monitor handle
hMon := DllCall("MonitorFromPoint"
   , "int64", 0 ; point on monitor
   , "uint", 1) ; flag to return primary monitor on failure

; Find number of Physical Monitors
DllCall("dxva2\GetNumberOfPhysicalMonitorsFromHMONITOR"
   , "int", hMon
   , "uint*", nMon)

; Get Physical Monitor from handle
VarSetCapacity(Physical_Monitor, (A_PtrSize ? A_PtrSize : 4) + 128)

DllCall("dxva2\GetPhysicalMonitorsFromHMONITOR"
   , "int", hMon   ; monitor handle
   , "uint", nMon   ; monitor array size
   , "int", &Physical_Monitor)   ; point to array with monitor
   
hPhysMon := NumGet(Physical_Monitor)

DllCall("dxva2\GetMonitorBrightness"
  , "int", hPhysMon
  , "uint*", minBright
  , "uint*", curBright
  , "uint*", maxBright)

MsgBox, Min: %minBright%`nMax: %maxBright%`nCurrent: %curBright%
:?:

(Requires Vista+)

AWK_Programmer
  • Members
  • 8 posts
  • Last active: Dec 12 2012 03:42 AM
  • Joined: 27 May 2011
Thanks for the help, although that returns the same result. Please test your code before you give me a reply, that way it helps me figure it out also.

Solar
  • Members
  • 345 posts
  • Last active: Jan 15 2012 08:11 PM
  • Joined: 03 May 2009
Worked as expected for me on Win7. What problem are you having? Are you using Windows Vista or later?

Also, according to the MSDN documentation, your monitor must support the GetMonitorBrightness function. You should call the GetMonitorCapabilities function to see if it returns the MC_CAPS_BRIGHTNESS flag (indicating support for brightness functions).

although that returns the same result. Please test your code before you give me a reply

Don't assume that just because it doesn't work for you means that it doesn't work at all.

I included the monitor description as well as the GetMonitorCapabilities function for debugging. Try this out (untested because I'm on WinXP atm):

; Initialize Monitor handle
hMon := DllCall("MonitorFromPoint"
	, "int64", 0 ; point on monitor
	, "uint", 1) ; flag to return primary monitor on failure

; Find number of Physical Monitors
DllCall("dxva2\GetNumberOfPhysicalMonitorsFromHMONITOR"
	, "int", hMon
	, "uint*", nMon)

; Get Physical Monitor from handle
VarSetCapacity(Physical_Monitor, (A_PtrSize ? A_PtrSize : 4) + 128, 0)

DllCall("dxva2\GetPhysicalMonitorsFromHMONITOR"
	, "int", hMon   ; monitor handle
	, "uint", nMon   ; monitor array size
	, "int", &Physical_Monitor)   ; point to array with monitor

hPhysMon := NumGet(Physical_Monitor)

if (!DllCall("dxva2\GetMonitorCapabilities"
	, "int", hPhysMon
	, "uint*", monCaps
	, "uint*", monColorTemps))
	MsgBox % "Monitor does not support DDC/CI."
else if (monCaps & 0x2 = 0) ; MC_CAPS_BRIGHTNESS
	MsgBox % "Monitor does not support GetMonitorBrightness or SetMonitorBrightness functions."

DllCall("dxva2\GetMonitorBrightness"
	, "int", hPhysMon
	, "uint*", minBright
	, "uint*", curBright
	, "uint*", maxBright)

MsgBox % "Monitor description: " . StrGet(&Physical_Monitor+(A_PtrSize ? A_PtrSize : 4), "utf-16")
	. "`nMinimum brightness: " . minBright
	. "`nMaximum brightness: " . maxBright
	. "`nCurrent brightness: " . curBright
Edit: Requires StrGet() if you're using AHK Basic.

Solar
  • Members
  • 345 posts
  • Last active: Jan 15 2012 08:11 PM
  • Joined: 03 May 2009
Ok, I got around to testing my code in the previous post on Win7. There were a couple problems when using AHK Basic (because StrGet was used) but I edited my previous post and fixed them.

My result on Win7:

Monitor description: Acer AL2216W
Minimum brightness: 0
Maximum brightness: 100
Current brightness: 77

AWK_Programmer
  • Members
  • 8 posts
  • Last active: Dec 12 2012 03:42 AM
  • Joined: 27 May 2011

Ok, I got around to testing my code in the previous post on Win7. There were a couple problems when using AHK Basic (because StrGet was used) but I edited my previous post and fixed them.

My result on Win7:

Monitor description: Acer AL2216W
Minimum brightness: 0
Maximum brightness: 100
Current brightness: 77

@Solar: Alright, thanks for the help. I do apologize, I didn't realize you had tested the code, and I am merely frustrated at the supposed simplicity of this method that doesn't appear to work on my monitor. I did see the GetMonitorCapabilites function in passing but I didn't think to use it. However, after testing your debug code, which I greatly appreciate by the way, I got the following result:

Monitor does not support DDC/CI.

Monitor description: ThinkPad Display 1280x800
Minimum brightness: 0
Maximum brightness: 0
Current brightness: 0

So it would appear that my LCD monitor (on a laptop) is incompatible with these functions. I'm running Windows Vista Home with DirectX 11. I do hope there is some sort of work-around, if this should work on other platforms (eg. Windows 7 appears to have no issues in your case).

Solar
  • Members
  • 345 posts
  • Last active: Jan 15 2012 08:11 PM
  • Joined: 03 May 2009

Monitor does not support DDC/CI.

That's unfortunate; but does explain why it wasn't working.

I stumbled upon this post of yours: <!-- m -->http://www.autohotke... ... 040#447040<!-- m -->

What's wrong with that solution?

AWK_Programmer
  • Members
  • 8 posts
  • Last active: Dec 12 2012 03:42 AM
  • Joined: 27 May 2011
Yes, it would appear that the issue is my display, not the code itself. I tested the same debug code on a newer machine running Windows 7, and it had no issues finding and changing the display settings.

I stumbled upon this post of yours: <!-- m -->http://www.autohotke... ... 040#447040<!-- m -->

What's wrong with that solution?

Yes, as an earlier post it would seem that the method explained there had no issues. True, I could adjust brightness successfully on my machine using that code, however it is an outdated usage which is supposed to be discontinued, so for future compatibility I wanted to change it. Additionally, I noticed a problem when trying to change brightness above the maximum (100). It would go up to 90, then when adjusting it to 95 it would default to 100 and stay there. I was unable to lower it from there for some odd reason. Try this code out: https://ahknet.autoh...om/paste/ysjn17

edit: After some further testing, I found that simply setting ACLevel and DCLevel to 95 caused it to default to 100, and by incrementing by 10 instead of 5, I could avoid this problem completely. This could be specific to my monitor, and I have found that it is limited to 20-100 in brightness. Odd, but true. Is this something that other monitors also have?
Also, in any case, I could simply use this code as a backup if the SetMonitorBrightness is not functional on a given monitor.

AWK_Programmer
  • Members
  • 8 posts
  • Last active: Dec 12 2012 03:42 AM
  • Joined: 27 May 2011
Does anyone see something else I missed here? I believe this issue may be largely solved.