How to prevent user from powering off the PDA

Dear all,

I'm working for a communication program. I found if I power off the PDA when my program is in 'talking' state (sending and receiving RTP packets using socket), the system will be frozen and dead when I power on. So I decide not to allowed user to power off during talking.

I could use SystemIdleTimerReset() to disable auto power off, but I don't know how to prevent the 'manual' power off. I know there must be a way, because I see Tomtom could do it. Could anyone give me a hint?

Thanks in advance!

Yun

[558 byte] By [YunXu] at [2007-12-24]
# 1
I would really like to know this too. If anyone has any ideas, could you please help?
kuntushi at 2007-10-8 > top of Msdn Tech,Smart Device Development,Smart Devices Native C++ Development...
# 2

I've found some stuff on power. Namely the POWER_ACTION_POLICY in which it looks like you can change your the way in which a power down will occur. I guess alternatively, you could somehow change the power down status, so that the power down/suspend event is ignored and then you yourself use the VK_OFF keyboard event to do whatever you want.

kuntushi at 2007-10-8 > top of Msdn Tech,Smart Device Development,Smart Devices Native C++ Development...
# 3

If you are still interested, I've done it in my application.

Basically you have to set up a keyboard hook. I read things saying these weren't available in Wndows CE 5.0, but I tried my app on that platform, and it worked.

The whole code is as follows:

#include <tpcshell.h>

// Sets up the keyboard hook for the device
//WINCEKBHOOK
_API BOOL ActivateKBHook(HINSTANCE hInstance, HOOKPROC LLKeyboardHookCallbackFunction)
BOOL ActivateKBHook(HINSTANCE hInstance, HOOKPROC LLKeyboardHookCallbackFunction)
{
//we need to manually load these standard Win32 API calls
//MSDN states that these aren't supported in WinCE
SetWindowsHookEx = NULL;
CallNextHookEx = NULL;
UnhookWindowsHookEx = NULL;

//now load the coredll.dll
g_hHookApiDLL = LoadLibrary(_T("coredll.dll"));
if
(g_hHookApiDLL == NULL)
{
//something is awfully wrong
//the dll has to be present
MessageBox(NULL, L"Can't Load coredll", L"Error", MB_OK);
return
false;
}
else
{
//load the SetWindowsHookEx API call
//the SetWindowsHookEx function installs an application-defined hook procedure into a hook chain.
//You would install a hook procedure to monitor the system for certain types of events.
//here we use use the hook to monitor kyeboard events
SetWindowsHookEx = (_SetWindowsHookExW)GetProcAddress(g_hHookApiDLL, _T("SetWindowsHookExW"));
if
(SetWindowsHookEx == NULL)
{
//this means that MS has really stopped supporting this API in WinCE
MessageBox(NULL, L"Can't use SetWindowsHookEx!", L"Error", MB_OK);
return
false;
}
else
{
//install the KB hook
//the handle needs to be saved for default processing of the events and to uninstall the hook, once we are done with it
g_hInstalledLLKBDhook = SetWindowsHookEx(WH_KEYBOARD_LL, LLKeyboardHookCallbackFunction, NULL, 0);
if
(g_hInstalledLLKBDhook == NULL)
{
MessageBox(NULL, L
"Can't Set Hook", L"Error"
, MB_OK);
return
false;
}
}

//load CallNextHookEx() API call
//the CallNextHookEx function passes the hook information to the next hook procedure in the current hook chain.
//we use this call for default processing of events.
CallNextHookEx = (_CallNextHookEx)GetProcAddress(g_hHookApiDLL, _T("CallNextHookEx"));
if
(CallNextHookEx == NULL)
{
MessageBox(NULL, L
"Can't Call Hook", L"Error"
, MB_OK);
return
false;
}

//load UnhookWindowsHookEx() API
//the UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.
//we use this call to unistall the hook.
UnhookWindowsHookEx = (_UnhookWindowsHookEx)GetProcAddress(g_hHookApiDLL, _T("UnhookWindowsHookEx"));
if
(UnhookWindowsHookEx == NULL)
{
MessageBox(NULL, L
"Can't Unhook Hook", L"Error"
, MB_OK);
return
false;
}
}

//all the APIs are loaded and the application is hooked
returntrue;
}
// Unhooks teh keyboard so it can function without this program
//WINCEKBHOOK_API BOOL DeactivateKBHook()
BOOL DeactivateKBHook()
{
//unload the hook
if(g_hInstalledLLKBDhook != NULL)
{
UnhookWindowsHookEx(g_hInstalledLLKBDhook);
g_hInstalledLLKBDhook = NULL;
}
//unload the coredll.dll
if(g_hHookApiDLL != NULL)
{
FreeLibrary(g_hHookApiDLL);
g_hHookApiDLL = NULL;
}
//we have terminated gracefully
returntrue;
}

/****************************************************************
WH_KEYBOARD_LL hook procedure
****************************************************************/

LRESULT CALLBACK LowLevelKeyboardProc(
int
nCode, WPARAM wParam, LPARAM lParam)
{

PKBDLLHOOKSTRUCT kb = (PKBDLLHOOKSTRUCT)lParam;
SHSendBackToFocusWindow(nCode,wParam,lParam);
LRESULT lResult = 0;

// Do not process message
if (nCode < 0)
return
CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);

if ((nCode == HC_ACTION) )
{
switch
(kb->vkCode)
{
case
VK_OFF:
// Don't send the off message to the system
lResult = 1;
break;
}
}

// Pass it along so it can be processed
if (lResult == 0)
lResult = CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);

// Return true if hook was handled, false to pass it on
return lResult;
}

That all goes in your C file. For your header file:

#ifndef _WINCE_KB_HOOK_H
#define
_WINCE_KB_HOOK_H
//used for passing to SetWindowsHookEx funtion to set a Low level (LL) keyboard hook
#define WH_KEYBOARD_LL 20
// Define the function types used by hooks
typedef LRESULT (CALLBACK* HOOKPROC)(int nCode, WPARAM wParam, LPARAM lParam);
typedef
HHOOK (WINAPI *_SetWindowsHookExW)(int, HOOKPROC, HINSTANCE, DWORD);
typedef
LRESULT (WINAPI *_CallNextHookEx)(HHOOK, int, WPARAM, LPARAM);
typedef
LRESULT (WINAPI *_UnhookWindowsHookEx)(HHOOK);
// For the low level keyboard hook, your keyboards procedures is passed a pointer to KBDLLHOOKSTRUCT instance
typedefstruct {
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
// Win32 Hook APIs
static _SetWindowsHookExW SetWindowsHookEx;
static
_UnhookWindowsHookEx UnhookWindowsHookEx;
static
_CallNextHookEx CallNextHookEx;
//WINCEKBHOOK_API BOOL ActivateKBHook(HINSTANCE hInstance, HOOKPROC LLKeyboardHookCallbackFunction);
BOOL ActivateKBHook(HINSTANCE hInstance, HOOKPROC LLKeyboardHookCallbackFunction);
//WINCEKBHOOK_API BOOL DeactivateKBHook();
BOOL DeactivateKBHook();
#endif

And that's it. It should all work for you now.

kuntushi at 2007-10-8 > top of Msdn Tech,Smart Device Development,Smart Devices Native C++ Development...