Solved

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

Posted on 2004-04-04
6
1,123 Views
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?
0
Comment
Question by:Alford-Miller
  • 4
6 Comments
 
LVL 17

Expert Comment

by:zzzzzooc
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"?
0
 
LVL 17

Expert Comment

by:zzzzzooc
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.


Form1:
=========

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)
        DoEvents
    Loop
End Sub
Private Sub Pause(ByVal iSecs As Integer)
    Dim lTimer As Long
    lTimer = Timer + iSecs
    Do Until Timer > lTimer
        DoEvents
    Loop
End Sub

0
 
LVL 6

Expert Comment

by:___XXX_X_XXX___
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 (msdn.microsoft.com):
SendNotifyMessage

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.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 17

Expert Comment

by:zzzzzooc
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
0
 

Author Comment

by:Alford-Miller
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.
0
 
LVL 17

Accepted Solution

by:
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:

http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_10798841.html

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.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
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…

708 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now