Détecter ordinateur portable couvercle fermeture et ouverture

Est-il possible de détecter quand le couvercle d'un ordinateur portable est ouvert ou fermé? D'après ce que j'ai lu, ce n'est pas possible, mais cela m'a aidé avec l'impossible avant.

La seule chose que j'ai trouvée qui pourrait être dans la bonne direction est un article de blog MSDN sur les IOCTLs nécessaires pour signaler les boutons d'alimentation. Est-il possible de" renifler " ceux-ci comme l'OS les appelle?

J'utilise VB.NET, mais prendra des suggestions dans n'importe quelle langue. Je vous remercie pour votre temps et conseil.

Edit : Mon logiciel remplacera (éventuellement) les actions (basées sur les préférences de l'utilisateur) qui se produisent lorsque le couvercle est fermé, donc écouter la suspension et d'autres actions qui se produisent généralement lorsque le couvercle est fermé n'est pas une option.

26
demandé sur Brad 2010-07-28 21:25:07

4 réponses

Code C # de travail complet pour l'application WPF qui montre comment écouter les événements d'ouverture/fermeture du couvercle:

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);
            }
        }
    }
}
15
répondu broslav 2014-04-27 18:29:12

Utilisez WM_POWERBROADCAST. Voici un lien qui peut vous aider: Lid Close action change notification

8
répondu Zabba 2010-07-28 17:53:27

Gardez à l'esprit que la plupart des ordinateurs portables, lorsque le couvercle se ferme, il appuie sur un bouton. Ce bouton est généralement juste un bouton de veille. Les classes WMI exposent L'ACPI et vous souhaiteriez idéalement utiliser la classe PowerManagement. Malheureusement, la classe ne déclenche pas d'événement lorsque le système d'exploitation est défini sur "Ne rien faire". La seule façon de contourner cela serait d'utiliser le DDK (Driver Development Kit) pour créer un filtre qui intercepte L'événement ioctl_get_sys_button_event. Voici deux liens pour vous aider commencer:

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

Et

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

5
répondu Icemanind 2010-07-28 18:00:59

Gestion De L'Alimentation

Gestion Des Événements D'Économie D'Énergie L'accent a été jusqu'ici sur la conservation de la vie de la batterie pendant que votre application est en cours d'exécution. Il y a une considération supplémentaire que vous devriez faire: comment votre application se comporte lorsque l'ordinateur suspend le fonctionnement. Il y a deux scénarios clés à considérer ici:

  • lorsque l'ordinateur est inactif pendant une certaine période de temps, le schéma d'alimentation active est susceptible de spécifier que le matériel soit passe en mode veille ou veille prolongée.
  • Lorsque l'utilisateur effectue une action qui met l'ordinateur en une suspension de l'exploitation, tels que , fermer le couvercle d'un ordinateur portable ou en appuyant sur le bouton d'alimentation.

J'espère que cela vous donnera une direction:)

0
répondu Lukasz Madon 2010-07-28 17:45:45