How To Determine If An LCD Is Off

I asked this question yesterday and I thought I received a solution, but I did not.

I ran the code on my laptop that had an external monitor attached. When I ran the code, the PrimaryDevice (my laptop screen) showed a DeviceID of 1. When the lid was closed, it showed an DID of 0.

I thought this was perfect. But, it turns out that when I removed the external monitor, the DeviceID stays 5 and persists no matter the state of the monitor.

I tried this on 5 notebooks. All had the same info. No information changed and this has become very frustrating. So I'm hoping someone can can help me come up with a solution. I've attached the code I'm using.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
I would think that WMI and the Win32_DesktopMonitor class would be able to give you Availability.

Win32_DesktopMonitor class
weirddemonAuthor Commented:

Unfortunately, that too does not work. It reports the same as the API. I tried that many days ago, with no luck.
Bob LearnedCommented:
That's interesting, but understandable, since I hadn't looked at this specifically.  The Availability property is supposed to give you the monitor state.  With a little research, I see that detecting when the laptop lid is closed is not an easy proposition.  I would imagine that you have looked into ACPI events, and the like.  I would like to know what you have tried, and what didn't work.
Announcing the Winners!

The results are in for the 15th Annual Expert Awards! Congratulations to the winners, and thank you to everyone who participated in the nominations. We are so grateful for the valuable contributions experts make on a daily basis. Click to read more about this year’s recipients!

weirddemonAuthor Commented:

I've tried the API I mentioned above, WMI and the WindProc method so far.

One person suggested that the top level window receives a WM_SYSCOMMAND message with wParam set to SC_MONITORPOWER whenever the power status of a display is changing. But I'm afraid I'm not 100% sure how to work with that.

With the WindProc function, I tried just seeing if the message matched SC_MONITORPOWER, but it didn't work. I tried a few other constants with it, but I can't remember them all and they didn't work.
Bob LearnedCommented:
I saw the SC_MONITORPOWER suggestion, but there where comments that this didn't work.  I would have implemented this in an IMessageFilter, rather than overriding WndProc, but that is not important.

I wonder if monitoring for the WM_POWERBROADCAST system notification would work.

System Power Management Events
Bob LearnedCommented:

In Vista you can register for a callback for when the Lid Close Action changes.  This is done by calling RegisterPowerSettingNotification (see for details).  The GUID for this power setting you're interested in is GUID_LIDCLOSE_ACTION.  This is defined in wdm.h in the Platform SDK.  
Once registered, a WM_POWERBROADCAST will be sent to your application with wParam set to PBT_POWERSETTINGCHANGE.   This event is sent anytime the value for the lid close action changes.  The lParam contains a pointer to a POWERBROADCAST_SETTING structure (see containing information on the setting change.
weirddemonAuthor Commented:

I forgotten to mention that I already looked into that method because I had given up on trying to determine if the lid had been closed.

I spent a lot of time trying to figure out how to put all the pieces together for that one, but I was unable to understand everything. I'm sure it could be done, but I lack the direct knowledge and I haven't received much help trying to piece it together.
Bob LearnedCommented:
Aha, that's why I was asking what you tried, and didn't work.  Can you describe your requirement again, so that I may be certain what you are trying to do.  I picked out the "lid closed" comment, which is probably not what you are concerned with.  The Win32_DesktopMonitor.Availability didn't work for you, but I haven't tried it for myself.
weirddemonAuthor Commented:

Sure, no problem. I'm sorry I'm not being as clear as I can. I hope this description clears things up.

Basically, I need to determine when the lid of the laptop is closed. I need to force the users to close the lid 'n' amount of times and open it the same amount of times.

So when I first started looking this up, I went with that. But everything I came across either didn't work, or I wasn't able to get it to work.

So then I thought... when the lid is closed, the LCD turns off. So if I could figure out when the LCD turned off, that would amount to the same thing as determining when the lid was closed.

And so here we are. Does that help?
David Johnson, CD, MVPRetiredCommented:
So then I thought... when the lid is closed, the LCD turns off. So if I could figure out when the LCD turned off, that would amount to the same thing as determining when the lid was closed.

all that happens when the lid is closed is the power to the lcd backlight is removed.
weirddemonAuthor Commented:

And when the lid is closed, the back light turns off. So it was a reasonable method. I just can't figure out how to detect either/or.
How to detect laptop lid closed?

Check this Blog...

How are power buttons reported in Windows?

POCLASS.H contains following flags:

#define SYS_BUTTON_LID              0x00000004L
#define SYS_BUTTON_WAKE             0x80000000L
#define SYS_BUTTON_LID_STATE_MASK   0x00030000L
#define SYS_BUTTON_LID_OPEN         0x00010000L
#define SYS_BUTTON_LID_CLOSED       0x00020000L
#define SYS_BUTTON_LID_INITIAL      0x00040000L
#define SYS_BUTTON_LID_CHANGED      0x00080000L

Did you get further with your problem???
weirddemonAuthor Commented:
This was a long an arduous path. Mainly because the documentation for this is next to none. But, thankfully someone at VBF was able to solve my problem. It all basically came down to an API that registers the form to receive this particular power event. Along with this, I needed to not only capture the message, but also the wparam of the message.

I've attached the solution. The API just needs to be called during Form load or whenever. It returns a value that you can pass to another API, that will unregister the power event if you need it.
Const WM_POWERBROADCAST As Integer = &H218
Public Shared GUID_LIDSWITCH_STATE_CHANGE As New Guid(&HBA3E0F4DUI, &HB817, &H4094, &HA2, &HD1, &HD5, &H63, &H79, &HE6, &HA0, &HF3)

Protected Overrides Sub WndProc(ByRef msg As System.Windows.Forms.Message)
       'Do whatever
    End If

End Sub


Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.