Edit: 23 March 2011. In Version 12 it is possible to make a dialog stay on top simply by setting the dialog’s FormStyle property to fsStayOnTop. The method outlined in this post is not necessary for v12 dialogs but will remain as it can be used for older versions and the same approach can be used for windows belonging to other processes.
A question that comes up every now and then is how to make a custom dialog stay “on top” of other windows even when it loses the focus. There is a way to do this by calling the Windows API function SetWindowPos. There are examples in the forums but for convenience here’s a version of one:
SRT>StayOnTop Let>HWND_TOPMOST=-1 Let>HWND_NOTOPMOST=-2 Let>SWP_NOSIZE=1 Let>SWP_NOMOVE=2 Let>SWP_NOACTIVATE=16 Let>SWP_SHOWWINDOW=64 Let>WindowHandle=%StayOnTop_var_1% Let>Flags={%SWP_NOACTIVATE% Or %SWP_SHOWWINDOW% Or %SWP_NOMOVE% Or %SWP_NOSIZE%} LibFunc>User32,SetWindowPos,swpr,%WindowHandle%,HWND_TOPMOST,0,0,0,0,Flags END>StayOnTop
This subroutine takes a window handle and modifies the properties of that window to make it stay above other windows.
For example, if we had just opened Notepad and wanted to force it to stay on top we could do:
GetWindowHandle>Untitled - Notepad,hwndNotepad GoSub>StayOnTop,hwndNotepad
Or to get the handle of the active window use GetActiveWindow with WIN_USEHANDLE set to 1.
To set one of your own custom dialogs to stay on top use:
GoSub>StayOnTop,DialogName.Handle
Don’t forget that we are at the mercy of Windows here (and possibly the developers of the app we’re trying to force to the top). It’s a bit rude to have a window floating around on top of other windows. And consider what would happen if another window is opened which is also set to stay on top in the same way? You can’t have two windows on top. So multiple “stay on top” windows will still overlap each other depending on which one has the focus. In short you can’t really guarantee that a window will always be on top.