Modifying Power Button Event

Hi,

This may sound wierd, but I've seen it done before, so I know it's possible.

I would like to have something running (a console based program running in the background on Windows CE) that does it's own thing, but when the user presses the Power Button, it doesn't actually stop everything and go into suspend, but instead just turns the screen off (which I know how to do) and doesn't suspend.

Does anyone know the way I can disable the power button sending hte suspend event and capture the power button key (VK_OFF) event to run my own code I can't seem to find anywhere how to capture a keypress event WITHOUT using a graphic window program. As my application runs in the background, I don't see the need for a windowed application.

Cheers,

Dan.



Answer this question

Modifying Power Button Event

  • DevDiver

    Hi,

    I am suppose to writing program(c# using VS 2005) that required the WM6/WM5 devices to stop the auto-suspend and when the user press the power button, it will off the screen instead of suspending because there is some script that will be running behind.

    Can it be done

    Please reply to my email at alpha_play_a_fool@hotmail.com

    Thank you


  • Stephan Smetsers

    Hello,

    I don't know why, but I can't retreive the VK_OFF event !

    All hard key presses are retreived except the power button press...

    Have you got an idea for me



  • RobSteele

    All good now... I had to have it in a Windowed app, so it had a message function. Also, you can't put messageboxes in the callback function, or it locks your whole system because it can't continue and process anymore key events.

    Anyways, it works well. The power button does what I want it to now, and doesn't shut off the PPC.

    HOWEVER:

    I can only press the power button once for it to work. After that, it never picks it up again. The press enters the callback loop, and the buttom has the right vkCode, and all the other codes are identical to the first time I pressed it... but it doesn't want to recognise it. Strange, no I'm not expecting a response (haven't got one yet), so I'm just writting this for the benifit of people in the future who want to solve the same problem.

    If I get no response, I'll try post the solution to it only working once when I figure it out.


  • StevenR2

    That happened because the VK_OFF only registers as a WM_KEYDOWN once. After that (if you didn't actually power the device off), it will ONLY come in as WM_KEYUP. As I was only checking the WM_KEYDOWN, I couldn't pick up the event
  • DeadDante

    I have a similar problem as you and would like your solution to test.
    I'm using embeddet visual c++ and do not know not exactly, how I can implement your solution.
    Exactly as you would like to start a console based program running in the background on Windows.
    You can give me few tipps for this

    Thanks,
    Sascha

  • Shodin

    To answer myself with some updated information:

    I decided to try use Hooks. I don't think these are implemented in Win CE, so I had to do that myself. However, I still can't get the key hooks to go into my callback function at all. Anyone have any ideas My code is as follows.

    .cpp
    In XXX_Init
    ...
    ActivateKBHook(GetModuleHandle(NULL), LowLevelKeyboardProc);
    ...


    Rest of code:
    //globals
    HINSTANCE g_hHookApiDLL = NULL; //handle to coredll.dll, where all the hook related APIs are present
    HHOOK g_hInstalledLLKBDhook = NULL; //g_hInstalledLLKBDhook represents handle to the installed KB hook

    //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
    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 re done with it
    g_hInstalledLLKBDhook = SetWindowsHookEx(WH_KEYBOARD_LL, LLKeyboardHookCallbackFunction, hInstance, 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
    return true;
    }


    //WINCEKBHOOK_API BOOL DeactivateKBHook()
    BOOL DeactivateKBHook()
    {
    //unload the hook
    if(g_hInstalledLLKBDhook != NULL)
    {
    UnhookWindowsHookEx(g_hInstalledLLKBDhook);
    g_hInstalledLLKBDhook = NULL;
    MessageBox(NULL, L
    "Unhooked Hook", L"Error", MB_OK);
    }
    //unload the coredll.dll
    if(g_hHookApiDLL != NULL)
    {
    FreeLibrary(g_hHookApiDLL);
    g_hHookApiDLL = NULL;
    MessageBox(NULL, L
    "Unloaded DLL", L"Error", MB_OK);
    }
    //we have terminated gracefully
    return true;
    }

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

    LRESULT CALLBACK LowLevelKeyboardProc(
    int nCode, WPARAM wParam, LPARAM lParam)
    {
    MessageBox(NULL, L
    "Callback", L"key", MB_OK);
    CHAR szBuf[128];
    HDC hdc;
    static int c = 0;
    size_t * pcch = 0;
    HRESULT hResult;

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

    hdc = GetDC(NULL);
    hResult = StringCchPrintf(CA2W(szBuf), 128/
    sizeof(TCHAR), L"KEYBOARD - nCode: %d, vk: %d, %d times ", nCode, wParam, c++);
    if (FAILED(hResult))
    {
    // TODO: write error handler
    }
    hResult = StringCchLength(CA2W(szBuf), 128/
    sizeof(TCHAR), pcch);
    if (FAILED(hResult))
    {
    // TODO: write error handler
    }
    MessageBox(NULL, CA2W(szBuf), L
    "key", MB_OK);
    ReleaseDC(NULL, hdc);
    return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
    }


    In the header .h

    #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 code, 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
    typedef struct {
    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

    That's it. It looks like a lot, but it's all mainly there to buiold the functions that didn't exist. I get no errors when I start the DLL, and everything seems to load fine, but my callback function is never entered. Any ideas


  • Pr09aN1g0d

    I implemented the solution. It works very well.
  • Modifying Power Button Event