How do I Task Switch to another process in VBA if all I have is a Process Id?

Posted on 2004-04-04
Last Modified: 2010-05-18
I am writting a subroutine that needs to switch to a window thats running in another process.  I tried using "AppActivate" to switch windows but my program breaks when a user opens a document or a child window in the target process.  I tried using the "FindWindow" and "SetForgroundWindow" functions from user32 but they had similar problem.  Does anyone know of a way around this problem?
Question by:Alford-Miller
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
LVL 17

Expert Comment

ID: 10754630
Are you trying to set focus to a child window in a parent window (such as the edit box in notepad) or are you just trying to set focus to a parent window (such as notepad itself)? Also.. what do you mean by "breaks"?
LVL 17

Expert Comment

ID: 10754676
For the sake of doing so.. here's an example (further down atleast).

The main problem with using ShowWindow/SetForegroundWindow/etc is the possibility of the window being a child of or related to another window. Tests with notepad and calc both yielded "hangs" (100% cpu usage) which you may be referring to with "break".

The below example shells notepad (minimized without focus.. shelled so I have a ProcID to work with) and uses ShowWindow & SetForegroundWindow on the owner of the window associated with the Process ID. Works fine for me.


Private Declare Function GetWindow Lib "User32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "User32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function ShowWindow Lib "User32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function SetForegroundWindow Lib "User32" (ByVal hWnd As Long) As Long

Private Const GW_HWNDFIRST = 0
Private Const GW_HWNDNEXT = 2
Private Const GW_OWNER = 4

Private Const SW_SHOWNORMAL = 1
Private Sub Form_Load()
    Dim lHandle As Long, lProcIDFind As Long, lProcID As Long
    Dim lTimer As Long
    Call Me.Show
    'Open testing app..
    lProcIDFind = Shell("notepad.exe", vbMinimizedNoFocus)
    'Wait for it to open..
    Call Pause(3)
    lHandle = GetWindow(Me.hWnd, GW_HWNDFIRST)
    Do Until lHandle = 0
        Call GetWindowThreadProcessId(lHandle, lProcID)
        If lProcID = lProcIDFind Then
            'Found a match
            lHandle = GetWindow(lHandle, GW_OWNER)
            Call ShowWindow(lHandle, SW_SHOWNORMAL)
            Call SetForegroundWindow(lHandle)
            Exit Sub
        End If
        lHandle = GetWindow(lHandle, GW_HWNDNEXT)
End Sub
Private Sub Pause(ByVal iSecs As Integer)
    Dim lTimer As Long
    lTimer = Timer + iSecs
    Do Until Timer > lTimer
End Sub


Expert Comment

ID: 10757670
As I read, when you try to use ShowWindow/SetForegroundWindow API's, your app hangs with 100% CPU usage ? If this is the problem, try this API:

Description from win32.hlp (

The SendNotifyMessage function sends the specified message to a window. If the window was created by the calling thread, SendNotifyMessage calls the window procedure for the window and does not return until the window procedure has processed the message. If the window was created by a different thread, SendNotifyMessage passes the message to the window procedure and returns immediately; it does not wait for the window procedure to finish processing the message.

As a message, place WM_ACTIVATE or WM_APPACTIVATE.
Also you can try with SetActiveWindow API.
Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

LVL 17

Expert Comment

ID: 10760173
>> As I read, when you try to use ShowWindow/SetForegroundWindow API's, your app hangs with 100% CPU usage ?

It's probably just an issue with trying to SetForegroundWindow/ShowWindow->Maximized a child window who's parent is minimized. Seems like a logical issue also. :P

Author Comment

ID: 10768410
Hello zzzzzooc, I need to reuse this code in a number of VB/VBA application at my site where sometime the process will be in a shell script or executable.  Is there any way to gather the window handle from a Proccess Id.  That would be esier because I can get the process Id from WMI.
LVL 17

Accepted Solution

zzzzzooc earned 500 total points
ID: 10769029
Feeling lazy and this question seems to be asked a lot so I searched for a prior answer.. the below should do the trick:

It'll basically just loop through all of the window handles, get their Process ID via GetWindowThreadProcessId and compare it to the shelled processes' Process ID. When it finds a match, currwnd is the window you're after.It's not masterfully done but the example provides the basics.

Featured Post

MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question