You should use the System.Windows.Forms.Form.TopMost property.
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As UInt32) As Boolean
End Function
Declare Auto Function SetWindowPos Lib "user32" (ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As UInteger) As Boolean
static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
static readonly IntPtr HWND_TOP = new IntPtr(0);
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
ReadOnly HWND_BOTTOM As New IntPtr(1)
ReadOnly HWND_NOTOPMOST As New IntPtr(-2)
ReadOnly HWND_TOP As New IntPtr(0)
ReadOnly HWND_TOPMOST As New IntPtr(-1)
Values for the uFlags parameter
// From winuser.h
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_NOZORDER = 0x0004;
const UInt32 SWP_NOREDRAW = 0x0008;
const UInt32 SWP_NOACTIVATE = 0x0010;
const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */
const UInt32 SWP_SHOWWINDOW = 0x0040;
const UInt32 SWP_HIDEWINDOW = 0x0080;
const UInt32 SWP_NOCOPYBITS = 0x0100;
const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don't do owner Z ordering */
const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don't send WM_WINDOWPOSCHANGING */
VB Conversion - If you want to paste into VB.
Shared ReadOnly SWP_NOSIZE As UInt32 = Convert.ToUInt32(&H1)
Shared ReadOnly SWP_NOMOVE As UInt32 = Convert.ToUInt32(&H2)
Shared ReadOnly SWP_NOZORDER As UInt32 = Convert.ToUInt32(&H4)
Shared ReadOnly SWP_NOREDRAW As UInt32 = Convert.ToUInt32(&H8)
Shared ReadOnly SWP_NOACTIVATE As UInt32 = Convert.ToUInt32(&H10)
Shared ReadOnly SWP_FRAMECHANGED As UInt32 = Convert.ToUInt32(&H20) '/* The frame changed: send WM_NCCALCSIZE */
Shared ReadOnly SWP_SHOWWINDOW As UInt32 = Convert.ToUInt32(&H40)
Shared ReadOnly SWP_HIDEWINDOW As UInt32 = Convert.ToUInt32(&H80)
Shared ReadOnly SWP_NOCOPYBITS As UInt32 = Convert.ToUInt32(&H100)
Shared ReadOnly SWP_NOOWNERZORDER As UInt32 = Convert.ToUInt32(&H200) '/* Don't do owner Z ordering */
Shared ReadOnly SWP_NOSENDCHANGING As UInt32 = Convert.ToUInt32(&H400) '/* Don't send WM_WINDOWPOSCHANGING */
HWND_TOP will bring a window to the front of the Z-Order only if the thread is in the foreground. Otherwise it will bring the window to the front of the thread's Z-order.
In .NET, to make a window stay on top you only need to call Me.TopMost = True
This is a little helper class which can be used with any Form object to make it topmost or not topmost.
static public class FormHelper
{
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
int Y, int cx, int cy, uint uFlags);
static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
static readonly IntPtr HWND_TOP = new IntPtr(0);
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_NOZORDER = 0x0004;
const UInt32 SWP_NOREDRAW = 0x0008;
const UInt32 SWP_NOACTIVATE = 0x0010;
const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */
const UInt32 SWP_SHOWWINDOW = 0x0040;
const UInt32 SWP_HIDEWINDOW = 0x0080;
const UInt32 SWP_NOCOPYBITS = 0x0100;
const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don't do owner Z ordering */
const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don't send WM_WINDOWPOSCHANGING */
const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
public static void MakeTopMost (Form form)
{
SetWindowPos(form.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
}
public static void MakeNormal (Form form)
{
SetWindowPos(form.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
}
}
Public Class FormHelper
<DllImport("user32.dll")> _
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, _
ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As UInt32) As Boolean
End Function
Private Shared ReadOnly HWND_NOTOPMOST As IntPtr = New IntPtr(-2)
Private Shared ReadOnly HWND_TOP As IntPtr = New IntPtr(0)
Private Shared ReadOnly HWND_TOPMOST As IntPtr = New IntPtr(-1)
Private Const SWP_NOSIZE As UInt32 = &H0001
Private Const SWP_NOMOVE As UInt32 = &H0002
Private Const SWP_NOZORDER As UInt32 = &H0004
Private Const SWP_NOREDRAW As UInt32 = &H0008
Private Const SWP_NOACTIVATE As UInt32 = &H0010
Private Const SWP_FRAMECHANGED As UInt32 = &H0020 ' The frame changed: send WM_NCCALCSIZE
Private Const SWP_SHOWWINDOW As UInt32 = &H0040
Private Const SWP_HIDEWINDOW As UInt32 = &H0080
Private Const SWP_NOCOPYBITS As UInt32 = &H0100
Private Const SWP_NOOWNERZORDER As UInt32 = &H00200 ' Don't do owner Z ordering
Private Const SWP_NOSENDCHANGING As UInt32 = &H0400 ' Don't send WM_WINDOWPOSCHANGING
Private Const TOPMOST_FLAGS As UInt32 = SWP_NOMOVE Or SWP_NOSIZE
Public Shared Sub MakeTopMost(ByVal form As Form)
FormHelper.SetWindowPos(form.Handle, HWND_TOPMOST, 0, 0, 0, 0, 3)
End Sub
Public Shared Sub MakeNormal(ByVal form As Form)
FormHelper.SetWindowPos(form.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, 3)
End Sub
End Class
Use the System.Windows.Forms.Form.TopMost property.