Detectar el cierre y la apertura de la tapa del portátil

¿Es posible detectar cuándo la tapa de un portátil está abierta o cerrada? Por lo que he leído, esto no es posible, pero SO me ha ayudado con lo imposible antes.

Lo único que he encontrado que podría estar en la dirección correcta es una publicación de blog de MSDN sobre IOCTL necesarios para informar de los botones de encendido . ¿Es posible “olfatear” estos como los llama el sistema operativo?

Estoy usando VB.NET, pero aceptaré sugerencias en cualquier idioma. Gracias por su tiempo y consejo.

Editar : Mi software anulará (eventualmente) las acciones (según la preferencia del usuario) que se produzcan cuando la tapa esté cerrada, por lo que no es una opción escuchar las acciones de suspensión y otras acciones que normalmente ocurren cuando se cierra la tapa.

Completar el código de C # para la aplicación WPF que muestra cómo escuchar los eventos de apertura / cierre de la tapa:

using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; namespace WpfApplication1 { ///  /// Interaction logic for MainWindow.xaml ///  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); } } } } 

Use WM_POWERBROADCAST. Aquí hay un enlace que puede ayudarlo: Lid Close Acción cambiar notificación

Tenga en cuenta que la mayoría de las computadoras portátiles, cuando se cierra la tapa, presiona un botón. Este botón generalmente es solo un botón para dormir. Las clases de WMI exponen el ACPI y lo ideal sería utilizar la clase de gestión de energía. Desafortunadamente, la clase no genera un evento cuando el sistema operativo está configurado para “no hacer nada”. La única forma de evitar esto sería usar el DDK (Driver Development Kit) para crear un filtro que intercepte el evento IOCTL_GET_SYS_BUTTON_EVENT. Aquí hay dos enlaces para ayudarlo a comenzar:

http://blogs.msdn.com/b/doronh/archive/2006/09/08/746834.aspx

y

http://support.microsoft.com/kb/302092

Administración de energía

Manejo de eventos de ahorro de energía El enfoque hasta ahora ha sido la conservación de la duración de la batería mientras se ejecuta su aplicación. Hay una consideración adicional que debe hacer: cómo se comporta su aplicación cuando la computadora suspende el funcionamiento. Hay dos escenarios clave para considerar aquí:

  • Cuando la computadora está inactiva durante un cierto período de tiempo, es probable que el esquema de energía activo especifique que el hardware entre en modo de espera o de hibernación.
  • Cuando el usuario realiza una acción que pone a la computadora en una operación de suspensión, como cerrar la tapa de una computadora portátil o presionar el botón de encendido.

Espero que te dé alguna dirección 🙂