I'm writing a C# app (specifically for laptops) and I want to be aware of the state of the lid, i.e. when is it open and when is it closed.
I've already used pInvoke along with Microsoft's RegisterPowerSettingNotification function with the help of this SO answer.
So, with the above I know when the lid is being closed or opened and know its state, BUT I want to get the state of the lid before anything else continues. I've noticed that even if there is no change to the lid, the callback function is called and I can check its parameter to know the lid's state, but this not good for me since it is an event and I can't simply wait for it to occur (maybe there's another way to work around this?).
I've also tried PowerEnumerate function but couldn't get something from it (maybe there is something I don't know there that could help)
EDIT 1: I can't wait or delay the app, and there are 2 issues that require me to get the state without a CB, the first is that a lid can be closed while the laptop is connected to a monitor thus allowing the user to use the laptop. If the user starts the app in this situation it should not start. The second reason is that I want the app to be user friendly and notify what happens when it starts or stops, and if I get the cb in the wrong time it might be ignored, due to the app's inner logic, and then will have to wait until the next time I get a cb, I'd at all.
So, (no pun intended) Is there a way to get this information right away?
EDIT 2: It seems from comments that it's not clear what I need. I need a way to query to state of the lid. i.e. - call some API or something and that the return value is the state. thanks!
Keywords: GUID_LIDSWITCH_STATE_CHANGE , WM_POWERBROADCAST, Power Setting
Newer laptops use magnets and hall effect sensors to detect every time the display is closed. The sensor typically gets engaged when the lid is closed, turning off the internal LCD. The sensor then moves the display output to the external monitor if present or puts the laptop to sleep or hibernation.
Once the Lid Closing Action is associated with Sleep Mode or some other Power Saving Option, you should notice a considerable improvement in the Battery Life of your Laptop. Another common reason for this issue is due to Fast Startup being enabled by default on most Windows 10 and Windows 11 Laptops.
Click the Windows icon and then the Settings icon, and select System. Go to Power & sleep > Additional power settings > Choose what closing the lid does. Set When I close the lid to Do nothing, and click Save changes.
I don't think 'lid state' is guaranteed to be reflected in the power management properties. Is your interest in the lid state simply down to the monitor? If so, you could find a way to determine the properties of the integrated screen (could be an issue if they install it while connected to an external monitor) and save them. Then check the properties of the screen/s in use and act accordingly.
See System.Windows.Forms.Screen - http://msdn.microsoft.com/en-us/library/system.windows.forms.screen%28v=vs.110%29.aspx
Serial numbers can be extracted from the 'Device Parameters' keys in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY
. How to extract it (along with other info) is demonstrated here:
http://sourceforge.net/p/wmimonitor/code/HEAD/tree/DisplayInfoWMIProvider/WMIProvider/WMIProvider.cs
Alternatively, assuming that the callbacks still fire even if the lid close event in Windows is set to 'Do Nothing', you could perhaps consider a helper process or service to run all the time and keep track of changes. You could share the state via the registry or a file. You could also look into whether any other items of hardware (eg. touchpad) change power state on close regardless of the 'power plan' and use the GetDevicePowerState API function.
So, after a long search led by @Llwyd's answer, I found a solution.
I noticed that when the lid is closed, the device is removed from the device manager, so the solution is to check whether it is there or not.
The code behind it is a bit massive to upload here so I won't, but the following was need:
Identify Internal screen's name\ID with WmiMonitorConnectionParams
and VideoOutputTechnology
and state (DISPLAY_DEVICE_ATTACHED
and/or DISPLAY_DEVICE_ACTIVE
).
Once I know the device's name/ID, I can easily look it up by enumerating System.Windows.Forms.Screen.AllScreens
(or save the value from the DISPLAY_DEVICE_ATTACHED
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With