Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Making a form "always on top" / form persistance

Status
Not open for further replies.

stevemelaaron

Programmer
Sep 14, 2000
25
0
0
US
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]
 
I've found a better way of doing this in case anybody's interested. See Microsoft Knowledge Base Article - 184297.
 
>I think that I may have a solution to the &quot;always on top&quot; dilemma

Can you clarify which &quot;always on top&quot; dilemma you are solving?
 
I didn't check johnj15's, but I do have an example of a way that I found. I did not write this, but here it is:

-------------------------------------

Private Declare Function ShellExecute Lib &quot;shell32.dll&quot; Alias &quot;ShellExecuteA&quot; (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Declare Function SetWindowPos Lib &quot;user32&quot; (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

Private Const SWP_NOMOVE = &H2

Private Const SWP_NOSIZE = &H1

Private Const HWND_TOPMOST = -1



Private Sub Form_Resize()
SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
End Sub

-----------------------------------------------

The event is run on the form_resize. This seems to make more sense to me that running a constant timer as far as using memory is concerned.

Good Luck.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top