Solved

Intercepting Power Button (Suspend)

Posted on 2004-09-18
7
1,202 Views
Last Modified: 2013-11-18
Does anyone know how to control or intercept the power button of the PDA from inside of software?

I am working on a .NET CF project right now, and I need to prevent the PDA from shuting down/suspending until I can do some exit porcessing.  It looks like when the power button is hit it sends a vk_off message.  

I'm working in C# in the .Net Compact Framework.  From what I can figure out, it looks like I need to do it in the WinCE API.  A P/Invoke or maybe a Keyboard hook proc are my current thoughts.  

Thanks for any help and insight ...



0
Comment
Question by:cdoggett
7 Comments
 
LVL 48

Expert Comment

by:Mikal613
ID: 12102639
You can't detect the power button (unless the device manufacturer provides this via SDK) however you can detect if the device has been suspended when it is resumed. Check out this thread :

http://www.opennetcf.org/Forums/topic.asp?TOPIC_ID=587
0
 
LVL 23

Expert Comment

by:rama_krishna580
ID: 12109060
Hi,

1. You might be able to RegisterHotKey( ... VK_OFF ... ) and do something. Is that what you're talking about? Preventing the user from shutting off the device when he wants to?

2. Well, you generally don't get notified if the device goes to sleep on its own, so I don't think that VK_OFF is going to help. Further, even if you write a driver, you don't get a notification where you can call any APIs to speak of.

3. Needs to discuss this with the OEM. you should not need to do anything from your application to allow the device to restart.

R.K
0
 
LVL 3

Expert Comment

by:Scoobyed
ID: 12142792
also with opennetcf, can launch an app on device wake event

Dim strExecutableOnWake As String = "/Program Files/myApp/myApp.exe"
Dim intResult As Integer
OpenNETCF.Win32.Notify.UserNotificationsARL.RunApplicationOnWake(strExecutableOnWake, CMD_APP_WAKEUP)
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 3

Accepted Solution

by:
Scoobyed earned 500 total points
ID: 12143122
oops, the enum
Private Const CMD_APP_WAKEUP As String = "WAKEUP"

it also looks like I've butchered the opennetcf by adding our own code for this (not sure why, should be available in proper opennetcf)

using System;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;

namespace OpenNETCF.Win32.Notify
{
      /// <summary>
      /// Summary description for NotifyARL.
      /// </summary>
      [CLSCompliant(false)]
      public sealed class UserNotificationsARL
      {
            // Methods for memory allocation and marshalling.
            private const uint LMEM_FIXED = 0;
            private const uint LMEM_ZEROINIT = 0x0040;
            private const uint LPTR = (LMEM_FIXED | LMEM_ZEROINIT);

            private static IntPtr AllocHLocal( int bytes )
            {
                  return( LocalAlloc(LPTR, (uint)bytes) );
            }

            private static void FreeHLocal( IntPtr hLocal )
            {
                  if( hLocal != IntPtr.Zero )
                  {
                        if( IntPtr.Zero != LocalFree(hLocal) )
                        {
                              throw new Win32Exception( Marshal.GetLastWin32Error() );
                        }
                        hLocal = IntPtr.Zero;
                  }
            }

            private static IntPtr StringToHLocal( string s )
            {
                  if( s == null )
                  {
                        return( IntPtr.Zero );
                  }
                  else
                  {
                        int nc = s.Length;
                        int len = 2*(1+nc);
                        IntPtr hLocal = AllocHLocal( len );
                        if( hLocal == IntPtr.Zero )
                        {
                              throw new OutOfMemoryException();
                        }
                        else
                        {
                              Marshal.Copy( s.ToCharArray(), 0, hLocal, s.Length );
                              return( hLocal );
                        }
                  }
            }
       

            // Platform invoke declarations and calls
            [DllImport("coredll.dll",SetLastError=true)]
            private static extern IntPtr LocalAlloc(
                  uint uFlags,
                  uint uBytes
                  );

            [DllImport("coredll.dll",SetLastError=true)]
            private static extern IntPtr LocalFree(
                  IntPtr hMem
                  );

