Making another application active

Can anyone give me a snippet that shows how to make another Application the active one

I ran into a snag with my test automation program.

Everything is fine if I make it totally passive: run the Application I am testing, then run my program, and finally, make the application active again by clicking on it.

When I do this, my app sends keyboard strokes to the program with no problem.

But if I need to select an option later on in my test program, keyboard strokes start going to my test program instead of the Application.

I use SetFocusAPI to set the focus correctly, but if the Application is not the active one, setting the focus doesn't work. As a work-around, I put a delay timer on my option, so I can make my choice, then manually make the other application active again. (And after the short time delay, keystrokes start up again.)

I suppose I could resort to something crude, like programmatically moving the mouse cursor over the Application's titlebar and sending a click event, but it seems like there should be another way.

Any ideas



Answer this question

Making another application active

  • shrek2006

    Thanks again, DMan

    Yup, I use FindWindow to get all my handles, and sometimes I use SetWindowPos to move one around or resize it.

    In this case, I am simulating a user by actually moving the mouse, and simulating him hitting keys. This allows me to try some pretty wild methods to cause a program to fail, so I can work on the weak-spots. It also allows me to use some known test values to make sure that output is correct.

    (SetWindowPos is cheating in this case, since I can shrink a "fixed" size window using it... My goal is to do things a regular Joe might do....)


  • Barnabas

    Dang, I thought that would do it... I do appreciate the suggestion.

    Nope - that only works if I shelled out the test Application in the first place. (This would be awkward in the way I am using it... the Application is running all the time; I'm just simulating a user using given test inputs. The Application needs to continue running to be a valid test.)

    Common sense seems to tell me that whichever window is Active will get keystrokes, but using keybd_event may not be the same as actually hitting keys, if you see what I'm getting at. Obviously my own program can not be the "active" application when keystrokes are being sent...

    And I know that programs can continue running in the background (like common games...) the Test Automater I'm using should be able to function in the background. (An earlier version worked just fine - don't you hate making changes )

    I pulled out my "Sendit" routine, stuck it into a new bare-bones winapp, and I'm testing it separately against Notepad to see if the problem is specific to the target Application. Basically trying to see how Focus and Active application interact when sending keyboard events.


  • Michiel Wories - MSFT

    Will Appactivate give you what you need.

    I've used this to when writing some testcode to click the cancel dialog on some copy commands.

    I write a process which is basically looping for a set amount of time doing an appactivate dialog. If its not there then it will raise an exception which I can ignore and keep trying.

    If it is then it will activate and then I use sendkeys to in essence click the cancel.

    The appactivate can take either a window name (which is what I use) or Process ID which i've seen examples of.


  • rscp

    Here is some api stuff that may help you:

    Declare Sub SetWindowPos Lib "User" (ByVal hWnd As Integer, ByVal hWndInsertAfter As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer)

    Global Const SWP_NOACTIVATE = &H10

    Global Const SWP_SHOWWINDOW = &H40

    Global Const HWND_TOPMOST = -1

    Global Const HWND_NOTOPMOST = -2

    SetWindowPos aForm.hWnd, Pos%, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW

    Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

    'Retrive the window's handle of the specified window's title

    Public Function WindowHandle(sTitle As String) As Long

    WindowHandle = FindWindow(vbNullString, sTitle)

    End Function

    Private Sub Command1_Click()

    MsgBox WindowHandle("WindowTitle") 'Specify the exact caption of the window

    End Sub



  • Pinakin

    Finally got it. Dan Appleton's VB Programmer's Guide to the Win32 API explains the problem on page 161. It seems that new programs developed with VB.NET run as 32 bit applications, and SetFocusAPI doesn't have any affect on them. (Microsoft again, protecting us from ourselves... Unfortunately, this makes writing automated test programs more difficult)

    Fortunately, there is a solution - SetForeground Window. Perfect - just what I needed. This does just what I wanted; basically the same as clicking on the other application, but without a kludgy solution.

    Private Declare Function SetForegroundWindow Lib "user32.dll" (ByVal hWnd As Integer) As Long


  • helpstring

    I tried something a little different: I minimized the program before sending the keystrokes.

    This works after a fashion, but it assumes that the Application I want to get focus was the active program before I clicked on the test automater.

    I may end up living with the delay (Giving me time to click on the Application and make it active), or better yet Simulating a mouse click on my target Application before sending keystrokes.

    It just seems like there ought to be a way to pass control of the Active program using an API or something...


  • Making another application active