Prerequisites |
None. |
|
Scenario:
- You have a multiple-exe application
- Each single exe provides unique functionality
- All apps are launched via a "control app" (ie a toolbar
app or a main application).
- All apps are standard exe's (not ActiveX exe's).

- No intercommunication methods (pipes, private messages) have been
implemented
- On closing an application started from the "control
app", you want to assure that the control app is restored on screen ready for user input.
This code page was prompted by a post on the DevX newsgroups, in
response to a terrible suggestion that the control app start a timer, poll FindWindow, and when the app in question is no longer found,
restore itself. This type of help frankly makes me cringe. The WinAPI provides many methods that could be used to perform this simple task
effectively without unnecessary timers or loops.. This code has worked flawlessly on Win95a/b, win98 and WinNT4.
In this example we're going to create two exe's. To assure that the
code is not obscured by fancy methods, and is simple to understand, I've used the simplest means of coding the apps - using Shell and
hard-coding the path to the exe's. Naturally you'll want to change this in anything you develop. |
|
Project
1: BAS Module Code - "Main" App |
|
Place the following code into the general declarations
area of a bas module: |
|
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
' applications, but you may not reproduce
' or publish this code on any web site,
' online service, or distribute as source
' on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Public Type POINTAPI
x As Long
y As Long
End Type
Public Type WINDOWPLACEMENT
Length As Long
flags As Long
showCmd As Long
ptMinPosition As POINTAPI
ptMaxPosition As POINTAPI
rcNormalPosition As RECT
End Type
Public Const SW_SHOWNORMAL = 1
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_SHOWNOACTIVATE = 4
Public Declare Function BringWindowToTop Lib "user32" _
(ByVal hwnd As Long) As Long
Public Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Public Declare Function GetWindowPlacement Lib "user32" _
(ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
Public Declare Function SetForegroundWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Public Declare Function SetWindowPlacement Lib "user32" _
(ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
Public Sub RestoreWindow(sWindowTitle As String)
Dim hWndCtlApp As Long
Dim currWinP As WINDOWPLACEMENT
'obtain the handle to the control app
hWndCtlApp = FindWindow(vbNullString, sWindowTitle)
If hWndCtlApp Then
'prepare the WINDOWPLACEMENT type
currWinP.Length = Len(currWinP)
If GetWindowPlacement(hWndCtlApp, currWinP) > 0 Then
'determine the window state
If currWinP.showCmd = SW_SHOWMINIMIZED Then
'minimized, so restore
currWinP.Length = Len(currWinP)
currWinP.flags = 0&
currWinP.showCmd = SW_SHOWNORMAL
Call SetWindowPlacement(hWndCtlApp, currWinP)
Else
'on screen, so assure visible
Call SetForegroundWindow(hWndCtlApp)
Call BringWindowToTop(hWndCtlApp)
End If
End If
End If
End Sub |
|
Project
1: Form Code - "Main" App |
|
For this demo, this form needs no controls. Add the
following code: |
|
Option Explicit
Private Sub Form_Load()
Me.Move (Screen.Width - Me.Width) \ 2, _
(Screen.Height - Me.Height) \ 2
End Sub
Private Sub Form_Unload(Cancel As Integer)
'last minute clean-up code here
'restore the control app
RestoreWindow "My Control App"
'we're done
End Sub
|
|
Project
2: BAS Module Code - Control App |
None. |
|
|
|
Project
2: Form Code - Control App |
|
To a form, add a command button and a checkbox. Set the
Form caption to something unique - this is what is used in the activate code. Add the following: |
|
Option Explicit
Private Sub Command1_Click()
Dim x As Long
'for simplicity, Shell with a hard
'coded path will be used
x = Shell("c:\apptest\appmain.exe", vbNormalFocus)
If x > 32 Then
If Check1.Value = 1 Then
Me.WindowState = vbMinimized
End If
End If
End Sub
Private Sub Form_Load()
Check1.Value = 1
End Sub |
|
Comments |
Compile both forms as separate exe's, and put them into
the path you specified in the Shell statement. Run the control app, and experiment. |
|