Shell an external app, return focus to VB app form when it closes

Posted on 2003-03-14
Medium Priority
Last Modified: 2010-04-07
 I'm writing a frontend program in VB5 for a Win98 system which won't use a mouse, only very basic keystrokes made by a special joystick (mainly : left [arrow], right, down, up, spacebar). My frontend EXE is used as the Win98 shell instead of EXPLORER.EXE, and the user is presented with a form populated with a grid of command buttons which correspond to certain programs (games). Users can navigate the grid of command buttons with the joystick (left, right, etc are mapped as keystrokes), and select the game they want to shell (via API call "ShellExecute") by hitting the joystick button mapped to send the spacebar key. Once the game has been played and exited, focus *should* return to the VB app's form so that the user can navigate through the command buttons and select another game.

  The problem I'm having is that some games don't return focus to the VB app once they exit. If I run my VB app with EXPLORER.EXE as the shell, I can see that the games in question leave a "blank" (no title or icon) entry in the Windows task bar. Clicking the "blank" entry will make it disappear.

  Can I use VB to return focus to itself once one of these "rogue" games exits? Even if the answer is a Windows one instead of VB, I'm just looking for an answer. [ not including adding extra input keys or a mouse to the system ;-) ]
Question by:asmcmrr
  • 2

Author Comment

ID: 8139187
By saying "EXPLORER.EXE as the shell", I mean that Windows is booting its default way with EXPLORER.EXE as the shell instead of my custom app, not that I'm shelling out to EXPLORER.EXE from the custom app. :)

Accepted Solution

Sweat earned 300 total points
ID: 8139219

When you shell to the new program, you must obtain it's handle.  Then the calling program would use the API to see if that handle was still active.  When it becomes inactive, focus would then return to your program.

You'll need some declarations:

Public Const STATUS_PENDING = &H103&

Then some API declarations:

Public Declare Function OpenProcess Lib "Kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long

Public Declare Function GetExitCodeProcess Lib "Kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long

And then you'll need some sub or function to do the actual calling and then waiting:

Sub eShell()
 Dim lInst As Long
 Dim lProcessId As Long
 Dim lExitCode As Long

 ' This does the actual calling to the new program...
 lInst = Shell("c:\app_to_run.exe", vbNormalFocus)

 ' Now. Once you've called the program, you have the program instance.  You need to get the id of the process you just called...
 lProcessId = OpenProcess(PROCESS_QUERY_INFORMATION, False, lInst)

 ' Then you'll sit inside this do/loop, checking to see if the process issues an exit code or in other words, ends.
    Call GetExitCodeProcess(lProcessId, lExitCode)
    ' Make sure you have this DoEvents to give timeslices back to the OS
 Loop While lExitCode = STATUS_PENDING

 ' Finally, when the exit code no longer matches the status_pending value, you fall through the loop and exit

End Sub

What this does is to keep your Explorer like program running, just not doing very much.  When the game ends, your program knows it and focus returns for the next selection.

Hope this helps,


Author Comment

ID: 8139774
I tried this and it works perfectly. I had to switch over to using VB's internal Shell instead of the ShellExecute API call though, it would be ideal if I could continue using ShellExecute, so that any registered file type could be executed without knowing the location of their parent EXE and I could specify a default directory. (e.g. this would be good for Visual PinMAME pinball tables)

That's the only reason it isn't an "A".

Thanks a lot,


Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…

569 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