Solved

Intercepting Power Button (Suspend)

Posted on 2004-09-18
7
1,225 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
Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

 
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

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Progress means simplifying, not complicating. Bruno Munari Preface How to detect the name of the internal storage or an SD-card on Windows Mobile device from the desktop application? I got this question, when I was working on a PC applicati…
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 a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

820 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