|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic Helper Routines SetWindowPlacement: Restore and Activate a Window via its hWnd |
||
Posted: | Saturday July 17, 1999 | |
Updated: | Monday December 26, 2011 | |
Applies to: | VB4-32, VB5, VB6 | |
Developed with: | VB6, Windows NT4 | |
OS restrictions: | None | |
Author: | VBnet - Randy Birch | |
Related: |
EnumWindows: Enumerate (and Restore) a Window via Callback GetWindowThreadProcessId: Obtain the hWnd of an App Started with Shell() |
|
Prerequisites |
None. |
|
Scenario:
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. |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |