Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium


How to hook keyboard inputs globally in vb?

Posted on 2003-03-03
Medium Priority
Last Modified: 2010-04-07

I want hook the keyboard inputs made to all applications currently running on the systemby using visual basic. I have some examples but they hook only current thread's inputs. And also it is necessary to put these inputs into text box. Thus, I will be able to behave according to specified command typed by the user.
I know the mains of the this process but it is a little difficult for me to code it. If you help me in solving this problem I will be preciate.

Thanks in advance
Question by:monarch_ilhan
  • 4
  • 2
  • 2
  • +1

Accepted Solution

imessvb earned 450 total points
ID: 8062624
here's the code from my old program. i know it looks a little too messy... and i had extra stuff specified to my program that you might want to delete: (it detects keyboard input to other apps)

Option Explicit

Private Type POINTAPI
    x As Long
    y As Long
End Type
Public Type EVENTMSG
    message As Long
    paramL As Long
    paramH As Long
    time As Long
    hwnd As Long
End Type
Private Type MSG
    hwnd As Long
    message As Long
    wParam As Long
    lParam As Long
    time As Long
    pt As POINTAPI
End Type
Private Declare Function SetWindowsHookEx Lib "user32" _
    Alias "SetWindowsHookExA" _
    (ByVal idHook As Long, _
    ByVal lpfn As Long, _
    ByVal hmod As Long, _
    ByVal dwThreadId As Long) _
As Long
Private Declare Function CallNextHookEx Lib "user32" _
    (ByVal hHook As Long, _
    ByVal nCode As Long, _
    ByVal wParam As Long, _
    lParam As Any) _
As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" _
    (ByVal hHook As Long) _
As Long
Private Declare Sub CopyMemory Lib "kernel32" _
    Alias "RtlMoveMemory" _
    (Destination As Any, _
    Source As Any, _
    ByVal Length As Long)

Private Declare Function GetAsyncKeyState _
    Lib "user32" _
    (ByVal vKey As Long) _
As Integer

Private Const WH_JOURNALRECORD = 0
Private Const WH_GETMESSAGE = 3
Private Const WH_KEYBOARD = 2
Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Private Const WM_SYSKEYDOWN = &H104
Private Const WM_SYSKEYUP = &H105

Private hHook As Long

Public Sub StartHook()
    If hHook = 0 Then
        hHook = SetWindowsHookEx(WH_JOURNALRECORD, AddressOf HookProc, 0&, 0&)
    End If
End Sub

Public Sub EndHook()
    If hHook Then UnhookWindowsHookEx hHook
End Sub

Public Function HookProc(ByVal nCode As Long, ByVal wParam As Long, lParam As Long) As Long
    Dim iShift As Integer, iKey As Integer
    iShift = 0
    If GetAsyncKeyState(vbKeyControl) Then iShift = vbCtrlMask
    If GetAsyncKeyState(vbKeyMenu) Then iShift = iShift + vbAltMask
    If GetAsyncKeyState(vbKeyShift) Then iShift = iShift + vbShiftMask
    Dim winMsg As EVENTMSG
    CopyMemory winMsg, lParam, Len(winMsg)
    iKey = CInt(winMsg.paramL And &HFF)
    Select Case winMsg.message
            If iKey <> vbKeyControl And iKey <> vbKeyMenu And iKey <> vbKeyControl Then
                frmMain.KeyTyped iKey, iShift
            End If
    End Select
    HookProc = CallNextHookEx(hHook, nCode, wParam, lParam)
Debug.Print winMsg.message, iKey
End Function

Author Comment

ID: 8151170
Hello again,
Thank you very much for you suggestions but unfortunatately it didnt work. May be there is a small trick which I couldnt see.
Please could you check it again and inform me soon??

And for motivating you, I am increasing its point from 100 to 150.

Best Regards

Expert Comment

ID: 8154251
what part of it didn't work? did it give any error messages or it simply did not response? if you leave your email i can send my sample code to you.
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 8154277
oh, be sure you call StartHook() in Form_Load() event and EndHook() in Form_Unload() event, and your form should be named "frmMain" and has a public function whose signature is: KeyTyped(Byval KeyCode, Byval Shift)

(the code was originally written in win98, i'll check again to see if it works in win2k)

Author Comment

ID: 8157466
hHook = SetWindowsHookEx(WH_JOURNALRECORD, AddressOf HookProc, 0&, 0&)

The return code of above function becomes Zero (0). So, StartHook process does not start. I did your suggestions but, since the SetWindowsHookEx does not start, it is unable to hook keyboard inputs. I think we may change the above function's parameters.

When I change tha functions as
hHook = SetWindowsHookEx(WH_JOURNALRECORD, AddressOf HookProc, App.hInstance , 0&) it gives a return code and it only hooks in my application not globally.

my email address is monarch_ilhan@yahoo.com

I am looking forward to have your solution suggestions.


Expert Comment

ID: 8200546
A problem with the code, is it's not in a DLL locally nor is it registered that way, so if say, someone hits the Windows key on the keyboard, that program goes dormant and stays that way (the hook is invalidated because the system can't find it after the process change).  I've run into the same situation, only means to fix that is to DLL the testing code and make the DLL locally registered and make sure the threadid is in the SetWindowsHookEx.  That way, any new threads that open up will also include that hook themselves (since a journalrecord is system wide, each thread will hook in if they don't have it present).

To hook the keyboard and mouse directly, you'd really need to write device drivers for them.

>hHook = SetWindowsHookEx(WH_JOURNALRECORD, AddressOf HookProc, App.hInstance , 0&) it gives a return code and it only hooks in my application not globally.

This is what I meant by the threadid being present, if this was in a registered DLL, all future opened threads would also open this hook for their usage and unhook it when they leave.

Expert Comment

ID: 8207769
Sorry monarch_ilhan, the code works fine in win98se, even not in a dll, but not in win2k, not matter acsii or unicode version of the APIs is used...

FunkyMeister, I'll try to put the code in a dll and test in win2k again, thanks for the explanation. btw, since hooking is not recommended except for debugging, do you know of any other methods to hook keyboard/mouse using existing APIs?

Expert Comment

ID: 8216124
Actually, hooking them may not be "recommended", but any mouse driver out there (and Internet keyboard driver as well) does it.  Thought they all use DLL's because each thread must be able to get AT the hook, otherwise it's invalidated and the code stops working (the hook gets "canned").  I've seen it get canned on a 98 machine outside of a dll but not inside of one.  And using a program that shows tasks and module usage, I see my dll listed on every last task (which is what you want).  But the downside is, if you're "late" in the stream, you may be getting sloppy seconds from the system (and may be too late down the list of listeners) and be able to do very little but go, "Oh, thats nice."

What are you hooking the inputs for?  Might help me understand the need.
LVL 49

Expert Comment

ID: 9024014
Hi monarch_ilhan,
It appears that you have forgotten to close this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Split points between: imessvb and FunkyMeister

monarch_ilhan, if you think your question was not answered at all or if you need help, just post a new comment here; Community Support will help you.  DO NOT accept THIS comment as an answer.

EXPERTS: If you disagree with that recommendation, please post an explanatory comment.
DanRollins -- EE database cleanup volunteer

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

577 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question