Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Animate application with sendkeys

Status
Not open for further replies.

Glasgow

IS-IT--Management
Jul 30, 2001
1,669
0
0
GB
I am trying to use Sendkeys to automate my application but in a way whereby it is visible to the user what is happening. I can do this using Sendkeys but it all happens to fast and all my attempts to implement delays have been unsuccessful.

As an example, I'd like to send the Alt key (SendKeys "%")alone to activate the MDIForm's drop down menu bar then move along two menus (SendKeys "{RIGHT}" x 2) then down three options on the menu (SendKeys "{DOWN}" x 3) then select that option (SendKeys "{ENTER}"). All at a speed that the user can see each movement (e.g. half a second between each movement.

I have tried using the sendkeys wait parameter, Doevents plus enforced delays (using Sleep API call) all to no avail.

Any suggesions?

Thanks in advance.
 
I don't seem to have problems when, for example, I am sending straight text to a textbox with a delay between each character. It just seems to be with the menu navigation - for now!
 
I think your problem comes from the fact that with SendKeys, groups of characters which form a special key, such as %F and {Right}, need to be passed to SendKeys as a group.

Here is some VBA code which works for me (in Access 2000). I think it should work with other 'flavours' of VB as it doesn't use any complex functions.

To run this test code, you need a form containing three objects:

Command0 - command button
txtTest1 and txtTest2 - text boxes

Add this to the button's click event:
Code:
Private Sub Command0_Click()

Dim iPos As Integer
Dim iBracket As Integer
Dim lngWaitTime As Long
Dim strTextToSend As String

'This is the string I want to send via SendKeys.  It
'includes normal text, an 'Alt' key to activate a menu,
'and cursor right commands
strTextToSend = "ABC%F{Right}{Right}"

txtTest1.SetFocus
iPos = 1

Do
    Select Case Mid$(strTextToSend, iPos, 1)
    
    'Found a left bracket.  Find the matching right
    'bracket, and pass string to SendKeys
    Case Is = "{"
        iBracket = InStr(iPos, strTextToSend, "}")
        txtTest2 = Mid$(strTextToSend, iPos, iBracket - iPos + 1)
        SendKeys Mid$(strTextToSend, iPos, iBracket - iPos + 1)
        iPos = iBracket + 1

    'Found Alt, Ctrl or Shift symbol.  Pass two
    'characters to SendKeys
    Case Is = "%", "+", "^"
        txtTest2 = Mid$(strTextToSend, iPos, 2)
        SendKeys Mid$(strTextToSend, iPos, 2)
        iPos = iPos + 2

    'All other text - passed one character at a time
    Case Else
        txtTest2 = Mid$(strTextToSend, iPos, 1)
        txtTest1.SetFocus
        SendKeys Mid$(strTextToSend, iPos, 1)
        iPos = iPos + 1
    End Select
    
    'This creates the half-second pause between 'sends'
    lngWaitTime = Timer + 0.5
    Do
        DoEvents
    Loop Until Timer > lngWaitTime
Loop Until iPos >= Len(strTextToSend)

MsgBox "finished"

End Sub
I have added lines to display the individual strings being sent, in txtTest2. These are not needed in the final working version.

When I click the button, I see:
-- ABC typed into txtTest1 with half-second gaps
-- The File menu activates
-- The cursor steps two menus to the right.
-- The 'finished' message appears.

I hope that this helps.


Bob Stubbs
 
Thanks Bob - I don't think this is my problem. I am sending the special sequences as complete strings.

For example
Code:
FrmMenu.SetFocus
SendKeys "%"
Sleep 500 'milliseconds
DoEvents
SendKeys "{RIGHT}"
Sleep 500 'milliseconds
DoEvents
SendKeys "{RIGHT}"
Sleep 500 'milliseconds
DoEvents

only seems to get as far as highlighting the first menu - it doesn't move right - it just seems to hang there
 
OK - maybe the problem is with sending '%' by itself. I have had another look and found:

-- If I send % by itself, then the {Right} instructions, I can see the menu title highlighted, but the actual menus do not drop down.

-- If I send %F, the File menu drops down. If I then send the {Right} instructions, successive menus drop down as the cursor moves to the right.

Try this manually - if it creates the effect you are looking for, change your code to send e.g. %F instead of just %, where F is the shortcut letter for the first of your menus.



Bob Stubbs
 

I think there is at least a couple of problems with your code, Glasgow.

1. Sleep 500 will give you half a second - that's fast.
2. You should use AppActivate before each SendKey - you may be losing focus.
3. DoEvents should not be used if you are not using AppActivate - you could be losing focus.
 
Thanks guys. I twigged to the DoEvents and removed it as it was behaving as though I'd set the Sendkeys Wait parameter as true (waiting for me to do something in the window before executing next line of code?). The effect now is that it appears to simply accumulate the delays and buffer the different sendkeys commands so there is a long delay while nothing happens then it does it all in one go so I get no noticeable stepping from menu to menu but it ends up where I want - no better then blasting all the keys in one hit. How infuriating - I must surely be doing something really dumb! Using AppActivate does not seem to help.
 
I thought using AppActivate solved the problem you mentioned earlier: only seems to get as far as highlighting the first menu - it doesn't move right - it just seems to hang there.

By the way, did you implement all my suggestions into the same test run? How does your code look now?
 
I've tried this with and without the DoEvents

Code:
FrmMenu.SetFocus
SendKeys "%C{DOWN}{DOWN}"
Sleep 1000 'milliseconds
AppActivate App.Title
'DoEvents
SendKeys "{RIGHT}"
AppActivate App.Title
Sleep 1000 'milliseconds
'DoEvents
SendKeys "{RIGHT}"
Sleep 1000 'milliseconds
AppActivate App.Title
'DoEvents
 
What OS version are you using? Do you have all the patches in place?

What is %C (alt C) supposed to do?
 
Windows XP Sp1 (so sp2 not yet installed). VB SP6. Alt C fires a specific menu which is to the left of the one I want to move to.
 
sp2 not yet installed - good for you!

Try waiting for the menu to come to life before navigating it.

Code:
FrmMenu.SetFocus
AppActivate App.Title, True
SendKeys "%C"
Sleep 1000 'milliseconds
AppActivate App.Title, True
SendKeys "{DOWN 2}"
Sleep 1000 'milliseconds
AppActivate App.Title, True
'DoEvents
SendKeys "{RIGHT}"
AppActivate App.Title, True
Sleep 1000 'milliseconds
'DoEvents
SendKeys "{RIGHT}"
 
Frankly, I'd consider using the SendInput API rather than VB's kludgy and often unreliable SendKeys
 
Dimandja - thanks but same symptoms, long delay then all at once.

strongm - thanks also, I'll have a play and report back.
 
Believe it or not I am getting very similar symptoms with SendInput - i.e. long delay then blasts the whole lot. Aaaargh.

It seems I need to somehow flush the key codes I am 'accumulating' but neither DoEvents nor AppActivate seem to help.
 
Hello all,

Granted all the shakiness of using sendkeys, one more element one has to take into consideration. The design spirit of xp is to prevent desktop application's focus being "stolen". The default setting is in the registry.
[tt]
[HKEY_CURRENT_USER\Control Panel\Desktop"
"ForegroundLockTimeout"=0x00030D10
[/tt]
which is equivalent to a "eternal" 200 seconds before the focus can switch over without user intervention.

So you xp onward, this is a factor to consider the practicality of sendkeys as well.

regards - tsuji
 
Thanks Tsuji

Is this an issue even if I am sending the keys from the same application? If so, is there a way around this without tampering with the registry?
 
Glasgow,

It is just concerning the Appactivate an application off-focused.

- tsuji
 
Glasgow,
Try using For..Next to type the characters one by one

e.g.
For i = 1 to Len(string)
Sendkeys Mid(string,i,1)
Next i

 
If you do it like this, it seems to work. The problem is having all the sendkeys in the same (event) procedure.
I can't exactly remember why this is, but VB is picky when it comes to handling certain chains of commands in the same event.

Code:
Private Sub Command1_Click()
   SendKeys "%E"
End Sub

Private Sub Wait(ByVal Period As Integer)
   Dim StartTimer As Double
   Dim EndTimer As Double
   
   EndTimer = Timer + Period
   Do While EndTimer > Timer
      DoEvents
   Loop
End Sub

Private Sub Edit_Click()
   Wait 1
   SendKeys "{DOWN 2}"
End Sub
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top