Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / June 2005

Tip: Looking for answers? Try searching our database.

Keyboard logging functionality

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Stephen Corey - 27 Jun 2005 20:46 GMT
I need to write a program that launches Internet Explorer, then counts
how many <ENTER> keys are pressed inside IE. I've seen a lot of
references to the SetWindowsHookEx() API call, but all sources I found
seem to be piece-meal and incomplete. I'm using VC++ .NET, and would
rather avoid using the WinAPI, if possible. Is there an easier way
(perhaps using .NET) to do this?
William DePalo [MVP VC++] - 28 Jun 2005 00:49 GMT
>I need to write a program that launches Internet Explorer,

See CreateProcess(). It will return a process identifier and a thread
identifier which will come in handy shortly.

> then counts how many <ENTER> keys are pressed inside IE. I've seen a lot
> of references to the SetWindowsHookEx() API call, but all sources I found
> seem to be piece-meal and incomplete.

:-) Well, they probably demonstrate how to intercept keystrokes but not how
to implement your task.

> I'm using VC++ .NET, and would rather avoid using the WinAPI,
> if possible. Is there an easier way (perhaps using .NET) to do this?

I don't believe so.

One way to attack the problem would be with a system wide keyboard hook
which must necessarily be implemented in a DLL. You'd only be interested in
notifications where the WPARAM parameter of the notification is VK_ENTER and
where the high bit (#31) of the LPARAM parameter is 0. When that's the case
you'd call GetFocus() to find the active window (that's the destination of
the keystroke) and then GetWindowThreadProcessId() to find either the
identifier of that the owning process or thread. You'd compare either
against what you got from CreateProcess() and on a match increment your
count.

That method is not at all specific to IE but would work with any process you
create.

IE does permit itself to be extended with add-ons so there _may_ be some
easier way inside one of these extensions. You might want to search for a
group devoted to IE to see if there is some easier way.

By the way, why do you need to count the ENTER keys pressed?

Regards,
Will
Joel Whitehouse - 28 Jun 2005 15:03 GMT
> By the way, why do you need to count the ENTER keys pressed?

Yes, I was just thinking to myself: "Whatever on earth for??"  Sounds
like an interesting application.
Stephen Corey - 28 Jun 2005 17:19 GMT
>> By the way, why do you need to count the ENTER keys pressed?
>
> Yes, I was just thinking to myself: "Whatever on earth for??"  Sounds
> like an interesting application.

Some of my users log onto a website that uses an ActiveX control to log
onto an AS/400 (within the web browser). We get charged for every
"screen" sent from the server, which happens whey they hit ENTER. To
avoid having to make them keep track of how many screens they see, I can
just count the ENTER keys.

I see that I can use WH_KEYBOARD_LL to create a global hook WITHOUT
having a separate DLL, but I can't find any examples anywhere. The only
code I see is for VB or C#. Do either of you know of any?? I'd even take
a "with the DLL" example if nothing better can be found...
William DePalo [MVP VC++] - 28 Jun 2005 18:23 GMT
> I see that I can use WH_KEYBOARD_LL to create a global hook WITHOUT having
> a separate DLL, but I can't find any examples anywhere.

Hmm, where do the docs say that? In the help entry for SetWindowsHookEx()
their is a table in which the WH_KEYBOARD_LL hook is listed as having only
global scope.

Then in the remarks for the HOOKPROC parameter in the call there is this

<quote>
[in] Pointer to the hook procedure. If the dwThreadId parameter is zero or
specifies the identifier of a thread created by a different process, the
lpfn parameter must point to a hook procedure in a dynamic-link library
(DLL). Otherwise, lpfn can point to a hook procedure in the code associated
with the current process.
</quote>

Taken together that means that a DLL is required, no?

> is for VB or C#. Do either of you know of any?? I'd even take a "with the
> DLL" example if nothing better can be found...

There is old C code for a global hook in the file Hook.c in the Platform
SDK's directory

   Samples\multimedia\gdi\WinCap32

Note its use of the hook is canonical in that the hook detects a condition
but does NOT handle it. It posts a message back to the application which
planted the hook and that application is the one that handles it. This is
the right way because

a) Global hooks should have small footprints as they bloat _every_ windowed
application
b) Their code runs in the context of the application being hooked. An errant
hook can crash an otherwise fine application

Regards,
Will
Stephen Corey - 28 Jun 2005 18:40 GMT
>>I see that I can use WH_KEYBOARD_LL to create a global hook WITHOUT having
>>a separate DLL, but I can't find any examples anywhere.
[quoted text clipped - 35 lines]
> Regards,
> Will

In experts exchange, as well as a few other sites, people mentioned that
with that hook, you didn't have to have your code in a separate DLL.

So, the main code to be managed, and I guess the DLL code needs to be
unmanaged?? What type of a project is the DLL?

Is there no code that is designed for VC++ .NET?
William DePalo [MVP VC++] - 28 Jun 2005 19:05 GMT
> In experts exchange, as well as a few other sites, people mentioned that
> with that hook, you didn't have to have your code in a separate DLL.

Hmm. To hook a process other than the one in which the SetWindowsHookEx()
call is made. Sounds hokey to me.

> So, the main code to be managed, and I guess the DLL code needs to be
> unmanaged?? What type of a project is the DLL?

The DLL would be native. If you are using VS.Net 2003 you first select C++
projects and then click on the Win32 icon. Then click Application Settings
and choose the DLL option. A

> Is there no code that is designed for VC++ .NET?

As far as I know, no. Realize that I don't claim to be a .Net expert.

Regards,
Will
Stephen Corey - 28 Jun 2005 19:40 GMT
>>In experts exchange, as well as a few other sites, people mentioned that
>>with that hook, you didn't have to have your code in a separate DLL.
[quoted text clipped - 15 lines]
> Regards,
> Will

Ok, well with the callback code in a separate DLL, how will I get the
"ENTER count" back into my managed code?
William DePalo [MVP VC++] - 28 Jun 2005 20:24 GMT
> Ok, well with the callback code in a separate DLL, how will I get the
> "ENTER count" back into my managed code?

You adopt some interprocess communication mechanism between the DLL (which
runs in the applications being hooked) and your application which planted
the hook (presumably via some form of interop). The sample to which I
pointed posts a WM_COMMAND message. You code do that.

Of course, that begs the question as to how you retrieve the message on the
managed side. It's not something that I've done so I can't offer any advice.
IMO, what you are trying to do is best done natively, anyway.

Regards,
Will
Vladimir Nesterovsky - 29 Jun 2005 11:25 GMT
>> Yes, I was just thinking to myself: "Whatever on earth for??"  Sounds
>> like an interesting application.
[quoted text clipped - 4 lines]
> to make them keep track of how many screens they see, I can just count the
> ENTER keys.

You may consider another approach to handle this case (case of using ActiveX
in the Internet Explorer):
1. Create alternative ActiveX, which mimics interface of the original
ActiveX and forwards all requests to it.
2. Implement there your tracing logic.
3. Register ActiveX substitution for the Internet Explorer in the registry:

   [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX
Compatibility\{original guid}]
       "AlternateCLSID"="{substitution guid}"
       "Compatibility Flags"=dword:00000000

Signature

Vladimir Nesterovsky
e-mail: vladimir@nesterovsky-bros.com
home: http://www.nesterovsky-bros.com


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.