Introduction
This is a useful function to estimate whether a form is on the top of all visible windows in Z-order.
The Windows platform uses Z-order to layout visible windows, hence a visible window form may be drawn on the top of Desktop or be covered by other windows. Sometimes, when you use a notify icon to make your GUI friendlier, you may face a question: when you click the icon, what kind of action should the application perform? Minimize window? Bring it to front? The program logic should be like this:
We can easily estimate whether a form is minimized by accessing the windowstate
property, but unfortunately, there is no function or property to find out whether a form is on the top of other windows.
My solution is to enumerate the handles from the top window until my application, and use each handle to get two kinds of information: first, is the window visible? If yes, then second, is this window's caption length greater than 0? (This step is very important to prevent confusing BalloonTips and ContextMenuStrips.)
If both conditions are true, the result of the enumeration will increase by 1. When the enumeration is over, we can have our application's Z-order number.
Using the code
The function named IsOnTop
accepts an integer window handle, and returns a boolean value to indicate whether the handle window is on the top.
Private Function IsOnTop(ByVal hwnd As Integer) As Boolean
Dim i As Integer = GetTopWindow(0)
Dim x As Integer = 1
Dim s As String
Do
i = GetNextWindow(i, 2)
If i = hwnd Then
Exit Do
Else
If i = 0 Then
Return False
End If
End If
If IsWindowVisible(i) = True Then
s = Space(256)
If GetWindowText(i, s, 255) <> 0 Then
x += 1
End If
End If
Loop
If x = 1 Then
Return True
Else
Return False
End If
End Function
In this function, we use four Win32 API functions: GetTopWindow()
, GetNextWindow()
, IsWindowVisible()
, and GetWindowText()
. Below is the declaration:
Private Declare Function GetTopWindow Lib "user32" Alias "GetTopWindow" _
(ByVal hwnd As Integer) As Integer
Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" _
(ByVal hwnd As Integer, ByVal wFlag As Integer) As Integer
Private Declare Function IsWindowVisible Lib "user32" Alias "IsWindowVisible" _
(ByVal hwnd As Integer) As Boolean
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Integer, ByVal lpString As String, _
ByVal cch As Integer) As Integer
You can refer to the MSDN to check for the details of these API functions:
Points of interest
By using this function, we can easily create an intelligent notify icon. If the main form is minimized, clicking on the icon will restore the window. If the main form is active, clicking on the icon will minimize the window, and if the main form is not minimized and is inactive, the notify icon will bring it to front.
I have done a demo project. When you run the demo, an icon will appear on the Windows taskbar; right clicking the icon will pop out a menu strip to display what action you can do.
Sorry for my poor English. I have once obtained a lot of help from people in this website and I wanted to contribute. This function was done by me in a recent project; I hope it helps some of you.
History
- 09 July 2007 - The first release.