Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[How To] Capture Virtual-key code of a Keypress


  • Please log in to reply
1 reply to this topic
SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

How to Capture Virtual-key code of a Keypress ?
http://www.autohotke...p?p=75007#75007

Foreword:

My sincere thanks to PhiLho for helping me to compact this function,
and ParanoidX for explaining me the concept.

See the Topic: DllCall() - Help required with ExtractInteger()

When I wanted to convert my FoxPro [DOS] based Hangman game to AutoHotkey, I missed the main
XBase function required to capture Keypress :InKey() ! Well! I am able to reproduce similar functionality
with this InputKey() for AHK. The difference is that InKey() returns the ASCII value of the key pressed
while InputKey() returns the Virtual-key code for a keypress.

You may refer MSDN for Virtual-key codes and/or
Download VK_NAMES.INI [4K] which contains the list of Virtual-key codes with names.


Here follows the InputKey() function:


InputKey(Duration=0, Prefix="")    {
 Global A_KBI_Timeleft
 IfEqual,Prefix,, SetEnv,Prefix,0x
 A_FI:=A_FormatInteger
 TC:=A_TickCount 
 VarSetCapacity(lpKeyState,256,0)    
 DllCall("SetKeyboardState", UInt,&lpKeyState)
 Loop {
        DllCall("GetKeyboardState", UInt,&lpKeyState)
        Loop, 256 {
                    Int:=*(&lpkeystate+(A_Index-1))
                    If (Int>=0x80)
                      {
                        VK_CODE:=A_Index-1      
                        Break
                      }
                  }
        IfNotEqual,VK_CODE,, Break
        A_KBI_Timeleft:=Round((Duration-(A_TickCount-TC))/1000)
        If (Duration AND (A_TickCount-TC>=Duration))
           Break 
        Sleep 20
      }
IfEqual,VK_CODE,, Return, VK_CODE
 SetFormat, Integer, Hex
 VK_CODE+=0
 StringReplace, VK_CODE, VK_CODE, 0x, 0x0
 StringRight, VK_CODE, VK_CODE, 2
 StringUpper, VK_CODE, VK_CODE
 SetFormat, Integer, %A_FI%
Retval=%Prefix%%VK_CODE%
Return RetVal
}

Download InputKey.ahk [0.9K]

Facts / Features :
[*:2vxa8t08]InputKey() is thread specific! Means you cannot use it to log general keyboard activity.
It can scan keypress only for the script that is calling the function.
You may use it as a thread-specific Wait For Any Key.

[*:2vxa8t08]You need have a GUI or any visual component active on the screen for InputKey() to work.

[*:2vxa8t08]A_KBI_Timeleft is a global variable that will be updated with remaining duration.
One the examples (that will follow) will demonstrate its use!

[*:2vxa8t08]When a GUI has a loop to capture Keypress, the system plays DING.WAV for every keypress
which maybe annoying! The workaround is to have a dummy ListView/ListBox control.
I do not know how this works .. but it works! Mr.Chris should be able to explain the how
ListView/ListBox is able to suppress the system sound event!


Example 1:

The following example displays a Count down and initiates shutdown.
Pressing any key or mouse-clicking on the window cancels the shutdown.

Posted Image
Gui, -Sysmenu +AlwaysOnTop
Gui,Font, s14 , Verdana
Gui, Add, Text, x0 y20 w400 Center,Mouse click on this window
Gui, Add, Text,    y+5 w400 Center,or Press any key to Cancel
Gui,Font, s72 Bold , Verdana
Gui, Add, Text,    y+5 w400 Center vTimeout, % A_Space
Gui,Show, w400, System ShutDown in Progress!
Sleep 250

