Clicky

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.

asked 11/21/2011 07:51

weirddemon's gravatar image

weirddemon ♦♦


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

Win32_DesktopMonitor class
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394122(v=VS.85).aspx
link

answered

TheLearnedOne's gravatar image

TheLearnedOne

TheLearnedOne,

Unfortunately, that too does not work. It reports the same as the API. I tried that many days ago, with no luck.
link

answered 2011-11-21 at 17:01:03

weirddemon's gravatar image

weirddemon

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.
link

answered 2011-11-21 at 17:02:41

TheLearnedOne's gravatar image

TheLearnedOne

TheLearnedOne,

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.
link

answered 2011-11-21 at 17:30:36

weirddemon's gravatar image

weirddemon

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
http://msdn.microsoft.com/en-us/library/windows/desktop/aa373223(v=vs.85).aspx
link

answered 2011-11-21 at 17:34:55

TheLearnedOne's gravatar image

TheLearnedOne

http://social.msdn.microsoft.com/Forums/en-US/tabletandtouch/thread/0bbf90be-9322-47fb-bfa4-016b57211b3a

In Vista you can register for a callback for when the Lid Close Action changes.  This is done by calling RegisterPowerSettingNotification (see http://msdn2.microsoft.com/en-us/library/aa373196.aspx 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 http://msdn2.microsoft.com/en-us/library/aa372723.aspx) containing information on the setting change.
link

answered 2011-11-21 at 17:39:22

TheLearnedOne's gravatar image

TheLearnedOne

TheLearnedOne,

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.
link

answered 2011-11-21 at 17:41:09

weirddemon's gravatar image

weirddemon

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.
link

answered 2011-11-21 at 17:43:04

TheLearnedOne's gravatar image

TheLearnedOne

TheLearnedOne,

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?
link

answered 2011-11-21 at 17:49:52

weirddemon's gravatar image

weirddemon

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.
link

answered 2011-11-21 at 17:53:33

ve3ofa's gravatar image

ve3ofa

ve30fa,

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.
link

answered 2011-11-23 at 08:36:48

weirddemon's gravatar image

weirddemon

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

link

answered 2011-11-23 at 11:51:53

Thommy's gravatar image

Thommy

Did you get further with your problem???
link

answered 2011-11-29 at 01:47:37

Thommy's gravatar image

Thommy

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.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
Const PBT_POWERSETTINGCHANGE As Integer = &H8013
Const WM_POWERBROADCAST As Integer = &H218
Const DEVICE_NOTIFY_WINDOW_HANDLE As Integer = &H0
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)
    If msg.Msg = WM_POWERBROADCAST And msg.WParam = PBT_POWERSETTINGCHANGE Then
       'Do whatever
    End If

    MyBase.WndProc(msg)
End Sub

RegisterPowerSettingNotification(Me.Handle, GUID_LIDSWITCH_STATE_CHANGE, DEVICE_NOTIFY_WINDOW_HANDLE)
link

answered 2011-12-04 at 11:13:29

weirddemon's gravatar image

weirddemon

Your answer
[hide preview]

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Tags:

×59
×21
×8
×13
×1
×1
×79
×9

Asked: 11/21/2011 07:51

Seen: 324 times

Last updated: 12/09/2011 09:36