inspired from some codes her arround, I created a working (and maybe usefull) standalone application.
You can use it as a single command, or with an optional file as a tool to automate some things.
I wrote this, because I had to automate a file upload to a web shop which is using https.
So it was not possible for me to detect the exact parameters of the web pages.
That was the reasopn for this tool.
Save it as SendKeysToWindow.pb
Code: Select all
;
; SendKeysToWindow.pb
;
; based on code from PB, Danilo, ts-soft and freepurebasic
;
; extended to a standalone console program
; extended the DELAY command with an optional delay value {DELAY}{1.5}
; addded RUN command {RUN}{notepad}
; replaced 'superseeded' keybd_event() with SendInput()
;
; added additional delay for fast CPUs and windows 7
Structure FindWindowData
hFW.l ; variable to store a handle
sFW.s ; variable to store a Window name
cFW.s ; variable to store a window class name
EndStructure
Global NewList WindowList.FindWindowData()
Procedure.l EnumWindowsCallBack(hFind, lParam)
WindowName.s = Space(255)
WindowClass.s = Space(255)
If GetWindowText_(hFind, WindowName, 255)
If FindString(WindowName, "SendKeysToWindow", 1) = 0 ; not our own window !!!
Result = GetClassName_(hFind, WindowClass, 255)
AddElement(WindowList())
WindowList()\hFW = hFind
WindowList()\sFW = WindowName
WindowList()\cFW = WindowClass
EndIf
EndIf
ProcedureReturn #True
EndProcedure
Procedure SendKeys(handle, window$, keys$)
Dim InputData.INPUT(10)
If window$ <> "" : handle = FindWindow_(0, window$) : EndIf ; Use window$ instead of handle.
If IsWindow_(handle) = 0 ; Does the target window actually exist?
ProcedureReturn #False ; Nope, so report 0 for failure to type.
Else
; This block gives the target window the focus before typing.
thread1 = GetWindowThreadProcessId_(GetForegroundWindow_(), 0)
thread2 = GetWindowThreadProcessId_(handle, 0)
If thread1 <> thread2 : AttachThreadInput_(thread1, thread2, #True) : EndIf
SetForegroundWindow_(handle) ; Target window now has the focus for typing.
Delay(250) ; 1/4 second pause before typing to prevent fast CPU problems.
; Now the actual typing starts.
CompilerIf #True
; Release ALT key before typing.
InputData(0)\Type = #INPUT_KEYBOARD
InputData(0)\ki\wVk = #VK_MENU
InputData(0)\ki\dwFlags = #KEYEVENTF_KEYUP
; Release CONTROL key before typing.
InputData(1)\Type = #INPUT_KEYBOARD
InputData(1)\ki\wVk = #VK_CONTROL
InputData(1)\ki\dwFlags = #KEYEVENTF_KEYUP
; Release SHIFT key before typing.
InputData(2)\Type = #INPUT_KEYBOARD
InputData(2)\ki\wVk = #VK_SHIFT
InputData(2)\ki\dwFlags = #KEYEVENTF_KEYUP
; Release WINDOWS key before typing.
InputData(3)\Type = #INPUT_KEYBOARD
InputData(3)\ki\wVk = #VK_LWIN
InputData(3)\ki\dwFlags = #KEYEVENTF_KEYUP
;SendInput_(4, InputData(), SizeOf(INPUT))
For n = 0 To 3
SendInput_(1, @InputData(n), SizeOf(INPUT))
Delay(20)
Next n
CompilerEndIf
For r = 1 To Len(keys$)
InputCounter = 0
vk = 0 : vk$ = Mid(keys$,r,1)
; PrintN("+" + vk$ + "+" + Str(r))
If vk$="{" ; Special key found.
s = FindString(keys$, "}", r + 1) - (r + 1) ; Get length of special key.
s$ = Mid(keys$, r + 1, s) ; Get special key name.
Select s$ ; Get virtual key code of special key.
Case "DELAY"
vk = 0
If Mid(keys$, r + 7, 1) = "{"
help = FindString(keys$, "}", r + 7)
Time$ = Mid(keys$, r + 8, help - r - 8)
; PrintN("-" + Time$ + "-")
Time = ValF(Time$) * 1000
s + Len(Time$) + 2
Else
Time = 1000
EndIf
;PrintN("Delay: " + Str(Time))
Delay(Time) ; Delay typing for one second.
Case "RUN"
vk = 0
If Mid(keys$, r + 5, 1) = "{"
help = FindString(keys$, "}", r + 5)
Program$ = Mid(keys$, r + 6, help - r - 6)
;PrintN("-" + Program$ + "-")
s + Len(Program$) + 2
;PrintN("Program: " + Program$)
RunProgram(Program$) ; Start the program
EndIf
Case "ALTDOWN"
alted = 1
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_MENU
InputData(InputCounter)\ki\dwFlags = 0
InputCounter + 1
Case "ALTUP"
alted = 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_MENU
InputData(InputCounter)\ki\dwFlags = #KEYEVENTF_KEYUP
InputCounter + 1
Case "BACKSPACE" : vk = #VK_BACK
Case "CONTROLDOWN"
ctrled = 1
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_CONTROL
InputData(InputCounter)\ki\dwFlags = 0
InputCounter + 1
Case "CONTROLUP"
ctrled = 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_CONTROL
InputData(InputCounter)\ki\dwFlags = #KEYEVENTF_KEYUP
InputCounter + 1
Case "DELETE" : vk = #VK_DELETE
Case "DOWN" : vk = #VK_DOWN
Case "END" : vk = #VK_END
Case "ENTER" : vk = #VK_RETURN
Case "ESCAPE" : vk = #VK_ESCAPE
Case "F1" : vk = #VK_F1
Case "F2" : vk = #VK_F2
Case "F3" : vk = #VK_F3
Case "F4" : vk = #VK_F4
Case "F5" : vk = #VK_F5
Case "F6" : vk = #VK_F6
Case "F7" : vk = #VK_F7
Case "F8" : vk = #VK_F8
Case "F9" : vk = #VK_F9
Case "F10" : vk = #VK_F10
Case "F11" : vk = #VK_F11
Case "F12" : vk = #VK_F12
Case "HOME" : vk = #VK_HOME
Case "INSERT" : vk = #VK_INSERT
Case "LEFT" : vk = #VK_LEFT
Case "PAGEDOWN" : vk = #VK_NEXT
Case "PAGEUP" : vk = #VK_PRIOR
Case "PRINTSCREEN" : vk = #VK_SNAPSHOT
Case "RIGHT" : vk = #VK_RIGHT
Case "SCROLL" : vk = #VK_SCROLL
Case "SPACE" : vk = #VK_SPACE
Case "SHIFTDOWN"
shifted = 1
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_SHIFT
InputData(InputCounter)\ki\dwFlags = 0
InputCounter + 1
Case "SHIFTUP"
shifted = 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_SHIFT
InputData(InputCounter)\ki\dwFlags = #KEYEVENTF_KEYUP
InputCounter + 1
Case "TAB" : vk = #VK_TAB
Case "UP" : vk = #VK_UP
Case "LWINDOWS" : vk = #VK_LWIN
Case "RWINDOWS" : vk = #VK_RWIN
Case "AWINDOWS" : vk = #VK_APPS
EndSelect
If Left(s$, 3) <> "ALT" And Left(s$, 7) <> "CONTROL" And Left(s$, 5) <> "SHIFT"
If vk <> 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = vk
InputData(InputCounter)\ki\dwFlags = 0
InputCounter + 1
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = vk
InputData(InputCounter)\ki\dwFlags = #KEYEVENTF_KEYUP
InputCounter + 1
EndIf
EndIf
r + s + 1 ; Continue getting the keystrokes that follow the special key
Else
vk = VkKeyScanEx_(Asc(vk$), GetKeyboardLayout_(0)) ; Normal key found
If (vk & $0100) <> 0 And shifted = 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_SHIFT
InputData(InputCounter)\ki\dwFlags = 0
InputCounter + 1
EndIf
If (vk & $0200) <> 0 And ctrled = 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_CONTROL
InputData(InputCounter)\ki\dwFlags = 0
InputCounter + 1
EndIf
If (vk & $0400) <> 0 And alted = 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_MENU
InputData(InputCounter)\ki\dwFlags = 0
InputCounter + 1
EndIf
; Press the normal key.
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = vk
InputData(InputCounter)\ki\dwFlags = 0
InputCounter + 1
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = vk
InputData(InputCounter)\ki\dwFlags = #KEYEVENTF_KEYUP
InputCounter + 1
If (vk & $0100) <> 0 And shifted = 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_SHIFT
InputData(InputCounter)\ki\dwFlags = #KEYEVENTF_KEYUP
InputCounter + 1
EndIf
If (vk & $0200) <> 0 And ctrled = 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_CONTROL
InputData(InputCounter)\ki\dwFlags = #KEYEVENTF_KEYUP
InputCounter + 1
EndIf
If (vk & $0400) <> 0 And alted = 0
InputData(InputCounter)\Type = #INPUT_KEYBOARD
InputData(InputCounter)\ki\wVk = #VK_MENU
InputData(InputCounter)\ki\dwFlags = #KEYEVENTF_KEYUP
InputCounter + 1
EndIf
EndIf
If InputCounter
; SendInput_(InputCounter, InputData(), SizeOf(INPUT))
InputCounter - 1
For n = 0 To InputCounter
SendInput_(1, @InputData(n), SizeOf(INPUT))
Delay(20)
Next n
EndIf
Next
If thread1 <> thread2 : AttachThreadInput_(thread1, thread2, #False) : EndIf ; Finished typing to target window!
CompilerIf #True
; Release ALT key in case user forgot.
InputData(0)\Type = #INPUT_KEYBOARD
InputData(0)\ki\wVk = #VK_MENU
InputData(0)\ki\dwFlags = #KEYEVENTF_KEYUP
; Release CONTROL key in case user forgot.
InputData(1)\Type = #INPUT_KEYBOARD
InputData(1)\ki\wVk = #VK_CONTROL
InputData(1)\ki\dwFlags = #KEYEVENTF_KEYUP
; Release SHIFT key in case user forgot.
InputData(2)\Type = #INPUT_KEYBOARD
InputData(2)\ki\wVk = #VK_SHIFT
InputData(2)\ki\dwFlags = #KEYEVENTF_KEYUP
; Release WINDOWS key in case user forgot.
InputData(3)\Type = #INPUT_KEYBOARD
InputData(3)\ki\wVk = #VK_LWIN
InputData(3)\ki\dwFlags = #KEYEVENTF_KEYUP
;SendInput_(4, InputData(), SizeOf(INPUT))
For n = 0 To 3
SendInput_(1, @InputData(n), SizeOf(INPUT))
Delay(20)
Next n
CompilerEndIf
ProcedureReturn #True ; Report successful typing! :)
EndIf
EndProcedure
Procedure ProcessLine(Line$)
Line$ = Trim(Line$) ; remove spaces
If Len(Line$) > 0 ; if something available
If Left(Line$, 1) <> ";" ; not a comment line
FirstSpacePos = FindString(Line$, " ", 1)
If FirstSpacePos
Window$ = Left(Line$, FirstSpacePos - 1)
Command$ = Mid(Line$, FirstSpacePos + 1)
; at the commandline starting and ending quote is eliminated
; to have the same behaviour in a file, the following was added:
If Left(Command$, 1) = #DQUOTE$
If Right(Command$, 1) = #DQUOTE$
Command$ = Mid(Command$, 2, Len(Command$) - 2)
EndIf
EndIf
Print(Window$ + "-")
PrintN(Command$)
ClearList(WindowList())
If EnumWindows_(@EnumWindowsCallBack(), 0)
ResetList(WindowList())
While NextElement(WindowList())
;PrintN("Window: " + WindowList()\sFW)
If FindString(WindowList()\sFW, Window$, 1)
;PrintN("Window: " + WindowList()\sFW)
;SendKeys(0, WindowList()\sFW, Command$)
SendKeys(WindowList()\hFW, "", Command$)
Break
EndIf
Wend
EndIf
EndIf
EndIf
EndIf
EndProcedure
If OpenConsole()
Parameters = CountProgramParameters()
If Parameters < 2
PrintN("")
PrintN("usage: SendKeysToWindow windowname keys")
PrintN(" or: SendKeysToWindow -f filename")
PrintN("")
Else
If ProgramParameter(0) = "-f"
If FileSize(ProgramParameter(1))
File = ReadFile(#PB_Any, ProgramParameter(1))
If File
While Not Eof(File)
Line$ = ReadString(File)
ProcessLine(Line$)
Wend
CloseFile(File)
EndIf
EndIf
Else
ProcessLine(ProgramParameter(0) + " " + ProgramParameter(1))
EndIf
EndIf
CloseConsole()
EndIf
Code: Select all
SendKeysToWindow Editor Hallo
Save this as test.dat
Code: Select all
Manager {RUN}{notepad}{DELAY}
Editor Hello{ENTER}{DELAY}{2}
Editor That's a simple test{ENTER}{DELAY}{3.5}
Editor {ALTDOWN}{F4}{ALTUP}
Editor {TAB}{ENTER}
Code: Select all
SendKeysToWindow -f test.dat
Bernd
P.S.: Maybe you have to find an other window than Manager.
But on my XP this 'window' is always available and so I use it as a dummy.
P.S.S: If you want more control search for AutoWin from ts-soft