            [DllImport("coredll.dll",SetLastError=true)]
            private static extern IntPtr CeSetUserNotificationEx(
                  IntPtr h,
                  ref CE_NOTIFICATION_TRIGGER nt,
                  ref CE_USER_NOTIFICATION un
                  );

            [DllImport("coredll.dll",SetLastError=true)]
            private static extern IntPtr CeSetUserNotificationEx(
                  IntPtr h,
                  ref CE_NOTIFICATION_TRIGGER nt,
                  IntPtr un
                  );


            [DllImport("coredll.dll",SetLastError=true)]
            private static extern void GetSystemTime(
                  out SYSTEMTIME lpSystemTime
                  );

            [DllImport("coredll.dll",SetLastError=true)]
            private static extern bool SystemTimeToFileTime(
                  ref SYSTEMTIME lpSystemTime,
                  out long lpFileTime
                  );

            [DllImport("coredll.dll",SetLastError=true)]
            private static extern bool FileTimeToLocalFileTime(
                  ref long lpFileTime,
                  out long lpLocalFileTime
                  );

            [DllImport("coredll.dll",SetLastError=true)]
            private static extern bool FileTimeToSystemTime(
                  ref long lpFileTime,
                  out SYSTEMTIME lpSystemTime
                  );

            private static SYSTEMTIME DateTimeToSystemTime( DateTime dateTime )
            {
                  SYSTEMTIME systemTime;
                  long fileTime = dateTime.ToFileTime();
                  FileTimeToLocalFileTime( ref fileTime, out fileTime );
                  FileTimeToSystemTime( ref fileTime, out systemTime );
                  return( systemTime );
            }

            // Structures. Note that all structures are LayoutKind.Sequential
            // on the .NET Compact Framework and there is no need to
            // plaform invoke [StructLayout(LayoutKind.Sequential)].

            private struct SmartString: IDisposable
            {
                  public IntPtr szString;
           
                  public SmartString( string s )
                  {
                        szString = StringToHLocal( s );
                  }

                  public void Dispose()
                  {
                        FreeHLocal( szString );
                  }
            }

            private struct CE_NOTIFICATION_TRIGGER: IDisposable
            {
                  public uint                    dwSize;
                  public CNT_TYPE                dwType;
                  public NOTIFICATION_EVENT    dwEvent;
                  public SmartString            lpszApplication;
                  public SmartString            lpszArguments;
                  public SYSTEMTIME            startTime;
                  public SYSTEMTIME            endTime;

                  public CE_NOTIFICATION_TRIGGER( string application, string arguments,  
                        DateTime start )
                  {
                        dwSize  = (uint)Marshal.SizeOf( typeof(CE_NOTIFICATION_TRIGGER) );
                        dwType  = CNT_TYPE.CNT_TIME;
                        dwEvent = NOTIFICATION_EVENT.NONE;
       
                        lpszApplication    = new SmartString( application );
                        lpszArguments    = new SmartString( arguments );

                        startTime = DateTimeToSystemTime( start );
                        endTime = new SYSTEMTIME();
                  }

                  public CE_NOTIFICATION_TRIGGER( DateTime start )
                  {
                        dwSize  = (uint)Marshal.SizeOf( typeof(CE_NOTIFICATION_TRIGGER) );
                        dwType  = CNT_TYPE.CNT_TIME;
                        dwEvent = NOTIFICATION_EVENT.NONE;
       
                        lpszApplication    = new SmartString( null );
                        lpszArguments    = new SmartString( null );

                        startTime = DateTimeToSystemTime( start );
                        endTime = new SYSTEMTIME();
                  }

                  public CE_NOTIFICATION_TRIGGER( string application, string arguments,
                        NOTIFICATION_EVENT notificationEvent )
                  {
                        dwSize  = (uint)Marshal.SizeOf( typeof(CE_NOTIFICATION_TRIGGER) );
                        dwType  = CNT_TYPE.CNT_EVENT;
                        dwEvent = notificationEvent;
       
                        lpszApplication    = new SmartString(application);
                        lpszArguments    = new SmartString(arguments);

                        startTime = DateTimeToSystemTime( DateTime.Now );
                        endTime = new SYSTEMTIME();
                  }