SetTimer, UpdateCountDown, 999
KeyPressed:=InputKey(20000) ; [color=#000000]Wait for a Keypress for 20 secs[/color]
If KeyPressed 
   ExitApp
Else
  {
;  ShutDown, 8
   ExitApp
  }
Return

UpdateCountDown:
GuiControl,,Timeout, % A_KBI_TimeLeft ; [color=#000000]A_KBI_TimeLeft var is[/color]
Return                                ; [color=#000000]updated by InputKey()[/color]

#Include InputKey.ahk
The above example requires the following file(s):
Download InputKey.ahk [0.9K]



Example 2:

One may use the following example to find the Virtual key-code for any key (hopefully!) in their keyboard!
These Virtual key-codes can be used for Hotkeys.

AHK Documentation:

VKnn (where nn is the hexadecimal virtual key code of a key) - Although this rarely-used method is supported in all versions, only in v1.0.38.02+ does it prevent certain types of hotkeys from requiring the keyboard hook. For example, the following hotkey does not use the keyboard hook, but as a side-effect it is triggered by pressing either Home or NumpadHome: ^VK24::MsgBox You pressed Home or NumpadHome while holding down Control.


Posted Image
#Persistent
ClipBack:=Clipboard
Gui, +AlwaysOnTop -SysMenu
Gui, Margin, 20, 20
Gui, Font, s18 Bold, Verdana
[color=black];Uncomment the following line to suppress System Sound Event DING.WAV![/color]
;Gui, Add, Listview, x20 y20 w90 h33 vDummyListView
Gui, Add, Text    , x20 y20 w90 h33 c686868 +0x200 +Center +Border vVKCODE
Gui, Add, Text, x+5        w400 h33 c3D3D30 +0x200 vVKNAME
Gui, Show, , Virtual-Key Code Finder .. Press any key!

Loop {
      KeyPressed:=InputKey()
      IniRead, VK, VK_NAMES.INI, VirtualKeyName, %KeyPressed%, %A_Space%
      GuiControl,,VKNAME, %VK%
      StringRight, Code, KeyPressed, 2
      Clipboard = % "VK" Code
      GuiControl,,VKCODE, % "VK" Code
     }
Return

GuiEscape:
 Clipboard:=ClipBack
 ExitApp
Return

#Include InputKey.ahk
The above example requires the following file(s):
Download InputKey.ahk [0.9K]
Download VK_NAMES.INI [4K] which contains the list of Virtual-key codes with names.

* - *

I will post more Scripts based on InputKey() in seperate topics!

Guess-It / Word Game v3.0 is a fully keyboard compatible ( also supports mouse :evil: ) script
for which I created this InputKey() function. I have lost interest in posting the source owing
to lack lustre interest shown :(. In case if anyone interested in viewing the source post in that topic.
It is one of my favourites measuring a mere 200 lines (all inclusive) for such functionality.

I am rewriting Incrementally switch between windows scripted by keyboardfreak.
My version will pass the ID of the window to a set of external scripts that shall
manipulate the window. Examples : Close, Toggle Always-On-Top, Resize, Change Title etc.
That is one script for each functionality. The main script will be very compact and it basic functionality
will be to Search & Switch between windows, using InputKey().

Regards, :)


Edit: Demonstration script has been posted:

Crazy Scripting : Secret Numeric Labels


kWo4Lk1.png

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
I wrote this to simulate an Inputbox in Windows 98 SE .. Just giving it as
as an additional example....

Posted Image

Posted Image

The following example requires InputKey.ahk !
Download InputKey.ahk [0.9K]

; [color=blue]InputBox.ahk for Windows (All versions) - Demo[/color]

Gui +AlwaysOnTop 
Gui, Add, StatusBar
Sb_SetText("Press Enter to Complete Input")
Sb_SetIcon("User32.dll",5)
Gui, Add, ListView, x5 y15 w190 h25 +Readonly +BackgroundFFFFFF 0x4000
Gui, Add, Text, x9 y15 w182 h25 +0x200 vKeyInput BackgroundTrans
Gui, Show, w200 h75, Input

Input=
LoopExit=0

Loop {

IfEqual,LoopExit,1, Exit
vKey:=InputKey()

If (VKey>=0x41 AND VKey<=0x5A) { ; [color=#AAAAAA]Keys A - Z[/color]
   Input=% Input Chr(vKey)
   GuiControl,,KeyInput,%Input%
  } 

If (vKey=0x08) {                 ; [color=#AAAAAA]BackSpace[/color]
   StringTrimRight,Input,Input,1
   GuiControl,,KeyInput,%Input%
  } 

If (vKey=0x20) {                 ; [color=#AAAAAA]SpaceBar[/color]
   Input=% Input Chr(32)
   GuiControl,,KeyInput,%Input%
  } 

If (vKey=0x0D) {                 ; [color=#AAAAAA]Enter / Return[/color]
   Sb_SetIcon("User32.dll",2)
   Sb_SetText("Press Y to Confirm (Y/N) :")
      Loop {
             vKey2:=InputKey()
             If (Vkey2=0x59 OR vKey2=0x4E) 
                Break
           }
      If (vKey2=0x59) {          ; [color=#AAAAAA]Keys Y[/color]
         LoopExit=1
         Gui, Destroy
         MsgBox, You Entered: %Input%
         ExitApp
      }  Else {                  ; [color=#AAAAAA]Keys N[/color]
         Input=
         GuiControl,,KeyInput,%Input%
         Sb_SetIcon("User32.dll",5)
         Sb_SetText("Press Enter to Complete Input")
         Continue
      }
  } 
}
Return ; [color=blue]End of Auto-execute Section[/color]

GuiClose:
GuiEscape:
 ExitApp
Return

[color=#AA0000]#Include InputKey.ahk[/color]


kWo4Lk1.png