Windows Mobile Developer Network Forum

Windows Mobile Developer Network Forum
It is currently Tue Feb 09, 2010 12:45 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: Modifying Power Button Function
PostPosted: Thu Sep 07, 2006 7:51 am 
Offline

Joined: Thu Sep 07, 2006 7:50 am
Posts: 5
Location: Australia
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.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 08, 2006 12:31 am 
Offline

Joined: Thu May 04, 2006 12:45 pm
Posts: 337
Location: Timisoara, Romania
Maybe this could help:
http://teksoftco.com/forum/viewtopic.php?t=49

Cheers,
Raul

_________________
www.teksoftco.com/forum


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 08, 2006 5:08 am 
Offline

Joined: Thu Sep 07, 2006 7:50 am
Posts: 5
Location: Australia
Thanks for the Raul. I'[ve been looking at how to use hooks since I saw this, and it seems pretty full on for just wanting to catch the power button press. It all seems to be windowed stuff with Callback functions already implemented.

If I could utilise a callback function for the keyboard, I would be set already. Maybe I'm missing something... I am very unsure how to use the SetWindowsHookEx, CallNextHookEx, and UnhookWindowsHookEx.

If anyone can give me an example of how to use it with any one key or anything, that'd be awesome.

Cheers,

Dan.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 11, 2006 4:42 am 
Offline

Joined: Thu Sep 07, 2006 7:50 am
Posts: 5
Location: Australia
Okay, I have tried using these functions, but nothing ever goes into my callback function. In my XXX_INIT function, I have:

Code:
...
ActivateKBHook(GetModuleHandle(NULL), LowLevelKeyboardProc);
...


And my callback function looks like:

Code:
/****************************************************************
  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);
}


That message at the top of the callback never occurs. Sometimes (I don't know what caused it, but it's gone away now), when I pressed a button, it froze the PPC. Well, the PPC would still run in the background, but I couldn't click use the screen at all. I couldn't click anywhere or do anything with it. I had to soft reboot to get it back.

Any ideas on what could be going on? I used the ActivateKBHook and DeactivateKBHook functions from the link that Raul gave me.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 25, 2006 10:38 pm 
Offline

Joined: Mon Apr 03, 2006 1:59 am
Posts: 29
The good news: I think I know what is going wrong. I am trying to hook the procedure myself right now. Read here about the parameters:
SetWindowsHookEx
If the callback is not in a dll and is in the code from the current process, hmod must be 0 and dwThreadId must be the current thread. I used to get the same freeze that you got. Probably means SetWindowsHookEx was working, but failed when trying to call the callback. Now I use this call:

g_hook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, GetCurrentThreadId());

The bad news: now SetWindowsHookEx fails. GetLastError returns Invalid Parameter. :x Any ideas? So close!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 25, 2006 10:56 pm 
Offline

Joined: Mon Apr 03, 2006 1:59 am
Posts: 29
Ok, I tried putting the callback in a seperate dll. In that dll, I just call a message box. Now SetWindowsHookEx succeeds and it doesnt freeze. It does not however show my message box.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 25, 2006 11:58 pm 
Offline

Joined: Thu Sep 07, 2006 7:50 am
Posts: 5
Location: Australia
I ended up getting this to work. The only way I found out how to do it was to put my hook stuff in a windowed app. A much as I tried to get around it, it seemed that it HAD to be in a program with a message loop.

I tried doing a message loop in the DLL, which obviously failed miserably. So I basically took that code I already showed, and just put it in a windowed app, which used my DLL for everything else.

I made the windowed app run in the background by doing:
Code:
// Hide the window
ShowWindow(hWnd, SW_HIDE);
UpdateWindow(hWnd)

In the initiliasation. Then if I ever wanted to see the window again (like to close the program), I went:
Code:
ShowWindow(hWnd, SW_NORMAL);
SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
UpdateWindow(hWnd);


That's the best I came up with. It's worked fine for me for over a month now.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 26, 2006 1:09 am 
Offline

Joined: Mon Apr 03, 2006 1:59 am
Posts: 29
So what makes the difference? Is it just the fact that a window exists? If I just added a create window routine, the function would just work? What exactly do I have to add to my code to get it to work? Basically, my app just creates a message queue, watches that queue for a WM_CLOSE (which is sent by a seperate companion), and exits. I do not have any init instance code or anything (I am kind of a PPC dev novice, so I dont really know what init instance is supposed to do).


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 26, 2006 3:22 am 
Offline

Joined: Thu Sep 07, 2006 7:50 am
Posts: 5
Location: Australia
Just make a new window (or use an existing on in your app), and it'll put a template there for you. Basically, just add this to it:

At the very end on InitInstance (just before returning true):
Code:
// Hide the window - Add this if you don't actually want to see the windowed app.
ShowWindow(hWnd, SW_HIDE);
UpdateWindow(hWnd);

// Setup the keyboard hook
ActivateKBHook(hInstance, LowLevelKeyboardProc);


In the WndProc (the window message handler), in the case of WM_DESTROY, add:
Code:
DeactivateKBHook();


Then just add the ActivateKBHook, DeactivateKBHook, and CALLBACK LowLevelKeyboardProc to the code, and any keypresses will force it to go through the LowLevelKeyboardProc function before anything else. I've added a basic hook function incase you didn't know how it should work.

Code:
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_SPACE:
            //Space bar was pressed.
         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;
}


Hope that explains it.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 26, 2006 4:12 am 
Offline

Joined: Mon Apr 03, 2006 1:59 am
Posts: 29
Ok, thanks for the help. I was able to get the hook working too. And it seems like the documentation is wrong, becuase the only way to get it to work is to set processid to 0 and pass hinstance.

Just wondering, how did you determine that a windowed app was the only way to make it work? What about the window makes the system happy? It seems like such a silly limmitation. Do you think it could be "tricked"? Also, would it be safe to create the window like normal, but not run the message loop, and then destroy the window before I exit? I already have a message queue in place and I don't really want to switch to the other message loop.

Thanks for all the help!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 26, 2006 9:56 pm 
Offline

Joined: Mon Apr 03, 2006 1:59 am
Posts: 29
Hey, sorry to ask again, but... I got it to work in the emulator just fine, but when I try it on a device (WM5) SetWindowsHookEx fails. GetLastError returns ERROR_GEN_FAILURE. Do you think it could be because wm5 handles the parameters differently?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 27, 2006 5:10 am 
Offline

Joined: Mon Apr 03, 2006 1:59 am
Posts: 29
I found the problem. CE 5.0 does not support multiple hooks. My device was also running pqzII.exe, which (I guessed and guessed correctly) also installs a hook. Very bad news for me. I dont want my apps to not work on some people's devices depending on what they have installed. Shame. This was a very promising method. All I wanted to do was detect a press and hold of the power button. GetAsyncKeyState does not work with the power button. Im all out of ideas. Oh well, failed project. :(


Read here. Towards end of page. Past 3/4 down.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group