We help IT Professionals succeed at work.

Keystroke changer / key converter even if the app is not in focus !!

kutuindia
kutuindia asked
on
660 Views
Last Modified: 2008-03-17
I need something that will print some other character when a specific key is presses,even if my app has no focus. Like, if I press 'A', then 'E' will be printed instead of 'A'. I have tried the following code and it worked:

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

Private Sub Timer1_Timer()
If GetAsyncKeyState(vbKeyA) = True Then
SendKeys "{BACKSPACE}"
SendKeys "E"
End If
End Sub

But apart from this 'Sendkeys' technique, is there any way to capture the keyboard event (before it prints anyt character) and send another event that will print the character I want .......  instead of the original one ?

Waiting for your reply.

Thank you in advance
Comment
Watch Question

Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
CERTIFIED EXPERT
Top Expert 2009

Commented:
' -----------------------------
' Form1
' -----------------------------
Option Explicit

Private Sub Form_Load()
    hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf LowLevelKeyboardProc, App.hInstance, 0)
End Sub

Private Sub Form_Unload(Cancel As Integer)
    If hhkLowLevelKybd <> 0 Then UnhookWindowsHookEx hhkLowLevelKybd
End Sub

' -----------------------------
' Module1
' -----------------------------
Option Explicit

Public 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
Public Declare Function CallNextHookEx Lib "user32" _
    (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, _
    lParam As Any) As Long
Public Declare Function UnhookWindowsHookEx Lib "user32" _
    (ByVal hHook As Long) As Long
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (Destination As Any, Source As Any, ByVal Length As Long)
Public Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, _
    ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

Public Const WH_KEYBOARD_LL = 13
Public Const HC_ACTION = 0
Public Const WM_KEYDOWN = &H100
Public Const WM_KEYUP = &H101
Public Const WM_SYSKEYDOWN = &H104
Public Const WM_SYSKEYUP = &H105
Public Const KEYEVENTF_KEYUP = &H2
Public Const KEYEVENTF_KEYDOWN = &H0

Public Type KBDLLHOOKSTRUCT
    vkCode As Long
    scancode As Long
    flags As Long
    time As Long
    dwExtraInfo As Long
End Type

Public hhkLowLevelKybd As Long

Public Function LowLevelKeyboardProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim kybd As KBDLLHOOKSTRUCT
    Dim number As String
   
    If (nCode = HC_ACTION) Then
        If wParam = WM_KEYDOWN Or wParam = WM_SYSKEYDOWN Or wParam = WM_KEYUP Or wParam = WM_SYSKEYUP Then
            CopyMemory kybd, ByVal lParam, LenB(kybd)
                             
            Select Case kybd.vkCode
                Case vbKeyA ' change A to E
                    If wParam = WM_KEYDOWN Then
                        LowLevelKeyboardProc = -1
                        Exit Function
                    ElseIf wParam = WM_KEYUP Then
                        keybd_event vbKeyE, 0, KEYEVENTF_KEYDOWN, 0
                        keybd_event vbKeyE, 0, KEYEVENTF_KEYUP, 0
                        LowLevelKeyboardProc = -1
                        Exit Function
                    End If
                       
            End Select
        End If
    End If

    LowLevelKeyboardProc = CallNextHookEx(hhkLowLevelKybd, nCode, wParam, ByVal lParam)
End Function

Author

Commented:
Thank you Idle_Mind for your suggestion .................. i will test the code within few days. Lets wait if any other suggestion comes .............. thanks again.
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
CERTIFIED EXPERT
Top Expert 2009

Commented:
This method will work though it's not 100% correct.  Instead of sending the new keystroke with the keybd_event() API, I believe you can actually modify the "vkCode" value in the KBDLLHOOKSTRUCT and then use CopyMemory() again to put it back into the hook chain.

The methods shown thus far are the only ones that you can implement using VB alone.  You have demonstrated a polling technique (which has obvious drawbacks) while I have used a low level keyboard hook.

If you are willing to use an external DLL/ActiveX control then it would be possible to install other hooks or even an application specific hook.

Author

Commented:
Hello Idle_Mind !!

The code is working ......... but there is one problem. The key is not repeating unless it is released and pressed again, and that is obvious because the code is monitoring KeyUp event too.

Its a minor problem, but is it possible to rectify this ??

Waiting for suggestion ............. Thanks.

High School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
CERTIFIED EXPERT
Top Expert 2009
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
Thanks Idle Mind ! The code served my purpose.

The code is  working fine without this chunk
of code too inside the 'Select Case' Block ::

    'ElseIf wParam = WM_KEYUP Then
    'keybd_event vbKeyE, 0, KEYEVENTF_KEYUP, 0
    'LowLevelKeyboardProc = -1
    'Exit Function

Thanks.


=========================================================

Global 'Autotext' - Keypress simulation !!


I want to create a programme that will store all 'Autotext' entries in a database or text file. It will monitor the typed text and will change it to the relevant AutoText entries if found in the database list (on pressing the 'Space Bar'). And this will be available to any opened editor. This will help me to avoid some repetitive typing hassles.

Example:

When someone type 'IINRM' and press spacebar, it will change to 'International Institute for Natural Resource Management' ……….. And when someone type 'mte' and press spacebar, it will change to 'Mid-Term Examination' .... etc.

There are some free programs like 'PhraseExpress' that does the same thing, but I want to make one for me :)

Waiting for your comments ….

Author

Commented:
My last comment was not complete ..... i suddenly pressed the submit button. So I am giving it here again :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


Thanks Idle Mind ! The code served my purpose.

The code is  working fine without this chunk
of code too inside the 'Select Case' Block ::

    'ElseIf wParam = WM_KEYUP Then
    'keybd_event vbKeyE, 0, KEYEVENTF_KEYUP, 0
    'LowLevelKeyboardProc = -1
    'Exit Function

Thanks.


********************************************************************


I have posted the following question. You are requested to have a look on this too. Because it is also related to Keyboard :)
=============================================================


Title:: Global 'Autotext' - Keypress simulation !!
-------------------------------------------------------

Question:
-----------
I want to create a programme that will store all 'Autotext' entries in a database or text file. It will monitor the typed text and will change it to the relevant AutoText entries if found in the database list (on pressing the 'Space Bar'). And this will be available to any opened editor. This will help me to avoid some repetitive typing hassles.

Example:

When someone type 'IINRM' and press spacebar, it will change to 'International Institute for Natural Resource Management' ……….. And when someone type 'mte' and press spacebar, it will change to 'Mid-Term Examination' .... etc.

There are some free programs like 'PhraseExpress' that does the same thing, but I want to make one for me :)

Waiting for your comments ….

Author

Commented:
Here is the Link of my new Question:



https://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_22148013.html




Author

Commented:
No comments came for the question: https://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_22148013.html


So I have deleted it .
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.