Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect laptop lid closure and opening

Is it possible to detect when a laptop's lid is open or closed? From what I've read, this isn't possible, but SO has helped me with the impossible before.

The only thing I've found that might be in the right direction is an MSDN blog post about IOCTLs needed to report power buttons. Is it possible to "sniff" these as the OS calls them?

I'm using VB.NET, but will take suggestions in any language. Thank you for your time and advice.

Edit: My software will be (eventually) overriding the actions (based on user preference) that occur when the lid is closed, so listening for suspend and other actions that typically occur when the lid is closed isn't an option.

like image 637
Brad Avatar asked Jul 28 '10 17:07

Brad


People also ask

How does laptop detect if lid is closed?

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.

How does laptop detect lid closed HP?

1 Answer. vjlanter, the switch is a magnetic sensor activated by a magnet in the LCD bezel. The power from the motherboard to the Inverter, is cut off when the Display Switch Module is depressed. Use a magnet and swipe it sound the outside bezel of your laptop.

Can I close the lid on my laptop and keep my monitor?

You can keep your screen on when your laptop is closed by altering the laptop's power settings. In Windows, open the Control Panel and go to Power Options to set what happens when the lid is closed. If you have a Mac, open System Preferences and go to the Power Adapter section of the Battery preferences.


1 Answers

Complete working C# code for WPF application that shows how to listen to lid open/close events:

using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop;  namespace WpfApplication1 {     /// <summary>     /// Interaction logic for MainWindow.xaml     /// </summary>     public partial class MainWindow : Window     {         [DllImport(@"User32", SetLastError = true, EntryPoint = "RegisterPowerSettingNotification",             CallingConvention = CallingConvention.StdCall)]          private static extern IntPtr RegisterPowerSettingNotification(IntPtr hRecipient, ref Guid PowerSettingGuid,             Int32 Flags);          internal struct POWERBROADCAST_SETTING         {             public Guid PowerSetting;             public uint DataLength;             public byte Data;         }          Guid GUID_LIDSWITCH_STATE_CHANGE = new Guid(0xBA3E0F4D, 0xB817, 0x4094, 0xA2, 0xD1, 0xD5, 0x63, 0x79, 0xE6, 0xA0, 0xF3);         const int DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000;         const int WM_POWERBROADCAST = 0x0218;         const int PBT_POWERSETTINGCHANGE = 0x8013;          private bool? _previousLidState = null;          public MainWindow()         {             InitializeComponent();             this.SourceInitialized += MainWindow_SourceInitialized;         }          void MainWindow_SourceInitialized(object sender, EventArgs e)         {             RegisterForPowerNotifications();             IntPtr hwnd = new WindowInteropHelper(this).Handle;             HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));         }          private void RegisterForPowerNotifications()         {             IntPtr handle = new WindowInteropHelper(Application.Current.Windows[0]).Handle;             IntPtr hLIDSWITCHSTATECHANGE = RegisterPowerSettingNotification(handle,                  ref GUID_LIDSWITCH_STATE_CHANGE,                  DEVICE_NOTIFY_WINDOW_HANDLE);         }          IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)         {             switch (msg)             {                 case WM_POWERBROADCAST:                     OnPowerBroadcast(wParam, lParam);                     break;                 default:                     break;             }             return IntPtr.Zero;         }          private void OnPowerBroadcast(IntPtr wParam, IntPtr lParam)         {             if ((int)wParam == PBT_POWERSETTINGCHANGE)             {                 POWERBROADCAST_SETTING ps = (POWERBROADCAST_SETTING)Marshal.PtrToStructure(lParam, typeof(POWERBROADCAST_SETTING));                 IntPtr pData = (IntPtr)((int)lParam + Marshal.SizeOf(ps));                 Int32 iData = (Int32)Marshal.PtrToStructure(pData, typeof(Int32));                 if (ps.PowerSetting == GUID_LIDSWITCH_STATE_CHANGE)                 {                     bool isLidOpen = ps.Data != 0;                      if (!isLidOpen == _previousLidState)                     {                         LidStatusChanged(isLidOpen);                     }                      _previousLidState = isLidOpen;                 }             }         }          private void LidStatusChanged(bool isLidOpen)         {             if (isLidOpen)             {                 //Do some action on lid open event                 Debug.WriteLine("{0}: Lid opened!", DateTime.Now);             }             else             {                 //Do some action on lid close event                 Debug.WriteLine("{0}: Lid closed!", DateTime.Now);             }         }     } } 
like image 94
broslav Avatar answered Sep 20 '22 20:09

broslav