Restored from previous forum. Originally posted by naw. Genius - How did you know that I was looking for a program to *remote control* Apps. Just what I needed to do some benchmarking work (simulated users)...
Just made a couple of changes to *externalise* the Key Sequences into a Loadable Macro File:
==========================
In Global Section:
Launch - Initial Program To Launch/Startup
Title - Default Title to Use of *Launched* Program
Delay - Big delay after Launching Initial Program
Items - # of commands / Keys to send
Description - Pop up text that appears before Application is Launched...
In Macro Section:
cmd1 - Text / Keys to send
del1 - Delay in milisecs
tit1 - Title of Window to send the Text to (overrides the "Title")
macro.naw file:
==========================
[Global]
Items=8
Launch=C:\WINNT\NOTEPAD.EXE
Title=Untitled - Notepad
Delay=3000
Description=This Macro Should Open Notepad, do a search and replace, close the replace dialog...
[Macro]
cmd1=This is a Text Entry{RETURN}
del1=1000
cmd2=This is another Text Entry{RETURN}
del2=1000
cmd3={CONTROLDOWN}h
del3=1000
tit4=Replace
cmd4=another{TAB}
del4=1000
tit5=Replace
cmd5=yet another{ALTDOWN}a
del5=1000
tit6=Replace
cmd6={RETURN}{TAB}{TAB}{TAB}{TAB}{TAB}{RETURN}
del7=1000
cmd7={RETURN}{RETURN}Hello World{RETURN}
===================================
PBs ripped off code :wink: with a few minor changes...
===================================
; SendKeys procedure by PB -- do whatever you want with it. :)
; Syntax: r=SendKeys(handle,window$,keys$) ; r = 0 for failure.
; Specify either a handle or window$ title to type to, but not both!
; You cannot type curly braces { } as part of the keystrokes, sorry!
;
Procedure Alert(m$)
MessageRequester("Alert",m$,#MB_ICONINFORMATION)
EndProcedure
Procedure$ FN_Space(Num)
For Counter = 1 To Num : Tmp$ + " " : Next Counter
ProcedureReturn Tmp$
EndProcedure
Procedure.s FN_readINI(inifile.s, section.s, key.s)
result.s = FN_Space(255)
Empty.s = ""
Ret = GetPrivateProfileString_(section, key, empty, @result, 255, inifile.s)
ProcedureReturn result
EndProcedure
Procedure.l FN_writeINI( inifile.s,section.s, key.s, value.s)
result = WritePrivateProfileString_(section, key, value, inifile)
ProcedureReturn result
EndProcedure
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 0 ; 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 thread1thread2 : 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.
Select s$ ; Get virtual key code of special key.
Case "ALTDOWN" : keybd_event_(#VK_MENU,0,0,0) ; Hold ALT down.
Case "ALTUP" : keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT.
Case "BACKSPACE" : vk=#VK_BACK
Case "CONTROLDOWN" : keybd_event_(#VK_CONTROL,0,0,0) ; Hold CONTROL down.
Case "CONTROLUP" : 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
EndSelect
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.
If vk>304 And shifted=0 : keybd_event_(#VK_SHIFT,0,0,0) : EndIf ; Due to shifted character.
keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the normal key.
If vk>304 And shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) : EndIf ; Due to shifted character.
EndIf
Next
If thread1thread2 : 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 1 ; Report successful typing!

EndIf
EndProcedure
Procedure GoMacro(x$,t$,m$)
desc$=FN_ReadINI(m$,"Global","Description"): If (desc$) : Alert(desc$): EndIf
If (RunProgram(x$,"",0))
Delay(Val(FN_ReadINI(m$,"Global","Delay"))+1)
maxctr=Val(FN_ReadINI(m$,"Global","Items"))
For ctr=1 To maxctr
cmd$=FN_ReadINI(m$,"Macro","Cmd"+Str(ctr))
del=Val(FN_ReadINI(m$,"Macro","Del"+Str(ctr)))
tit$=FN_ReadINI(m$,"Macro","Tit"+Str(ctr))
Delay(del)
If (tit$): SendKeys(0,tit$, cmd$): Else: SendKeys(0,t$,cmd$): EndIf
Next
Else: Alert("Couldnt start "+x$)
EndIf
EndProcedure
Dim SPCL.s(40)
SPCL(01)="ALTDOWN"
SPCL(02)="ALTUP"
SPCL(03)="BACKSPACE"
SPCL(04)="CONTROLDOWN"
SPCL(05)="CONTROLUP"
SPCL(06)="DELETE"
SPCL(07)="DOWN"
SPCL(08)="END"
SPCL(09)="ENTER"
SPCL(10)="F1"
SPCL(11)="F2"
SPCL(12)="F3"
SPCL(13)="F4"
SPCL(14)="F5"
SPCL(15)="F6"
SPCL(16)="F7"
SPCL(17)="F8"
SPCL(18)="F9"
SPCL(19)="F10"
SPCL(20)="F11"
SPCL(21)="F12"
SPCL(22)="ESCAPE"
SPCL(23)="HOME"
SPCL(24)="INSERT"
SPCL(25)="LEFT"
SPCL(26)="PAGEDOWN"
SPCL(27)="PAGEUP"
SPCL(28)="PRINTSCREEN"
SPCL(29)="RETURN"
SPCL(30)="RIGHT"
SPCL(31)="SHIFTDOWN"
SPCL(32)="SHIFTUP"
SPCL(33)="TAB"
SPCL(34)="UP"
WID=OpenWindow(1, 100, 100, 400, 600, #PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget, "MACRO CONTROL")
CreateGadgetList(WindowID())
TextGadget(1,10,10,200,16,"List of *Special Keys*"): ComboBoxGadget(2,10,30,200,800)
For x=1 To 40: If SPCL(x): AddGadgetItem(2,-1,SPCL(x)): EndIf: Next: SetGadgetState(1,2)
;TextGadget(3,220,10,200,16,"Open *Special Key* char"): StringGadget(4,360,10,16,16,"{")
;TextGadget(5,220,30,200,16,"Close *Special Key* char"): StringGadget(6,360,30,16,16,"}")
ButtonGadget(7,10,70,100,26,"Launch Program"): StringGadget(8,10,100,170,18,"")
TextGadget(9,10,130,100,16,"Titlebar Text"): StringGadget(10,10,150,170,18,"")
ButtonGadget(11,220,70,100,26,"Open Macro File"): StringGadget(12,220,100,170,18,"")
ButtonGadget(20,220,130,170,46,"Run Macro Against Program"):
TextGadget(13,10,190,380,80,"[url]mailto:Nigel_Wale@uk.ibm.com[/url]"+Chr(13)+Chr(13)+"nawMacro.exe - simple Macro Program for windows - good for benchmarking or automating certain tasks"+Chr(13)+Chr(13)+"example:")
TextGadget(14,20,270,380,400,Chr(13)+"[Global]"+Chr(13)+"Items=6"+Chr(13)+"Launch=C:\WINNT\NOTEPAD.EXE"+Chr(13)+"Title=Untitled - Notepad"+Chr(13)+Chr(13)+"[Macro]"+Chr(13)+"cmd1=This is a Text Entry{RETURN}"+Chr(13)+"del1=1000"+Chr(13)+"cmd2=This is another Text Entry{RETURN}"+Chr(13)+"del2=1000"+Chr(13)+"cmd3={CONTROLDOWN}h"+Chr(13)+"del3=1000"+Chr(13)+"tit4=Replace"+Chr(13)+"cmd4=another{TAB}"+Chr(13)+"del4=1000"+Chr(13)+"tit5=Replace"+Chr(13)+"cmd5=yet another{ALTDOWN}a"+Chr(13)+"del5=1000"+Chr(13)+"cmd6={RETURN}{RETURN}Hello World{RETURN}"+Chr(13)+"del6=1000")
QUIT=0
Repeat: wevent=WaitWindowEvent()
Select wevent
Case #WM_DROPFILES:
Case #WM_CLOSE : QUIT=1
Case #PB_EventCloseWindow: QUIT=1
Case #PB_EventGadget:
Select EventGadgetID()
Case 7: SetGadgetText(8,OpenFileRequester("Program To Launch","*.exe","*.exe",1))
Case 11: SetGadgetText(12,OpenFileRequester("Macro File","macro.naw","*.naw",1)):
SetGadgetText(10,FN_ReadINI(GetGadgetText(10)+GetGadgetText(12),"Global","Title"))
SetGadgetText(8,FN_ReadINI(GetGadgetText(8)+GetGadgetText(12),"Global","Launch"))
Case 20:
If (GetGadgetText(8) And GetGadgetText(10) And GetGadgetText(12)):
GoMacro(GetGadgetText(8),GetGadgetText(10),GetGadgetText(12)):
Else: Alert("Must Specify:"+Chr(13)+" Open / Close *Special Character"+Chr(13)+"Launch Program & Macro File"):
EndIf
Default:
EndSelect
Case #PB_EventMenu:
Select EventMenuID():
Case 1:
Default:
EndSelect
EndSelect
Until QUIT=1