C# - Window always on top problem

David Menard picture David Menard · Jun 24, 2011 · Viewed 7.5k times · Source

So i'm making an overlay, and I need it to be always on top. To do so, i just set

chackBox1.checked = true;

private void checkChanged(object sender, EventArgs e)
{
        this.TopMost = checkBox1.Checked;
}  

as it is suggested in many places. The problem here is 1) I need a checkbox button... but thats not rly an issue, I can set to to Visible = false. 2) It never works untill I manually check the box with my mouse! Even if I set it to checked, set form1.isTopMost = true (after initComponents) and call the checkChanged event, I always have to manually check the box before it always stays on top!

please help! How do I make it so that the overlay loads up always on top?

My next step is making a thread that will force the form to stay on top, but I would like to avoid this LOL

Thanks,

Dave

Answer

Abhishek picture Abhishek · Sep 12, 2012

Setting Topmost = true on getfocus and lostfocus works apparantly till you have a message box popping up from some EXE you are running, clicking on the top bar of the popup message box would take your window to background.

Try this, a VERY robust way of achieving this:

namespace WindowsFormsApplication52
{
    public partial class Form1 : Form
    {
        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);
        const UInt32 SWP_NOSIZE = 0x0001;
        const UInt32 SWP_NOMOVE = 0x0002;
        const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
        }
    }
}