 |
|
 |
Hi!
I was testing this application on a WM6.5 device. It works well until I open up the start menu. I do that, then press some keys and then close the menu again. The application does not detect the keys I pressed in the menu, nor does it get any further keypresses, even if it's the foreground application.
Could you advise?
Many thanks,
Gabor
|
|
|
|
 |
|
 |
Hello Gabor
this class (I did not provide any form code or application) is designed to show one possibility to catch all keys inside an compact framework application in a global event handler.
If you are looking for a system global keyboard hook, you have to write a C/C++ DLL (or an exe with an export declaration) as you will find some global hook apps here: http://www.hjgode.de/wp/all-posts-list/[^]
If you want to just catch Function Keys if your CF app is in the foreground, just use the AllKeys(True) API call.
If you want to remove the OS action on function keys, you have to unregister these HotKeys (like F1, F2, F3 and so on). There is a sample app on my blog too.
If you still need assistance, please describe your intention in details.
with regards
Josef
|
|
|
|
 |
|
 |
Hello Josef,
first of all, thank you very much for your help. You're site is great.
I need to develop an application which monitors a specific key (say APP5). If the user presses this key multiple times in a short period, I have to create distress message (send an SMS message or whatever), so this function must work whenever the PDA is operational, no matter what application is starting, stopping, or running in the foreground.
I also have to monitor and log phone usage and other information coming in from running applications of the system, so there's a .NET console application that watches the system state, monitors some named WinCE P2P message queues and processes the incoming messages. I was hoping to integrate the distress functionality into this application, but for that this application would have to receive all APP5 keydown events - that's when keyboard hooking came to mind. Now I'm not sure how I should proceed.
How would you do this?
Thank you,
Gabor
|
|
|
|
 |
|
 |
Hi
you have to write another 'service' using C/C++ to hook the keyboard globally and in the hook event function you should fire a special message (WM_USER+xxx) or (easier to catch with .net console app) a named private event. This message or event can then be catched by your .Net console app and you can perform what you want.
On my blog list you will find different examples of C code for hooking: http://www.hjgode.de/wp/all-posts-list/[^]
regards
Josef
|
|
|
|
 |
|
 |
Sounds great, many thanks.
|
|
|
|
 |
|
 |
Hi,
I am trying use it in an application without forms or in an application which works minimized.
Mi objective is created an application working in background waiting any keyboard event. When the event occurs the application has to save in a txt file a text.
The PDA has to work normally until the key were pressed.
Is possible to do it with this? If not, how could I do it?
Thank you very much.
|
|
|
|
 |
|
 |
Yes, you may use this as a keyboard logger but you should implement the file save etc in a separate thread and share a queue with the keystrokes between the hook and the thread.
But I dont would use C# (too much overhead) for that, you better code it in C/C++.
|
|
|
|
 |
|
 |
Hi, I'm testing your code on vb and I've a problem I don't know solve and if it's possible I'd like you help me. This is the problem:
When I show a messagebox the application hangs. Must I capture the message box??
Thanks
|
|
|
|
 |
|
 |
Hello
you should not call ANY blocking functions inside the hook!
If you wish to show a messagebox in your code, use an event or a message that is catched by the main app and then shows the messagebox. In compact framework you can use the MessageWindow class to catch messages send to the form.
pseudo code:
hookfunction
if(condition)
SendMessage(MainFormhWnd, WM_USER+111, 0, 0)
in MessageWindow class
if(msg==WM_USER+111)
MessageBox.Show(TEXT)
You can use lParam and wParam of SendMessage to transfer small data to the receiver.
See also my easy to use Background classes about on how to use MessageWindow: http://www.hjgode.de/wp/2010/06/01/mobile-development-easy-to-use-background-thread-with-gui-update/[^]
|
|
|
|
 |
|
 |
Ok, I understand. This solved my problem. Thank you very much.
Greetings
|
|
|
|
 |
|
 |
