Hooking Windows events in compact framework

R

Ralph Flaugher

In the full .NET framework you can hook Windows events
using the WIN32 function SetWindowsHookEx. This function
does not appear to be included in the CE API. Is there
another method which can be utilized to accomplish this in
the compact framework?
 
P

Paul G. Tobey [eMVP]

I think there's been substantial traffic on this before. Have you checked
the newsgroup archives?

http://groups.google.com/groups?hl=...soft.public.dotnet.framework.compactframework

You can't have the hook be written in .NET CF, but you can write a C/C++
native DLL which calls SetWindowsHookEx(), implements the hook function and
maybe posts messages to a MessageWindow subclass in .NET CF. I've done this
to catch Tab keys in dialogs to move the focus around...

Paul T.
 
R

Ralph Flaugher

As I mentioned in my original posting, SetWindowHookEx does not appear
to be available in Windows CE. At least according to the documnetation
I have been able to find. Do you know differently? If it is available
then this should not be a problem.

Thanks,

Ralph
 
R

Ralph Flaugher

Thanks. That was my first thought as well. However, as I
mentioned in my original email, I can't find anything in
the documentation for SetWindowsHookEx that indicates it
is available in Windows CE. From what you indicate it is
available. If so, do you know in which DLL it is located?

Ralph
 
P

Paul G. Tobey [eMVP]

Yes, that's right. The documentation doesn't list it. However, it is
present and you can call it like this:

localHook = SetWindowsHookEx( WH_KEYBOARD_LL, ... );

I believe it's in coredll, but you would not want to call it directly from
..NET CF.

Paul T.
 
R

Ralph Flaugher

Thanks, that information makes things a lot easier.
However, just out of curiosity, why not call it from
within .NET CF?

Ralph
 
P

Paul G. Tobey [eMVP]

I don't believe that the necessary machinery is present in .NET CF to do
that. Also, since you'd have to define all of the message constants
(WM_KEYDOWN, WM_CHAR, etc.), plus do the message cracking, I think you'll
get done sooner if you just do the hooking in C++ and pass something to a
MessageWindow subclass in the .NET CF to handle communications from the hook
routine. It's not super fast, but it seems to be very reliable.

Paul T.
 
P

Paul G. Tobey [eMVP]

What code value are you passing to SetWindowsHookEx()? Not all of the Win32
desktop values are supported (I've only used the keyboard one for low-level
keyboard input).

Paul T.
 
P

Paul G. Tobey [eMVP]

Here's my call to SetWindowsHookEx():

localHook = SetWindowsHookEx( WH_KEYBOARD_LL,
&TabHook,
(HINSTANCE)hMod,
0 /* Associate with current thread */ );

This works fine for me, but I'm hooking from a C++ DLL and the hook routine
is in that DLL...

I'm running Windows CE.NET, so more like PPC 2003 than 2002, and I am using
eVC 4.

Paul T.
 
R

Ralph Flaugher

I am using 13 as well. Where did you find that the
correct value should be 20?

Ralph
 
R

Ralph Flaugher

No, unfortuabtely I haven't gotten as far as you. I
haven't figured out what generates a keyboard event yet.
Does the SIP? It doesn't seem to me for me.

Incidently, I tried all values of event types from 0 to
63. 20 is the only value that will work in
SetWindowsHookEx. If this is for keyboard events there
must be no way of hooking mouse events then, which is what
I am trying to do. This whole area seems to be
undocumented and confusing for CE. Others have done it,
so it must be possible, but how is the question that never
seems to get answered in the threads I've seen.

I would appreciate you keeping me informed of any progress
you make. Feel free to email me directly, if you prefer.

Ralph
 
C

Chris Tacke, eMVP

The issue is that CE doesn't officially support *any* hooks. I think that
the keyboard is the only one that has any of the internals included in the
kernel.
 
T

Tibor Meinczinger

Paul,

I have the same code, and it seems to work. But my
MessageWindow subclass gets always the same message.
I have logged the callback func it the unmanaged dll,
but the same, it gets always the same message (resp.
lParam is diferrent when pressing/releasing, but the
rest is the same).
Is it possible, that the os (Pocket PC in my case)
does not really support this
and send always the same dummy message?
Thanks,

Tibor
 
T

Tibor Meinczinger

I have spent quite a lot of time on this topic,
and I have read several times in some newsgroups, that
mouse events are not supported at all. What kind of a
device do you have that you have some mouse?
I am trying to catch the keyboard events. The problem is,
that I always get the same message...

Tibor
 
R

Ralph Flaugher

Ok, I'll buy that, but how then does the guy who is
selling the widgets controls accomplish what his product
accomplishes? He must be doing something "unofficial",
but what? I was hoping to not have to spend a $1000 just
to get a mouse click event in a treeview control.

Ralph
 
P

Paul G. Tobey [eMVP]

It's up to you to send whatever message you want from your hook routine to
your MessageWindow subclass. I register my own message using
RegisterWindowMessage() (on both ends), and then pass that, along with
whatever information I need, to the MessageWindow.

Paul T.
 
T

Tibor Meinczinger

Paul,

isn't the RegisterWindowMessage there to register new
messages? I would like to pass the keyboard events as a
message to my managed MessageWindow. Some extract of my
sources:

LRESULT CALLBACK Handler(int nCode, WPARAM wParam,
LPARAM lParam)
{
fprintf(_f, "%d:%d:%ld\n", nCode, wParam, lParam);
PostMessage(handle_to_notify, nCode, wParam, lParam);
return NextHookProc(hook, nCode, wParam, lParam);
}

HOOKLIB_API HHOOK SetKeyboardHook(HWND handle)
{
hook = (*SetHookProc)(WH_KEYBOARD_LL, Handler, hDll, 0);
return hook;
}

What I thougt is, that after setting the hook, the
function "Handler" will be always called, when the user
hits some key, lParam and wParam containing the
information, which key. The function is called, but lParam
and wParam always have the same value, nCode is always 0.

Maybe I have some general misunderstanding concerning the
whole issue.

Thanks,
Tibor
 
T

Tibor Meinczinger

Paul,

I have again a problem, I hope you (or somebody else have
an idea). I try to implement two things:
- tabbing (focusing)
- shortcuts (like e.g. Ctrl-d for some action).
Both work, but...
I set the hook in an unmanaged dll and send the message
to a subclassed message window in managed code. This
subclassed message window has a list of (windows form,
delegate). The delegate is actually the keyboard message-
handler of the form. So when the message window revieves a
message, it searches for the enabled form in the list and
calls the delegate. In some cases the pressed button causes
to show up a new window. And then the pen doesn't work any
more.
For example I have a button (plus a shortcut) for logging
in. When the login fails, I show up a messagebox. If I
push the button with the pen, everything works well. But
if I use the shortcut, I can't close the messagebox with
the pen, actually I can't do anything with the pen. It is
strange, that I can close the messagebox with the Enter
button.
I have tried to use in the unmanaged dll both the
SendMessage and the SendNotifyMessage functions, there is
no difference. Is it some threading problem? Any other
idea?
Thanks,
Tibor
 
P

Paul G. Tobey [eMVP]

My thought is that you are not passing the event along to the next hook
routine in the list. This could, potentially, cause a problem with event
processing in the system. Also, I'd suggest that you send messages to the
MessageWindow subclass via PostMessage(), rather than something like
SendMessage().

Paul T.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top