                  public CE_NOTIFICATION_TRIGGER( NOTIFICATION_EVENT notificationEvent )
                  {
                        dwSize  = (uint)Marshal.SizeOf( typeof(CE_NOTIFICATION_TRIGGER) );
                        dwType  = CNT_TYPE.CNT_EVENT;
                        dwEvent = notificationEvent;
       
                        lpszApplication    = new SmartString( null );
                        lpszArguments    = new SmartString( null );

                        startTime = DateTimeToSystemTime( DateTime.Now );
                        endTime = DateTimeToSystemTime( DateTime.Now.AddDays(1) );
                  }

                  public void Dispose()
                  {
                        lpszApplication.Dispose();
                        lpszArguments.Dispose();
                  }
            }

            public enum ActionFlags
            {
                  PUN_LED     = 1,
                  PUN_VIBRATE = 2,
                  PUN_DIALOG  = 4,
                  PUN_SOUND   = 8,
                  PUN_REPEAT  = 16
            }

            private struct CE_USER_NOTIFICATION: IDisposable
            {
                  public ActionFlags actionFlags;
                  public SmartString pwszDialogTitle;
                  public SmartString pwszDialogText;
                  public SmartString pwszSound;
                  public uint           dwMaxSound;
                  public uint           dwReserved;

                  public CE_USER_NOTIFICATION( string title, string text )
                  {
                        actionFlags = ActionFlags.PUN_DIALOG;
                        pwszDialogTitle = new SmartString( title );
                        pwszDialogText = new SmartString( text );
                        pwszSound = new SmartString( null );
                        dwMaxSound = 0;
                        dwReserved = 0;
                  }

                  public void Dispose()
                  {
                        pwszDialogTitle.Dispose();
                        pwszDialogText.Dispose();
                        pwszSound.Dispose();
                  }

            }

            private enum CNT_TYPE: uint
            {
                  CNT_EVENT        = 1,
                  CNT_TIME        = 2,
                  CNT_PERIOD        = 3,
                  CNT_CLASSICTIME = 4
            }

            public enum NOTIFICATION_EVENT: uint
            {
                  NONE           = 0,
                  TIME_CHANGE    = 1,
                  SYNC_END       = 2,
                  ON_AC_POWER    = 3,
                  OFF_AC_POWER   = 4,
                  NET_CONNECT    = 5,
                  NET_DISCONNECT = 6,
                  DEVICE_CHANGE  = 7,
                  IR_DISCOVERED  = 8,
                  RS232_DETECTED = 9,
                  RESTORE_END    = 10,
                  WAKEUP         = 11,
                  TZ_CHANGE      = 12
            }

            private struct SYSTEMTIME
            {
                  public ushort Year;
                  public ushort Month;
                  public ushort DayOfWeek;
                  public ushort Day;
                  public ushort Hour;
                  public ushort Minute;
                  public ushort Second ;
                  public ushort MilliSecond;
            }

            // Methods used by the application.
            private static DateTime SystemTimeToDateTime( SYSTEMTIME dateTime )
            {
                  long lpFileTime;
                  SystemTimeToFileTime( ref dateTime, out lpFileTime );
                  return( DateTime.FromFileTime( lpFileTime ) );
            }

            public static void RunApplication( string application, string arguments,                    DateTime start )
            {
                  CE_NOTIFICATION_TRIGGER nt =
                        new CE_NOTIFICATION_TRIGGER( application, arguments, start );

                  using( nt )
                  {
                        IntPtr hNotify = CeSetUserNotificationEx( IntPtr.Zero, ref nt, IntPtr.Zero );
                   
                        if( hNotify == IntPtr.Zero )
                        {
                              throw new Win32Exception( Marshal.GetLastWin32Error() );
                        }
                  }
            }