The code is like
hookDeleg = new HookProc(HookProcedure);
hHook = WinAPI.SetWindowsHookEx(Constant.WH_KEYBOARD_LL, hookDeleg, WinAPI.GetModuleHandle(null), 0);
if (hHook == 0)
{
int Error = WinAPI.GetLastError();
}
WinAPI.AllKeys(true);
but everytime it is giving error 87 i.e. parameter is incorrect. Can u please help me out of this?
|
|
|
|
 |
|
 |
Looks like you have rewritten the code. As I dont see what you have changed behind the scene, I cant help.
On what OS you are trying to to hook?
|
|
|
|
 |
|
|
 |
|
 |
Working now..i was passing WH_KEYBOARD_LL value as 13
|
|
|
|
 |
|
|
 |
|
 |
To get all keyboard strokes before the OS use AllKeys(True)
|
|
|
|
 |
|
 |
Hello,
in your code above is Allkeys(true) already!?
Where I should use it, too?
Thank you very much!
ths180
|
|
|
|
 |
|
 |
Your code worked great. Wonderful job.
|
|
|
|
 |
|
 |
Hi, I was wondering if there was anyway to use this code but be able to pass through certain keys back to the operating system like the e.handled kind of method.
So most keys I can get and effectively take over their function and they never get seen (e.g. e.handled = true) but some could go back to the system.
I'm asking as I have a PDA that uses one of the function buttons for a barcode scanner and I need to pass back the function button press once I have registered that I know the key was pressed.
Any help would be great.
Thanks for the code its fantastic.
Steven
|
|
|
|
 |
|
 |
Hello
in this code we call a delegate to handle the key:
OnHookEvent(e, keyInfo);
// Yield to the next hook in the chain
return CallNextHookEx(hookDeleg, code, wParam, lParam);
if you return TRUE from the Hook funcion, the key message is marked as handled and removed from the message queue. If you return false or better return the CallNextHookEx function, the key will remain in the msg queue and can be handled by other windows.
You are talking about a KeyPreview/KeyPress/Key_UP/Key_Down dotnet function, where e.cancel=true signals the Compact Framework runtime, that you like to remove the key message. If you just use e.cancel=false, the key should be forwarded (remain in message queue) to other windows.
AFAIK, the scan button to trigger the barcode scanner do not use key message. On Intermec the scanner key does fire two named events and you cannot catch the key press with keyboard hooks or using the windows message queue.
regards
Josef
BTW: AllKeys and the KeyboardHooking described here are totally independent. AllKeys(true) just ensures that your dotnet application will get the keyboard messages delivered for Phone Keys (like VK_TEND) by the message queue and not consumed by the OS (ie phone app).
|
|
|
|
 |
|
 |
Hi,
This is a great piece of code, thank you.
The only thing I don't understand is why am I getting the HookEvent event 2 times when I press a key?
I am using the Windows CE 5.0 emulator with C# 2.0
Thank you
|
|
|
|
 |
|
 |
I have found it. There are 2 events because of KeyDown/KeyUp:
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
const int WM_SYSKEYDOWN = 0x104;
const int WM_SYSKEYUP = 0x105;
if(wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
{
}
else if(wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
{
}
|
|
|
|
 |
|
 |
Fine, that you found it yourself.
It may also happen, that you will get more than two messages for a keystroke, depending on the key you pressed. In example: a big A (Shift+a) will produce this sequence of WM_ messages:
WM_KEYDOWN shift
WM_KEYDOWN a
WM_CHAR A
WM_KEYUP shift
WM_KEYUP a
See also Charles Petzold's great book about windows programming.
regards
Josef
BTW: you can also see this key sequences within my tool called KeyTest3AK.
|
|
|
|
 |
|
 |
that was helpful to me also
|
|
|
|
 |
|
 |
Hi there I do have a problem with that code because the PInvoke Method GetCurrentThreadId could not be found in coredll.dll.
What I'm doin wrong in here?
I'm using Windows CE
|
|
|
|
 |