123
Senior Member
This was a truly hard-won victory and I hope this information will help fellow Cocooners.
I've connected a touchscreen to my, formerly headless, HA server. To conserve power, I want the ability to turn the touchscreen on and off via my HA application. For example, upon arming my security system (via a keypad) I want the touchscreen to go into sleep mode.
One technique would be to use a simple X10 appliance module to control the monitor's power source. However, Windows has programmatic control of the monitor's power-mode so there must be a way of doing it in software (and not by calling an external EXE).
If you think there's a WMI method to control the monitor's powerstate, you'd be both right and wrong! Curiously, Microsoft has documented the SetPowerState method yet indicated it is "not implemented"!?!
The primary means of controlling a monitor's powerstate is by using the Windows SendMessage function. Yup, you have to make a low-level call to USER32.dll, in the OS's innards, to get the job done. The procedure is straightforward if you use C, C++, VB, or a .NET language. There are several articles on the subject in CodeProject.
Unfortunately, VBScript does not support calls to the Win32 API. AutoIT does but VBScript doesn't.
The solution is an obscure DLL described in WinHelpLine.info. I can't read German but, after skimming the thread, I found a link to a helper called DynaCall (enhanced version is called DynaWrap). DynaCall allows you to make Win32 API calls using VBScript.
After downloading and registering DynaCall, you can use the following code to control a monitor's powerstate:
I found that if you pass the numeric parameters in hexadecimal format, as shown in most examples, the function will not work. They're supposed to be Long values yet casting the hex numbers as Long didn't help either ... go figure. Supplying them as decimal values did the trick.
All of that I=, f=, and R= gibberish is quite important because it tells DynaCall the quantity and type of the parameters being passed. In this case, SendMessage requires four Long parameters so "I=llll". The details are documented in DynaCall's readme file. I found Pinvoke.net to be good reference for the Win32 API.
So there you have it; three lines of VBScript to turn off a monitor.
I've connected a touchscreen to my, formerly headless, HA server. To conserve power, I want the ability to turn the touchscreen on and off via my HA application. For example, upon arming my security system (via a keypad) I want the touchscreen to go into sleep mode.
One technique would be to use a simple X10 appliance module to control the monitor's power source. However, Windows has programmatic control of the monitor's power-mode so there must be a way of doing it in software (and not by calling an external EXE).
If you think there's a WMI method to control the monitor's powerstate, you'd be both right and wrong! Curiously, Microsoft has documented the SetPowerState method yet indicated it is "not implemented"!?!
The primary means of controlling a monitor's powerstate is by using the Windows SendMessage function. Yup, you have to make a low-level call to USER32.dll, in the OS's innards, to get the job done. The procedure is straightforward if you use C, C++, VB, or a .NET language. There are several articles on the subject in CodeProject.
Unfortunately, VBScript does not support calls to the Win32 API. AutoIT does but VBScript doesn't.
The solution is an obscure DLL described in WinHelpLine.info. I can't read German but, after skimming the thread, I found a link to a helper called DynaCall (enhanced version is called DynaWrap). DynaCall allows you to make Win32 API calls using VBScript.
After downloading and registering DynaCall, you can use the following code to control a monitor's powerstate:
Code:
' To power-down a monitor
Set oItem = CreateObject("DynamicWrapper")
oItem.Register "USER32.DLL", "SendMessageA", "I=llll", "f=s", "R=l"
oItem.SendMessageA -1, 274, 61808, 2
' To power-up a monitor
Set oItem = CreateObject("DynamicWrapper")
oItem.Register "USER32.DLL", "SendMessageA", "I=llll", "f=s", "R=l"
oItem.SendMessageA -1, 274, 61808, -1
I found that if you pass the numeric parameters in hexadecimal format, as shown in most examples, the function will not work. They're supposed to be Long values yet casting the hex numbers as Long didn't help either ... go figure. Supplying them as decimal values did the trick.
All of that I=, f=, and R= gibberish is quite important because it tells DynaCall the quantity and type of the parameters being passed. In this case, SendMessage requires four Long parameters so "I=llll". The details are documented in DynaCall's readme file. I found Pinvoke.net to be good reference for the Win32 API.
So there you have it; three lines of VBScript to turn off a monitor.