Lyle Kopnicky wrote:
> It appears the code only needs to be in a DLL if you want to create a> system level hook. I only need a thread level hook.
Correct, to my knowledge at least. I wass thinking of system wide hooks
mainly and failed to point that out. So I suppose your Perl solution should
work.
> Listed below is what I have so far. It waits for a few seconds, then > quits. <code relocated>
OK I took a quick glance at it and a couple of more or less trivial
questions and observations came to mind.
The MSDN docs state specifically that if the hook code is negative, no
processing should be done except to pass on the parameters to CallNextHookX
and return its return value. I suppose it doesn't really matter here but
that's one minor detail of the "hook contract", which your testing code
violates.
Also the question of how to get the HINSTANCE and ThreadId parameters using
Perl has been bothering me, too. Are you sure that the GetCurrentThreadId
function you import from kernel32 does get the same thread in which your
application actually runs? I suppose Perl might be multi-threaded, am not
certain about this, though, or some of the TK or Win32 stuff might have some
event handling threads. I know next to nothing about how those modules are
implemented, these are just wild guesses. I do know Java has multiple
threads running starting from the garbage collector, which caused me to
extrapolate here.
Finally, where did you get the magic number for the low-level keyboard hook?
Are you sure its correct? Silly question, I know, but sometimes silly things
do happen (like mistyping JDBC as JBDC and wondering why things don't work).
My oldish MSDN collection says, by the way, that low-level keybord hooks are
only supported in NT. You aren't running Win 9X by any chance, are you?
> If I change the return type of SetWindowsHookEx from 'P' to 'N', my> main window will open, but I still don't get any calls to KeyboardHook.
Umm, the fact that changing the prototype affects program behavior here
might be a sign of a wrong prototype. I've only imported very basic
functions with Win32::API so far, so I cannot be of much help with Perlish
callbacks to Win32 functions, I'm afraid.
Your code:
use warnings;
use strict;
use Tk;
use Win32::API;
use Win32::API::Callback;
my $WH_KEYBOARD_LL = 13;
my $GetCurrentThreadId
= new Win32::API('kernel32', 'GetCurrentThreadId', '', 'N');
my $SetWindowsHookEx =
new Win32::API('user32', 'SetWindowsHookEx', 'NKPP', 'P');
Win32::API->Import('user32', 'HHOOK SetWindowsHookEx(int idHook,
HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)');
my $CallNextHookEx =
new Win32::API('user32', 'CallNextHookEx', 'PNNN', 'N');
sub KeyboardHook($$$) {
my ($nCode, $wParam, $lParam) = @_;
print "nCode=$nCode, wParam=$wParam, lParam=$lParam\n";
$CallNextHookEx->Call(0, $nCode, $wParam, $lParam);
}
my $KeyboardHookCallback =
new Win32::API::Callback(\&KeyboardHook, 'NNP', 'N');
my $ThreadId = $GetCurrentThreadId->Call();
my $Hook = $SetWindowsHookEx->Call($WH_KEYBOARD_LL, $KeyboardHookCallback,
0, $ThreadId);
my $win = MainWindow->new();
MainLoop();
End code.
--
With kind regards Veli-Pekka Tätilä (vtat...@mail.student.oulu.fi)
Accessibility, game music, synthesizers and programming:
http://www.student.oulu.fi/~vtatila/