Can't send specific LEFT or RIGHT Ctrl- or Alt-key with keybd_event ?

onidarbe

Board Regular
Joined
Mar 22, 2013
Messages
65
I can't seem to send a specific LEFT or RIGHT Ctrl or Alt, or is it that I can't read it out... ?:confused:
I made a little test sub: (delete the gray part in Declare if you don't have a 64bit Excel)
Code:
[FONT=courier new]Private Declare [COLOR=#A9A9A9]PtrSafe [/COLOR]Sub keybd_event Lib "user32"  (ByVal bVk As Byte _
                                                      ,ByVal bScan As Byte _
                                                      ,ByVal [COLOR=#000000]dwFlags [/COLOR]As Long _
                                                      ,ByVal dwExtraInfo As Long[COLOR=#a9a9a9]Ptr[/COLOR])
[/FONT][FONT=courier new]Sub sTest_keybd_event()
[/FONT][FONT=courier new]    Debug.Print "[/FONT][FONT=courier new]----------------------------[/FONT][FONT=courier new]-----[/FONT][FONT=courier new]"[/FONT]
[FONT=courier new]    For i = 0 To 8[/FONT]
[FONT=courier new]        vKey = Array(16, 17, 18, 160, 161, 162, 163, 164, 165)(i)[/FONT]
[FONT=courier new]        vName = Split("Shift , Ctrl ,  Alt ,ShiftL,ShiftR, CtrlL, CtrlR,  AltL,  AltR", ",")(i)[/FONT]

[COLOR=#008080][FONT=courier new]'       vMap = MapVirtualKey(vKey, 0)[/FONT][/COLOR][COLOR=#ff0000][FONT=courier new] '''no difference then just using 0, so why use MapVirtualKey?[/FONT][/COLOR]
[FONT=courier new]        vMap = 0[/FONT][FONT=courier new]
[/FONT]
[COLOR=#008080][FONT=courier new]        '''vUpDown: bit1=ExtKey, bit2=KeyUp[/FONT][/COLOR]
[FONT=courier new]        vUp = 1: vDown = 3  [COLOR=#ff0000]'''all Left keys are read as Right!?[/COLOR][/FONT]
[COLOR=#008080][FONT=courier new]'       vUp = 0: vDown = 2[/FONT][/COLOR][COLOR=#ff0000][FONT=courier new] '''all Right keys are read as Left, except for Shift!?[/FONT][/COLOR][FONT=courier new]
[/FONT]
[FONT=courier new]        keybd_event [/FONT][FONT=courier new]vKey, vMap, vUp, 0[/FONT]
[FONT=courier new]        DoEvents[/FONT]

[FONT=courier new]        Debug.Print (vName & " " & vMap & " " & vDown & " ");[/FONT]
[FONT=courier new]        vShift = IIf(CBool(GetKeyState(16) And -128), "Shift-", "") _
               & IIf(CBool(GetKeyState(160) And -128), "L", "") _
               & IIf(CBool(GetKeyState(161) And -128), "R", "")[/FONT]
[FONT=courier new]        vCtrl = IIf(CBool(GetKeyState(17) And -128), "Ctrl-", "") _
              & IIf(CBool(GetKeyState(162) And -128), "L", "") _
              & IIf(CBool(GetKeyState(163) And -128), "R", "")[/FONT]
[FONT=courier new]        vAlt = IIf(CBool(GetKeyState(18) And -128), "Alt-", "") _
             & IIf(CBool(GetKeyState(164) And -128), "L", "") _
             & IIf(CBool(GetKeyState(165) And -128), "R", "")[/FONT]
[FONT=courier new]        Debug.Print Left(vShift & Space(9), 9) & Left(vCtrl & Space(8), 8) & vAlt[/FONT]

[FONT=courier new]        keybd_event [/FONT][FONT=courier new]vKey, vMap, vDown, 0[/FONT]
[FONT=courier new]        DoEvents[/FONT]
[FONT=courier new]    Next[/FONT]
[FONT=courier new]End Sub[/FONT]

output:
Code:
[FONT=courier new]----------------------------[/FONT][FONT=courier new]-----[/FONT][FONT=courier new]
[/FONT][FONT=courier new]Shift  0 3 Shift-R          [/FONT]
[FONT=courier new] Ctrl  0 3          Ctrl-R  [/FONT]
[FONT=courier new]  Alt  0 3          [I][COLOR=#ff0000]Ctrl-L[/COLOR][/I]  Alt-R[/FONT]
[FONT=courier new]ShiftL 0 3 Shift-[B][COLOR=#ff0000]R[/COLOR][/B]          [/FONT]
[FONT=courier new]ShiftR 0 3 Shift-R          [/FONT]
[FONT=courier new] CtrlL 0 3          Ctrl-[B][COLOR=#ff0000]R[/COLOR][/B]  [/FONT]
[FONT=courier new] CtrlR 0 3          Ctrl-R  [/FONT]
[FONT=courier new]  AltL 0 3                  Alt-[COLOR=#ff0000][B]R[/B][/COLOR][/FONT]
[FONT=courier new]  AltR 0 3          [I][COLOR=#ff0000]Ctrl-L[/COLOR][/I]  Alt-R[/FONT]

The R should be L !!!
Also I can't seem to send only the Alt-R without also pressing Ctrl-L !?

HELP ME, thanks
 

Excel Facts

How to find 2nd largest value in a column?
MAX finds the largest value. =LARGE(A:A,2) will find the second largest. =SMALL(A:A,3) will find the third smallest
Re: Can't send specific LEFT or RIGHT Ctrl- or Alt-key with keybd_event ? SOLVED

Reply to my selve :confused: I think I solved it.

I made the test a bit better and although previous code worked the vDown and vUp where wrongly named. Sorry for that. :oops:

I found out that there is something weird going on but I think I may have found a solution.
It seems there is a little flow in the keybd_event and Ms doesn't tell us that here!


KEYEVENTF_EXTENDEDKEY (bit 1) should not be used for modifying keys (Shift, Ctrl, Alt,...)
Unless you want to send Ctrl-R or Alt-R, and even more troubling you need to send Alt-L instead of Alt-R

So apart from the Alt-L instead of Alt-R which could have something to do with the AltGr, only the Right Ctrl and Right Alt keys are considered to be KEYEVENTF_EXTENDEDKEY !

Can anyone please confirm my conclusion? Just try this code and check if the output is the same as mine, on Win7, 64bit Excel
Thank you.
Code:
#If Win64 Then
    Private Declare PtrSafe Function GetKeyState Lib "user32" (ByVal nVirtKey As Integer) As Integer
    Private Declare PtrSafe Sub Keybd_event Lib "user32" Alias "keybd_event" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As LongPtr)
    Private Declare PtrSafe Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal uCode As Long, ByVal uMapType As Long) As Long
#Else '''32 bit
    Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Integer) As Integer
    Private Declare Sub Keybd_event Lib "user32" Alias "keybd_event" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
    Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal uCode As Long, ByVal uMapType As Long) As Long
#End If

Sub sTest_Keybd_event() '''01/06/2013, michel(dot)be(a)gmail....
Dim iFlag As Integer, iKey As Integer, iMap As Integer, iDown As Integer, iUp As Integer, vName As String
    Application.VBE.Windows("Immediate").Visible = True '''show the Immediate window for debug.print
    For iFlag = 0 To 1
[COLOR=#008080]        '''bit1=ExtKey, bit2=KeyUp according to MS but...see results[/COLOR]
[COLOR=#008080]        '''vDown = 1: vUp = 3 '''all keys are Right!               except for Alt & AltR=AltGr(CtrlL+AltR)![/COLOR]
[COLOR=#008080]        '''vDown = 0: vUp = 2 '''all keys are Left, except ShiftR! except for AltR=AltGr(CtrlL+AltL)![/COLOR]
        iDown = 0 Or iFlag: iUp = 2 Or iFlag
        Debug.Print "------- iDown = " & iDown & " : iUp = " & iUp & " ------"
        For i = 0 To 8
            iKey = Array(16, 17, 18, 160, 161, 162, 163, 164, 165)(i)
            vName = Split("Shift  , Ctrl  ,  Alt  ,Shift-L,Shift-R, Ctrl-L, Ctrl-R,  Alt-L,  Alt-R", ",")(i)
            iMap = MapVirtualKey(iKey, 0) 
[B]        [COLOR=#008080]'[/COLOR][/B][COLOR=#008080]iMap =0 [/COLOR][B][COLOR=#008080]'''Doesn't seem to make any difference using 0, so why do they all use MapVirtualKey? Try 0 as well ;-)[/COLOR][/B]
            Keybd_event iKey, iMap, iDown, 0
            DoEvents
            Debug.Print (vName & " " & iMap & " ") _
                & Left(IIf(CBool(GetKeyState(16) And -128), "Shift-", "") _
                      & IIf(CBool(GetKeyState(160) And -128), "L", "") _
                      & IIf(CBool(GetKeyState(161) And -128), "R", "") & Space(9), 9) _
                & Left(IIf(CBool(GetKeyState(17) And -128), "Ctrl-", "") _
                     & IIf(CBool(GetKeyState(162) And -128), "L", "") _
                     & IIf(CBool(GetKeyState(163) And -128), "R", "") & Space(8), 8) _
                & Left(IIf(CBool(GetKeyState(18) And -128), "Alt-", "") _
                     & IIf(CBool(GetKeyState(164) And -128), "L", "") _
                     & IIf(CBool(GetKeyState(165) And -128), "R", "") & Space(7), 7) 
            Keybd_event iKey, iMap, iUp, 0
            DoEvents
        Next
    Next
    Debug.Print "---------------------------------"
End Sub
Code:
[COLOR=#0000ff]'''Output Keybd_event and GetKeyState results:[/COLOR]
[COLOR=#0000ff]'''------- iDown = 0: iUp = 2 -------[/COLOR]
[COLOR=#0000ff]'''Shift   42 Shift-L                 ok[/COLOR]
[COLOR=#0000ff]''' Ctrl   29          Ctrl-L         ok[/COLOR]
[COLOR=#0000ff]'''  Alt   56                  Alt-L  ok[/COLOR]
[COLOR=#0000ff]'''Shift-L 42 Shift-L                 ok[/COLOR]
[COLOR=#0000ff]'''Shift-R 54 Shift-R                 ok[/COLOR]
[COLOR=#0000ff]''' Ctrl-L 29          Ctrl-L         ok[/COLOR]
[COLOR=#0000ff]''' Ctrl-R 29          Ctrl-[/COLOR][COLOR=#ff0000]L         [/COLOR][COLOR=#ff0000]![/COLOR]
[COLOR=#0000ff]'''  Alt-L 56                  Alt-L  ok[/COLOR]
[COLOR=#0000ff]'''  Alt-R 56          [/COLOR][COLOR=#ff0000]Ctrl-L[/COLOR][COLOR=#0000ff]  Alt-[/COLOR][COLOR=#ff0000]L  [/COLOR][COLOR=#ff0000]=*[/COLOR]
[COLOR=#0000ff]'''------- iDown = 1: iUp = 3 -------[/COLOR]
[COLOR=#0000ff]'''Shift   42 Shift-R                 ok[/COLOR]
[COLOR=#0000ff]''' Ctrl   29          Ctrl-R         ok[/COLOR]
[COLOR=#0000ff]'''  Alt   56          [/COLOR][COLOR=#ff0000]Ctrl-L[/COLOR][COLOR=#0000ff]  Alt-[/COLOR][COLOR=#0000ff]R[/COLOR]  [COLOR=#ff0000]![/COLOR]
[COLOR=#0000ff]'''Shift-L 42 Shift-[/COLOR][COLOR=#ff0000]R            [/COLOR][COLOR=#ff0000]![/COLOR]
[COLOR=#0000ff]'''Shift-R 54 Shift-R                 ok[/COLOR]
[COLOR=#0000ff]''' Ctrl-L 29          Ctrl-[/COLOR][COLOR=#ff0000]R           [/COLOR][COLOR=#ff0000]![/COLOR]
[COLOR=#0000ff]''' Ctrl-R 29          Ctrl-R         ok[/COLOR]
[COLOR=#0000ff]'''  Alt-L 56                  Alt-[/COLOR][COLOR=#ff0000]R  [/COLOR][COLOR=#ff0000]*[/COLOR]
[COLOR=#0000ff]'''  Alt-R 56          [/COLOR][COLOR=#ff0000]Ctrl-L[/COLOR][COLOR=#0000ff]  Alt-R  [/COLOR][COLOR=#ff0000]![/COLOR]
[COLOR=#0000ff]'''----------------------------------[/COLOR]
[B][COLOR=#0000ff]'''My conclusion: Use only bit2 as in 0(down) & 2(up), exept for[/COLOR]
[COLOR=#0000ff]'''               CtrlR and AltR, they need bit1 as in 1(down) & 3(up),[/COLOR]
[COLOR=#0000ff]'''               and use AltL for AltR[/COLOR][/B]
 
Last edited:
Upvote 0
Re: Can't send specific LEFT or RIGHT Ctrl- or Alt-key with keybd_event ? SOLVED

x
 
Last edited:
Upvote 0
Re: Can't send specific LEFT or RIGHT Ctrl- or Alt-key with keybd_event ? SOLVED

Do you still need help with this, or to compare results? Here is the output of your amended code on 2 computers. both Windows XP (32-bit).

First, a UK keyboard with the right-hand Alt key labelled as 'Alt Gr':

Code:
------- iDown = 0 : iUp = 2 ------
Shift   42 Shift-L                 
 Ctrl   29          Ctrl-L         
  Alt   56                  Alt-L  
Shift-L 42 Shift-L                 
Shift-R 54 Shift-L                 
 Ctrl-L 29          Ctrl-L         
 Ctrl-R 29          Ctrl-L         
  Alt-L 56                  Alt-L  
  Alt-R 56          Ctrl-L  Alt-L  
------- iDown = 1 : iUp = 3 ------
Shift   42 Shift-R                 
 Ctrl   29          Ctrl-R         
  Alt   56          Ctrl-L  Alt-R  
Shift-L 42 Shift-R                 
Shift-R 54 Shift-R                 
 Ctrl-L 29          Ctrl-R         
 Ctrl-R 29          Ctrl-R         
  Alt-L 56                  Alt-R  
  Alt-R 56          Ctrl-L  Alt-R  
---------------------------------
Note how Alt-R down results in both Ctrl-L and Alt-L or Ctrl-L and Alt-R showing as down. Also, I think iDown = 1 and iUp = 3 are invalid values, hence the incorrect result for Alt which shows Ctrl-L and Alt-R down. All the code I've seen uses iDown = 0 and iUp = 2 (KEYEVENTF_KEYUP).

Second, a US keyboard with the right-hand Alt key labelled as 'Alt':
Code:
------- iDown = 0 : iUp = 2 ------
Shift   42 Shift-L                 
 Ctrl   29          Ctrl-L         
  Alt   56                  Alt-L  
Shift-L 42 Shift-L                 
Shift-R 54 Shift-L                 
 Ctrl-L 29          Ctrl-L         
 Ctrl-R 29          Ctrl-L         
  Alt-L 56                  Alt-L  
  Alt-R 56                  Alt-L  
------- iDown = 1 : iUp = 3 ------
Shift   42 Shift-R                 
 Ctrl   29          Ctrl-R         
  Alt   56                  Alt-R  
Shift-L 42 Shift-R                 
Shift-R 54 Shift-R                 
 Ctrl-L 29          Ctrl-R         
 Ctrl-R 29          Ctrl-R         
  Alt-L 56                  Alt-R  
  Alt-R 56                  Alt-R  
---------------------------------
I think the all keys Left or all keys Right result is due to using GetKeyState. Try this code which uses GetAsyncKeyState instead and produces correct and expected results on both computers.

Code:
Sub sTest2_Keybd_event()

    Dim iFlag As Long, iKey As Byte, iMap As Byte, iDown As Long, iUp As Long, vName As String
    Dim i As Integer, k As Integer
    Dim keyCodes As Variant
    
    keyCodes = Array(16, 17, 18, 160, 161, 162, 163, 164, 165)
            
    Application.VBE.Windows("Immediate").Visible = True '''show the Immediate window for debug.print
    
    For iFlag = 0 To 0 '1
        iDown = 0 Or iFlag: iUp = 2 Or iFlag
        Debug.Print "------- iDown = " & iDown & " : iUp = " & iUp & " ------"
        
        For i = 0 To UBound(keyCodes)
            iKey = keyCodes(i)
            vName = Split("Shift  , Ctrl  ,  Alt  ,Shift-L,Shift-R, Ctrl-L, Ctrl-R,  Alt-L,  Alt-R", ",")(i)
            iMap = MapVirtualKey(iKey, 0)
            
            Keybd_event iKey, iMap, iDown, 0
            
            If iKey = 16 Or iKey = 17 Or iKey = 18 Then
                
                'Show status of SHIFT, CTRL, or ALT keys without distinguishing between left and right
                
                Debug.Print vName & " " & iMap & " " _
                    & Left(IIf(GetAsyncKeyState(16) <> 0, "Shift", "") & Space(9), 9) _
                        & Left(IIf(GetAsyncKeyState(17) <> 0, "Ctrl", "") & Space(9), 9) _
                        & Left(IIf(GetAsyncKeyState(18) <> 0, "Alt", "") & Space(9), 9)
            Else
                
                'Show status of SHIFT, CTRL, or ALT keys, distinguishing between left and right
                
                Debug.Print vName & " " & iMap & " " _
                    & Left(IIf(GetAsyncKeyState(160) <> 0, "Shift-L", "") _
                          & IIf(GetAsyncKeyState(161) <> 0, "Shift-R", "") & Space(9), 9) _
                    & Left(IIf(GetAsyncKeyState(162) <> 0, "Ctrl-L", "") _
                         & IIf(GetAsyncKeyState(163) <> 0, "Ctrl-R", "") & Space(9), 9) _
                    & Left(IIf(GetAsyncKeyState(164) <> 0, "Alt-L", "") _
                         & IIf(GetAsyncKeyState(165) <> 0, "Alt-R", "") & Space(9), 9)
            
            End If
            
            Keybd_event iKey, iMap, iUp, 0
            
            'Get state of all keys.  Without this, Shift-L key down results in Shift-L, Ctrl-L and Alt-L all showing as down
            
            For k = 0 To UBound(keyCodes)
                GetAsyncKeyState keyCodes(k)
            Next
            
        Next
    Next
    Debug.Print "----------------------------------"
    
End Sub
UK keyboard results:
Code:
------- iDown = 0 : iUp = 2 ------
Shift   42 Shift                      
 Ctrl   29          Ctrl              
  Alt   56                   Alt      
Shift-L 42 Shift-L                    
Shift-R 54 Shift-R                    
 Ctrl-L 29          Ctrl-L            
 Ctrl-R 29          Ctrl-R            
  Alt-L 56                   Alt-L    
  Alt-R 56          Ctrl-L   Alt-R    
----------------------------------
US keyboard results:
Code:
------- iDown = 0 : iUp = 2 ------
Shift   42 Shift                      
 Ctrl   29          Ctrl              
  Alt   56                   Alt      
Shift-L 42 Shift-L                    
Shift-R 54 Shift-R                    
 Ctrl-L 29          Ctrl-L            
 Ctrl-R 29          Ctrl-R            
  Alt-L 56                   Alt-L    
  Alt-R 56                   Alt-R    
----------------------------------
PS - I don't know why the GetAsyncKeyState loop after the key up has the effect noted in the comment or why it is needed.
 
Last edited:
Upvote 0
Re: Can't send specific LEFT or RIGHT Ctrl- or Alt-key with keybd_event ? SOLVED

Hey, Thank for all your efforts John!

It's still not without faults though. I get a Ctrl-L with Alt-R! And there are more things going wrong when manually pressing a modifying key wile running it!
Code:
------- iDown = 0 : iUp = 2 ------
Shift   42 Shift                      
 Ctrl   29          Ctrl              
  Alt   56                   Alt      
Shift-L 42 Shift-L                    
Shift-R 54 Shift-R                    
 Ctrl-L 29          Ctrl-L            
 Ctrl-R 29          Ctrl-R            
  Alt-L 56                   Alt-L    
  Alt-R 56          Ctrl-L   Alt-R    
----------------------------------
And why hide which key is pressed in a test-mode? So i removed "If iKey = 16 Or iKey = 17 Or iKey = 18 Then" again ;)
I specially need to find out which key is pressed because I want to press the other side for sending a combination of keys. It has all to do with making a flawless SendKey. If both the program and the user are manipulating the same modifying key, then changes are that the key will loose the real actual state. By not pressing it programmaticly when already pressed, changes are that the user just released that key upon sending the character-key....

So you think the GetKeyState isn't reporting correct, rather then the Keybd_event doing something wrong then? I'll do some more tests...
 
Upvote 0
Re: Can't send specific LEFT or RIGHT Ctrl- or Alt-key with keybd_event ? SOLVED

Small update notes: (These are tested on a i5 laptop win7, Excel 2010 64bit)

Don't use Alt+L with the extended bit for Alt+R but (it messes up when raising keys) !
But send Alt+R and immediately raise Ctrl+L if it wasn't down before pressing Alt+R.
On some computers sending Alt+R with Keybd_event, will also press Ctrl+L


You also need to use DoEvents before using
GetKeyState to get the present state of the modifying keys, because sometimes the manual pressed mod.key while already running VBA-code will not be read correctly!!!!
 
Upvote 0
Re: Can't send specific LEFT or RIGHT Ctrl- or Alt-key with keybd_event ? SOLVED

Final way to send and use modifying keys (Shift, Ctrl, Alt) without changing any.
If anyone has some other outcome on his PC, please let me know! Post output and your language/keyboard setup.
Code:
Private Sub test_Keybd_event_modifyingKeys() [COLOR=#0000ff]'''16/07/2013, michel(dot)be(a)gmail....[/COLOR]
Dim keyDown As Byte, keyUp As Byte, keyName As String
Dim i As Integer, nextKey As Variant, extKey As Byte, keyAlreadyDown As Boolean
    Debug.Print "======= test Keybd_event ======="
    keyDown = 0: keyUp = 2
    startTime = Now() [COLOR=#0000ff]'''get start time waiting[/COLOR]
    Do While Now() < startTime + TimeValue("00:00:02")
    Loop[COLOR=#0000ff] '''wait a seconds to be able to press any other modifying key before testing[/COLOR]
    For i = 0 To 9
        nextKey = Split("016,017,018,160,161,162,163,164,165,000", ",")(i)
        keyName = Split("Shift  , Ctrl  ,  Alt  ,Shift-L,Shift-R, Ctrl-L, Ctrl-R,  Alt-L,  Alt-R,       ", ",")(i)

       [COLOR=#0000ff] '''Change modifying keys to the Left- or Right-equivalent, what ever is not already pressed down.
        '''Because otherwise the manually pressed key could rise or stays down as this function ends.
        '''And just in case the already pressed modifying key is released while running this function.[/COLOR]
        DoEvents[COLOR=#ff0000] '''NEEDED FOR BUG: To be shure that a manual presses modifying key after starting VBA-code can be read correctly.[/COLOR]
        If CBool(GetKeyState(VBkeyShiftR) And -128) Then [COLOR=#0000ff]'''R-Shift already (manually) down...[/COLOR]
            nextKey = Replace(nextKey, "016", "160")        [COLOR=#0000ff]'''...replace all Shift with L-Shift[/COLOR]
        Else
            nextKey = Replace(nextKey, "016", "161")  [COLOR=#0000ff]      '''replace all Shift with R-Shift[/COLOR]
        End If
        If CBool(GetKeyState(VBkeyCtrlR) And -128) Then [COLOR=#0000ff] '''R-Ctrl already (manually) down...[/COLOR]
            nextKey = Replace(nextKey, "017", "162") [COLOR=#0000ff]       '''...replace all Ctrl with L-Ctrl[/COLOR]
        Else
            nextKey = Replace(nextKey, "017", "163")        [COLOR=#0000ff]'''replace all Ctrl with R-Ctrl[/COLOR]
        End If
        If CBool(GetKeyState(VBkeyAltR) And -128) Then  [COLOR=#0000ff] '''R-Alt already (manually) down...[/COLOR]
            nextKey = Replace(nextKey, "018", "164")      [COLOR=#0000ff]  '''...replace all Alt with L-Alt[/COLOR]
        Else
            nextKey = Replace(nextKey, "018", "165")       [COLOR=#0000ff] '''replace all Alt with R-Alt[/COLOR]
        End If

        keyAlreadyDown = CBool(GetKeyState(nextKey) And -128)
        If Not keyAlreadyDown Then
            extKey = -(InStr(" 163, 165, 091, 092, 093 ", nextKey) > 0)
            If nextKey = 165 And CBool(GetKeyState(162) And -128) = False Then[COLOR=#0000ff] '''if AltR and CtrlL is up[/COLOR]
                [COLOR=#ff0000]'''NEEDED FOR BUG: When pressing AltR, the CtrlL also go's down on some PC's (=AltGr)[/COLOR]
               [COLOR=#0000ff] '''note: MapVirtualKey(nextKey, 0) not needed, works also with 0 for these modifying keys[/COLOR]
                Keybd_event nextKey, 0, keyDown + extKey, 0 [COLOR=#0000ff]'''press AltR (AltGr)[/COLOR]
                Keybd_event 162, 0, keyUp, 0 [COLOR=#0000ff]'''release CtrlL ![/COLOR]
            Else
                Keybd_event nextKey, 0, keyDown + extKey, 0 [COLOR=#0000ff]'''press modifying key[/COLOR]
            End If
        End If
        DoEvents
        
        Debug.Print (keyName & ": ") _
            & Left(IIf(CBool(GetKeyState(16) And -128), "Shift-", "") _
                 & IIf(CBool(GetKeyState(160) And -128), "L", "") _
                 & IIf(CBool(GetKeyState(161) And -128), "R", "") & Space(9), 9) _
            & Left(IIf(CBool(GetKeyState(17) And -128), "Ctrl-", "") _
                 & IIf(CBool(GetKeyState(162) And -128), "L", "") _
                 & IIf(CBool(GetKeyState(163) And -128), "R", "") & Space(8), 8) _
            & Left(IIf(CBool(GetKeyState(18) And -128), "Alt-", "") _
                 & IIf(CBool(GetKeyState(164) And -128), "L", "") _
                 & IIf(CBool(GetKeyState(165) And -128), "R", "") & Space(7), 7)

        If Not keyAlreadyDown Then Keybd_event nextKey, 0, keyUp + extKey, 0[COLOR=#0000ff] '''release modifying key[/COLOR]
        DoEvents
    Next
    Debug.Print "================================"
End Sub

This should be the output + all manual pressed modifying keys, whitout changing there state.
Code:
[COLOR=#0000ff]======= test Keybd_event =======
Shift  : Shift-R
Ctrl   :          Ctrl-R
Alt    :                  Alt-R
Shift-L: Shift-L
Shift-R: Shift-R
 Ctrl-L:          Ctrl-L
 Ctrl-R:          Ctrl-R
  Alt-L:                  Alt-L
  Alt-R:                  Alt-R
       :
================================[/COLOR]
So if you press AltGr when just started the Sub, your output should be:
Code:
[COLOR=#0000ff]======= test Keybd_event =======
Shift  : Shift-R  Ctrl-L  Alt-R  
 Ctrl  :          Ctrl-LR Alt-R  
  Alt  :          Ctrl-L  Alt-LR 
Shift-L: Shift-L  Ctrl-L  Alt-R  
Shift-R: Shift-R  Ctrl-L  Alt-R  
 Ctrl-L:          Ctrl-L  Alt-R  
 Ctrl-R:          Ctrl-LR Alt-R  
  Alt-L:          Ctrl-L  Alt-LR 
  Alt-R:          Ctrl-L  Alt-R  
       :          Ctrl-L  Alt-R  
================================[/COLOR]
 
Upvote 0

Forum statistics

Threads
1,214,829
Messages
6,121,826
Members
449,051
Latest member
excelquestion515

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top