Use the System.Windows.Forms.Form.TopMost property.
Alternately, if you want to do this the long way using P/Invoke, keep reading.
[DllImport("user32.dll")]
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.