stevemelaaron
Programmer
I think that I may have a solution to the "always on top" dilemma. You must set up a "sentinel" that checks to see which form is currently on top, and if the desired form is not, then set it to be so. First, set up these three WinAPI functions and global constants (the constants are for the SetWindowPos function):
Declare Function GetTopWindow Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Global Const SWP_NOSIZE = &H1
Global Const SWP_NOMOVE = &H2
Global Const SWP_NOACTIVATE = &H10
Global Const SWP_NOOWNERZORDER = &H200
Global Const HWND_TOPMOST = -1
Global Const HWND_NOTOPMOST = -2
Global Const FLAGS = SWP_NOOWNERZORDER Or SWP_NOACTIVATE Or SWP_NOMOVE Or SWP_NOSIZE
Next, insert this code in the appropriate area of the program (probably in the Form_Activate event, though you could associate it with a command button click or a menu option):
' Set up variable to handle return value from SetWindowPos API call
Dim SetWindowPosReturn as Long
' Call SetWindowPos to set Form1 as topmost window on screen
SetWindowPosReturn =
SetWindowPos Form1.hwnd,HWND_TOPMOST,0,0,0,0,FLAGS)
Now, set up a timer with a reasonably short interval on your form, say 1000 msec or so, and plug this code into it's event procedure:
' Set up variables to handle return values from API calls
Dim GetDesktopWindowReturn as Long
Dim GetTopWindowReturn as Long
' Get handle to desktop
GetDesktopWindowReturn = GetDesktopWindow
' Get handle to topmost window on desktop
GetTopWindowReturn = GetTopWindow(GetDesktopWindowReturn)
' Check to see if the handle from the topmost window
' matches the handle of Form1 - if not, call
' SetWindowPos to put it back on top
If Form1.hwnd<>GetTopWindowReturn Then
SetWindowPosReturn = SetWindowPos
Form1.hwnd,HWND_TOPMOST,0,0,0,0,FLAGS)
End If
I've tested this a few different ways, and it works just fine, albeit at the expense of firing a timer event every second or so. [sig][/sig]
Declare Function GetTopWindow Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Global Const SWP_NOSIZE = &H1
Global Const SWP_NOMOVE = &H2
Global Const SWP_NOACTIVATE = &H10
Global Const SWP_NOOWNERZORDER = &H200
Global Const HWND_TOPMOST = -1
Global Const HWND_NOTOPMOST = -2
Global Const FLAGS = SWP_NOOWNERZORDER Or SWP_NOACTIVATE Or SWP_NOMOVE Or SWP_NOSIZE
Next, insert this code in the appropriate area of the program (probably in the Form_Activate event, though you could associate it with a command button click or a menu option):
' Set up variable to handle return value from SetWindowPos API call
Dim SetWindowPosReturn as Long
' Call SetWindowPos to set Form1 as topmost window on screen
SetWindowPosReturn =
SetWindowPos Form1.hwnd,HWND_TOPMOST,0,0,0,0,FLAGS)
Now, set up a timer with a reasonably short interval on your form, say 1000 msec or so, and plug this code into it's event procedure:
' Set up variables to handle return values from API calls
Dim GetDesktopWindowReturn as Long
Dim GetTopWindowReturn as Long
' Get handle to desktop
GetDesktopWindowReturn = GetDesktopWindow
' Get handle to topmost window on desktop
GetTopWindowReturn = GetTopWindow(GetDesktopWindowReturn)
' Check to see if the handle from the topmost window
' matches the handle of Form1 - if not, call
' SetWindowPos to put it back on top
If Form1.hwnd<>GetTopWindowReturn Then
SetWindowPosReturn = SetWindowPos
Form1.hwnd,HWND_TOPMOST,0,0,0,0,FLAGS)
End If
I've tested this a few different ways, and it works just fine, albeit at the expense of firing a timer event every second or so. [sig][/sig]