            public static void RunApplication( string application, string arguments, NOTIFICATION_EVENT notificationEvent )
            {
                  CE_NOTIFICATION_TRIGGER nt =
                        new CE_NOTIFICATION_TRIGGER( application, arguments, notificationEvent );

                  using( nt )
                  {
                        IntPtr hNotify = CeSetUserNotificationEx( IntPtr.Zero, ref nt, IntPtr.Zero );
                   
                        if( hNotify == IntPtr.Zero )
                        {
                              throw new Win32Exception( Marshal.GetLastWin32Error() );
                        }
                  }
            }

            public static void RunApplicationOnWake( string application, string arguments)
            {
                  NOTIFICATION_EVENT notificationEvent;
                  notificationEvent = NOTIFICATION_EVENT.WAKEUP;
                  CE_NOTIFICATION_TRIGGER nt = new CE_NOTIFICATION_TRIGGER( @application, arguments, notificationEvent );
                  using( nt )
                  {
                        IntPtr hNotify = CeSetUserNotificationEx( IntPtr.Zero, ref nt, IntPtr.Zero );
                   
                        if( hNotify == IntPtr.Zero )
                        {
                              throw new Win32Exception( Marshal.GetLastWin32Error() );
                        }
                  }
            }

            public static void NotifyDialog( string title, string text, DateTime start )
            {
                  CE_NOTIFICATION_TRIGGER nt =
                        new CE_NOTIFICATION_TRIGGER( start );
           
                  CE_USER_NOTIFICATION un = new CE_USER_NOTIFICATION( title, text );

                  using( nt )
                  using( un )
                  {
                        IntPtr hNotify = CeSetUserNotificationEx( IntPtr.Zero, ref nt, ref un );
                   
                        if( hNotify == IntPtr.Zero )
                        {
                              throw new Win32Exception( Marshal.GetLastWin32Error() );
                        }
                  }
            }

            public static void NotifyDialog( string title, string text,  
                  NOTIFICATION_EVENT notificationEvent )
            {

                  CE_NOTIFICATION_TRIGGER nt =
                        new CE_NOTIFICATION_TRIGGER( notificationEvent );

                  CE_USER_NOTIFICATION un = new CE_USER_NOTIFICATION( title, text );

                  using( nt )
                  using( un )
                  {
                        IntPtr hNotify = CeSetUserNotificationEx( IntPtr.Zero, ref nt, ref un );
                   
                        if( hNotify == IntPtr.Zero )
                        {
                              throw new Win32Exception( Marshal.GetLastWin32Error() );
                        }
                  }
            }
      }
}

oh, and un hook it afterwards
OpenNETCF.Win32.Notify.Notify.RunAppAtEvent(strExecutableOnWake, OpenNETCF.Win32.Notify.NotificationEvent.None)

...I wish I hadn't bothered posting that 'little' suggestion now
0
 
LVL 3

Expert Comment

by:Scoobyed
ID: 12143180
by un hook it afterwards, I mean on application exit (otherwise will launch app every wake event - as many times as is registered if not unhooked)

...I'll get me coat
0
 

Author Comment

by:cdoggett
ID: 12160649
Thanks for the tips, all processing has to be done before it goes into suspend mode though.  

I think I found the code to do a keyboard hook.  Converted code to .net CF, however in CF I can't figure out how to get the app instance which I need to associate the hook proc with an instance.

Thanks again...

Craig
0
 

Author Comment

by:cdoggett
ID: 12185833
Still need a solution for this.  I'm getting desperate for a solution.  I need a way to intercept the power key.  

I have tried registerhotkey and various flavors of keyboard hooks, via p/invokes.  This is in c# .net compact framework which is the bottleneck.

Thanks!!
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Bluetooth keeps crashing on Samsung Galaxy S6 edge 4 43
cell phone battery.. 6 79
change to a different email 5 37
maxBlock challenge 30 101
With Windows Embedded Handheld, called Windows Mobile, Microsoft re-designed the user interface. The Start Icon moved down to the bottom, inside the menu bar area.   If you need to hide the Start Icon and/or the SIP (soft input panel, softwar…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now