The information in this article applies to:
- Standard and Professional Editions of Microsoft Visual Basic for
Windows, versions 2.0 and 3.0
SUMMARY
There can be many TopMost windows in the Z-Order. TopMost windows are those
that have their WS_EX_TOPMOST Windows style set. This article describes how
to find the handle of the Window that occupies the top-most position above
all other windows -- that is, the top-most TopMost window. This is the
window that has the highest Z-Order in Windows internal Window Manager
List.
MORE INFORMATION
Given the window handle of the startup form or any other non-child form,
you can use the GetWindow API function to find the very first window
(highest Z-Order) in the Window Manager List. This window need not
neccessarily be the top-most visible window on the screen. However, if the
SetActiveWindow API function is called immediately after, the next visible
Top-most window (the one that is actually visible as the topmost Window on
the screen) will be Activated. Then you can use the GetActiveWindow API
function to get the window handle of the top-most visible Window on the
screen.
Step-by-Step Example
- Start a new project in Visual Basic. Form1 is created by default.
- Create a new form (Form2), and add it to the project.
- Create a new Code Module and add the following statements:
'Enter each Declare statement as one, single line:
Declare Function GetActiveWindow Lib "User" () As Integer
Declare Function GetWindow Lib "User"
(ByVal hWnd As Integer, ByVal wCmd As Integer) As Integer
Declare Function SetActiveWindow Lib "User"
(ByVal hWnd As Integer) As Integer
Global Const GW_HWNDFIRST = 0
Global Const GW_HWNDNEXT = 2
- Place a Command Button (Command1) on Form1, and add the following
code to its Click event:
Sub Command1_Click ()
Dim TopMosthWnd%, OldActivehWnd%, NewActivehWnd%
TopMosthWnd% = GetWindow(Me.hWnd, GW_HWNDFIRST)
OldActivehWnd% = SetActiveWindow(TopMosthWnd%)
NewActivehWnd% = GetActiveWindow()
' The following code is required only if there is more than one
' non-child form in the project. In this case you will have to
' start from the next topmost window, if focus shifts to the
' other non-child forms, just before this code on the original
' form is executed.
While NewActivehWnd% = 0
TopMosthWnd% = GetWindow(TopMosthWnd%, GW_HWNDNEXT)
OldActivehWnd% = SetActiveWindow(TopMosthWnd%)
NewActivehWnd% = GetActiveWindow()
Wend
End Sub
- Add the following code to the Form_Load() Event of Form1:
' This is Optional. It is used to show the effect of another
' non-child form:
Sub Form_Load ()
form2.Show
End Sub
- For testing purposes, before running the program, open any help
window and choose the "always on top" option from the Help menu. In
addition, you could do the same for the windows clock program by
choosing the "always on top" option from the control menu.
- Press F5 to run the program. Click the command button. The focus will
shift to the window currently positioned above all other windows.
NOTE: The code listed in this article will work even if it is executed from
an MDI Parent associated event. To achieve the same results if executed
from an event associated with a child (MDI or non-MDI) window, you will
need to replace the following line of code at the beginning of the Sub
procedure:
TopMosthWnd% = GetWindow(Me.hWnd, GW_HWNDFIRST)
with these two lines of code:
TopMosthWnd% = GetWindow(Me.hWnd, GW_OWNER)
TopMosthWnd% = GetWindow(TopMosthWnd%, GW_HWNDFIRST)
and include the following line in the code module:
Global Const GW_OWNER = 4