Handling the power off button in Pocket PC in C#

On Pocket PC intercepting the power button is an elusive task. When we press power button to the switch off device, we are actually putting the device in suspension state.

How can I handle the code if power is being switched off?

There is a way in Pocket PC to detect the power status change through a specialized notification mechanism. Power notifications are requested through the RequestPowerNotifications function it instruct the OS to start sending the appropriate power notification message. Based on these messages the code can be handled if the power is being switched off on the device.

Look at the sample C# code:


public class PowerNotifications

    {      

        IntPtr ptr = IntPtr.Zero;

        Thread t = null;

        bool done = false;

 

        [DllImport("coredll.dll")]

        private static extern IntPtr RequestPowerNotifications(IntPtr hMsgQ, uint Flags);

 

        [DllImport("coredll.dll")]

        private static extern uint WaitForSingleObject(IntPtr hHandle, int wait);

 

        [DllImport("coredll.dll")]

        private static extern IntPtr CreateMsgQueue(string name, ref MsgQOptions options);

 

        [DllImport("coredll.dll")]

        private static extern bool ReadMsgQueue(IntPtr hMsgQ, byte[] lpBuffer, uint cbBufSize, ref uint lpNumRead, int dwTimeout, ref uint pdwFlags);

        public PowerNotifications()

        {

            MsgQOptions options = new MsgQOptions();

            options.dwFlags = 0;

            options.dwMaxMessages = 4;

            options.cbMaxMessage = 256;

            options.bReadAccess = true;

            options.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(options);

            ptr = CreateMsgQueue("PowerNotify", ref options);

            RequestPowerNotifications(ptr, 0xFFFFFFFF);

            t = new Thread(new ThreadStart(DoWork));

            t.Start();            

        }

        public void stop()

        {                 

            done = true;           

        }

        private void DoWork()

        {

            //buf is declared with 8bytes, since 1st 4bytes are used for Powername and 2nd 4bytes are used for the actual power state type

byte[] buf = new byte[8];

            uint nRead = 0, flags = 0, res = 0;

            try

            {

                while (!done)

                {

                    res = WaitForSingleObject(ptr, 1000);

                   

                    if (res == 0)

                    {

                        ReadMsgQueue(ptr, buf, (uint)buf.Length, ref nRead, -1, ref flags);

                        uint flag = ConvertByteArray(buf, 4);

                       

                        switch (flag)

                        {

                            case 2097152:

                               //device is in suspended state. do your opertaion here
                               //MyClass.Executemymethod()                               

                                break;


                            / * other windows message flags
                              

                              65536- Power on

                              131072 – Power off

                              262144 – Power critical

                              524288 – Power Boot

                              1048576 – Power Idle

                              8388608 – Power reset 
                              */

                        }

                    }

                }

                return;

            }

            catch (Exception ex)

            {

             

                        ErrorLog.LogError("My Workerthread",null,

                    Utility.GetDeviceName(), ex, null,

                    ErrorLog.ErrorDisplayType.General, String.Empty);

            }

            }

      

        uint ConvertByteArray(byte[] array, int offset)

        {

            uint res = 0;

            res += array[offset];

            res += array[offset + 1] * (uint)0x100;

            res += array[offset + 2] * (uint)0x10000;

            res += array[offset + 3] * (uint)0x1000000;

            return res;

        }

 

        [StructLayout(LayoutKind.Sequential)]

        public struct MsgQOptions

        {

            public uint dwSize;

            public uint dwFlags;

            public uint dwMaxMessages;

            public uint cbMaxMessage;

            public bool bReadAccess;

        }

    }

Next Recommended Readings