I know how the SendKeys functions work in the traditional sense of hotkey applications, but is there a way to hold keys down for specified amount of time? For example, I want to hold some keys down while an executable is being run. Any ideas?
Thanks in advance.
The article pointed to by the link below along with a bit of research, critical thinking and scripting could provide a solution:
http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/Sending~Keystrokes+Send~Fn~key~on~a~Notebook.txt (http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/Sending~Keystrokes+Send~Fn~key~on~a~Notebook.txt)
A limited and rough example:
#DefineFunction GetVirualKeyScanCode( nVirtualKey )
nScanCode = DllCall("user32.dll", long:"MapVirtualKeyA", long:nVirtualKey, long:0)
Return nScanCode
#EndSubRoutine
#DefineFunction SendKeyInput( strKey, strState )
; Flag member values
INPUT_KEYBOARD = 1
KEYEVENTF_EXTENDEDKEY = 1 ; Causes a 0xE0 to be sent ahead of the key
KEYEVENTF_KEYUP = 2
KEYEVENTF_SCANCODE = 8
; INPUT structure descriptor.
strInput = $"DWORD::type
WORD::wVk
WORD::wScan
DWORD::dwFlags
DWORD::time
LONG_PTR::dwExtraInfo
DWORD::Padding1
DWORD::Padding2$" ; 8 byte padding necessary because structure contains a union.
hInput = DllStructAlloc(strInput)
DllStructPoke(hInput, 'type', INPUT_KEYBOARD)
; Assume are ANSI key with same virtual key code.
nVk = Char2Num(StrUpper(strKey))
DllStructPoke(hInput, 'wVk', nVk)
DllStructPoke(hInput, 'wScan', 0) ;GetVirualKeyScanCode(nVk))
if StriCmp(strState, 'UP')
DllStructPoke(hInput, 'dwFlags', KEYEVENTF_KEYUP) ;|KEYEVENTF_SCANCODE
else
DllStructPoke(hInput, 'dwFlags', 0) ;KEYEVENTF_SCANCODE)
endif
DllStructPoke(hInput, 'time', 0)
DllStructPoke(hInput, 'dwExtraInfo', 0)
; Do the deed.
dwSize = IntControl(98, hInput, 1, 0, 0)
nResult = DllCall("user32.dll", long:"SendInput", long:1, lpstruct:hInput, long:dwSize)
; Clean up
DllStructFree(hInput)
Return nResult ; 0 on failure otherwise number of inputs.
#EndFunction
; Key down for one second
nResult1 = SendKeyInput('H', 'down')
TimeDelay(1)
nResult2 = SendKeyInput('H', 'up')
If nResult1 && nResult2
sText = "Success"
Else
sText = "Failure"
EndIf
Message("SendKey Test", sText)
Neglected to mention that most systems are set to begin repeating a key down and up press after a key has been physically held down for a predetermined time. If that is the end goal then the SendKey function's repeat key feature can be used instead of using DllCall on the Win32 'SendInput' function.
Thank you. I now have stuff to experiment with. :D
I noticed in the code you supplied below that the first
DefineFunction is closed with an
EndSubRoutine. Forgive my ignorance, but I thought a DefineFunction is supposed to be closed with an EndFunction, and a DefineSubroutine is supposed to be closed by an EndSubRoutine. Am I wrong?
Quote from: td on October 19, 2016, 03:11:28 PM
A limited and rough example:
#DefineFunction GetVirualKeyScanCode( nVirtualKey )
nScanCode = DllCall("user32.dll", long:"MapVirtualKeyA", long:nVirtualKey, long:0)
Return nScanCode
#EndSubRoutine
#DefineFunction SendKeyInput( strKey, strState )
; Flag member values
INPUT_KEYBOARD = 1
KEYEVENTF_EXTENDEDKEY = 1 ; Causes a 0xE0 to be sent ahead of the key
KEYEVENTF_KEYUP = 2
KEYEVENTF_SCANCODE = 8
; INPUT structure descriptor.
strInput = $"DWORD::type
WORD::wVk
WORD::wScan
DWORD::dwFlags
DWORD::time
LONG_PTR::dwExtraInfo
DWORD::Padding1
DWORD::Padding2$" ; 8 byte padding necessary because structure contains a union.
hInput = DllStructAlloc(strInput)
DllStructPoke(hInput, 'type', INPUT_KEYBOARD)
; Assume are ANSI key with same virtual key code.
nVk = Char2Num(StrUpper(strKey))
DllStructPoke(hInput, 'wVk', nVk)
DllStructPoke(hInput, 'wScan', 0) ;GetVirualKeyScanCode(nVk))
if StriCmp(strState, 'UP')
DllStructPoke(hInput, 'dwFlags', KEYEVENTF_KEYUP) ;|KEYEVENTF_SCANCODE
else
DllStructPoke(hInput, 'dwFlags', 0) ;KEYEVENTF_SCANCODE)
endif
DllStructPoke(hInput, 'time', 0)
DllStructPoke(hInput, 'dwExtraInfo', 0)
; Do the deed.
dwSize = IntControl(98, hInput, 1, 0, 0)
nResult = DllCall("user32.dll", long:"SendInput", long:1, lpstruct:hInput, long:dwSize)
; Clean up
DllStructFree(hInput)
Return nResult ; 0 on failure otherwise number of inputs.
#EndFunction
; Key down for one second
nResult1 = SendKeyInput('H', 'down')
TimeDelay(1)
nResult2 = SendKeyInput('H', 'up')
If nResult1 && nResult2
sText = "Success"
Else
sText = "Failure"
EndIf
Message("SendKey Test", sText)
It doesn't matter: #endfunction or #endsubroutine will work with either #definefunction or #definesubroutine.