Yup, as I expected.
PB is a little easier to use when it comes to doing resident WinAPI calls. I still may consider re-writing this into my Clarion exe, but as you can see below it will be very easy to pass two command line parameters ("sendkeys.exe “Microsoft Flight Simulator” “{SHIFTDOWN}G{SHIFTUP}”) into a PB SendKeys.exe and it does the rest of the work.
PB Code:
Procedure SendKeys(handle,window$,keys$)
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(125) ; 1/8 second pause before typing, to prevent fast CPU problems.
; Now the actual typing starts.
For r=1 To Len(keys$)
vk$=Mid(keys$,r,1)
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.
notakey=#False
Select s$ ; Get virtual key code of special key.
Case "ALTDOWN" : alted = 1 : keybd_event_(#VK_MENU,0,0,0) ; Hold ALT down.
Case "ALTUP" : alted = 0 : keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT.
Case "BACKSPACE" : vk=#VK_BACK
Case "CONTROLDOWN" : ctrled = 1 : keybd_event_(#VK_CONTROL,0,0,0) ; Hold CONTROL down.
Case "CONTROLUP" : ctrled = 0 : keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL.
Case "DELETE" : vk=#VK_DELETE
Case "DOWN" : vk=#VK_DOWN
Case "END" : vk=#VK_END
Case "ENTER" : vk=#VK_RETURN
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 "ESCAPE" : vk=#VK_ESCAPE
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 "RETURN" : vk=#VK_RETURN
Case "RIGHT" : vk=#VK_RIGHT
Case "SHIFTDOWN" : shifted=1 : keybd_event_(#VK_SHIFT,0,0,0) ; Hold SHIFT down.
Case "SHIFTUP" : shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT.
Case "TAB" : vk=#VK_TAB
Case "UP" : vk=#VK_UP
Default
notakey = #True
EndSelect
If notakey=#False
If Left(s$,3)<>"ALT" And Left(s$,7)<>"CONTROL" And Left(s$,5)<>"SHIFT"
keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the special key.
EndIf
r=r+s+1 ; Continue getting the keystrokes that follow the special key.
Else
vk=VkKeyScanEx_(Asc(vk$),GetKeyboardLayout_(0)) ; Normal key found
keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the normal key.
EndIf
Else
;LoadKeyboardLayout_("000040c",#KLF_ACTIVATE|#KLF_REORDER)
vk=VkKeyScanEx_(Asc(vk$),GetKeyboardLayout_(0)) ; Normal key found
If (vk&$0100)<>0 And shifted = 0 : keybd_event_(#VK_SHIFT,0,0,0) : EndIf ; Due to shifted character.
If (vk&$0200)<>0 And ctrled = 0 : keybd_event_(#VK_CONTROL,0,0,0) : EndIf
If (vk&$0400)<>0 And alted = 0 : keybd_event_(#VK_MENU,0,0,0) : EndIf
keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the normal key.
If (vk&$0100)<>0 And shifted = 0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) : EndIf ; Due to shifted character.
If (vk&$0200)<>0 And ctrled = 0 : keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) : EndIf
If (vk&$0400)<>0 And alted = 0 : keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) : EndIf
EndIf
Next
If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#False) : EndIf ; Finished typing to target window!
keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT key if user forgot.
keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL key if user forgot.
keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT key if user forgot.
ProcedureReturn #True ; Report successful typing! :)
EndIf
EndProcedure
;Test using an open NotePad.exe
w$="Untitled - Notepad" ; Specifies target window name.
SendKeys(0,w$,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\\\///___----[[[") ; Type some dummy text.
SendKeys(0,w$,"{CONTROLDOWN}a{CONTROLUP}") ; Select it all.
SendKeys(0,w$,"{DELETE}") ; Delete it.