Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I have a C# winforms app that runs a macro in another program. The other program will continually pop up windows and generally make things look, for lack of a better word, crazy. I want to implement a cancel button that will stop the process from running, but I cannot seem to get the window to stay on top. How do I do this in C#?
Edit: I have tried
TopMost = true;
, but the other program keeps popping up its own windows over top. Is there a way to send my window to the top every n milliseconds?
Edit: The way I solved this was by adding a system tray icon that will cancel the process by double-clicking on it. The system tray icon does no get covered up. Thank you to all who responded. I read the article on why there is not a 'super-on-top' window... it logically does not work.
–
–
–
–
–
–
I was searching to make my WinForms application "Always on Top" but setting "TopMost" did not do anything for me. I knew it was possible because WinAmp does this (along with a host of other applications).
What I did was make a call to "user32.dll." I had no qualms about doing so and it works great. It's an option, anyway.
First, import the following namespace:
using System.Runtime.InteropServices;
Add a few variables to your class declaration:
private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
private const UInt32 SWP_NOSIZE = 0x0001;
private const UInt32 SWP_NOMOVE = 0x0002;
private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
Add prototype for user32.dll function:
[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);
Then in your code (I added the call in Form_Load()), add the call:
SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
[Reference][1]
[1]: http://www.c-sharpcorner.com/uploadfile/kirtan007/make-form-stay-always-on-top-of-every-window/
–
–
–
–
If by "going crazy" you mean that each window keeps stealing focus from the other, TopMost will not solve the problem.
Instead, try:
CalledForm.Owner = CallerForm;
CalledForm.Show();
This will show the 'child' form without it stealing focus. The child form will also stay on top of its parent even if the parent is activated or focused. This code only works easily if you've created an instance of the child form from within the owner form. Otherwise, you might have to set the owner using the API.
–
–
–
I had a momentary 5 minute lapse and I forgot to specify the form in full like this:
myformName.ActiveForm.TopMost = true;
But what I really wanted was THIS!
this.TopMost = true;
–
–
–
The following code makes the window always stay on top as well as make it frameless.
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace StayOnTop
public partial class Form1 : Form
private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
private const UInt32 SWP_NOSIZE = 0x0001;
private const UInt32 SWP_NOMOVE = 0x0002;
private 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();
FormBorderStyle = FormBorderStyle.None;
TopMost = true;
private void Form1_Load(object sender, EventArgs e)
SetWindowPos(this.Handle, HWND_TOPMOST, 100, 100, 300, 300, TOPMOST_FLAGS);
protected override void WndProc(ref Message m)
const int RESIZE_HANDLE_SIZE = 10;
switch (m.Msg)
case 0x0084/*NCHITTEST*/ :
base.WndProc(ref m);
if ((int)m.Result == 0x01/*HTCLIENT*/)
Point screenPoint = new Point(m.LParam.ToInt32());
Point clientPoint = this.PointToClient(screenPoint);
if (clientPoint.Y <= RESIZE_HANDLE_SIZE)
if (clientPoint.X <= RESIZE_HANDLE_SIZE)
m.Result = (IntPtr)13/*HTTOPLEFT*/ ;
else if (clientPoint.X < (Size.Width - RESIZE_HANDLE_SIZE))
m.Result = (IntPtr)12/*HTTOP*/ ;
m.Result = (IntPtr)14/*HTTOPRIGHT*/ ;
else if (clientPoint.Y <= (Size.Height - RESIZE_HANDLE_SIZE))
if (clientPoint.X <= RESIZE_HANDLE_SIZE)
m.Result = (IntPtr)10/*HTLEFT*/ ;
else if (clientPoint.X < (Size.Width - RESIZE_HANDLE_SIZE))
m.Result = (IntPtr)2/*HTCAPTION*/ ;
m.Result = (IntPtr)11/*HTRIGHT*/ ;
if (clientPoint.X <= RESIZE_HANDLE_SIZE)
m.Result = (IntPtr)16/*HTBOTTOMLEFT*/ ;
else if (clientPoint.X < (Size.Width - RESIZE_HANDLE_SIZE))
m.Result = (IntPtr)15/*HTBOTTOM*/ ;
m.Result = (IntPtr)17/*HTBOTTOMRIGHT*/ ;
return;
base.WndProc(ref m);
protected override CreateParams CreateParams
CreateParams cp = base.CreateParams;
cp.Style |= 0x20000; // <--- use 0x20000
return cp;
–
What is the other application you are trying to suppress the visibility of? Have you investigated other ways of achieving your desired effect? Please do so before subjecting your users to such rogue behaviour as you are describing: what you are trying to do sound rather like what certain naughty sites do with browser windows...
At least try to adhere to the rule of Least Surprise. Users expect to be able to determine the z-order of most applications themselves. You don't know what is most important to them, so if you change anything, you should focus on pushing the other application behind everything rather than promoting your own.
This is of course trickier, since Windows doesn't have a particularly sophisticated window manager. Two approaches suggest themselves:
enumerating top-level windows
and checking which process they
belong to, dropping their
z-order if so. (I'm not sure if
there are framework methods for
these WinAPI functions.)
Fiddling with child process permissions to prevent it from accessing the desktop... but I wouldn't try this until the othe approach failed, as the child process might end up in a zombie state while requiring user interaction.
–
–
In the code behind for Window_Deactivated:
private void Window_Deactivated(object sender, EventArgs e)
Window window = (Window)sender;
window.Activate();
This will keep your window on top.
Based on clamum's answer, and Kevin Vuilleumier's comment about the other flag responsible for the behavior, I made this toggle that switches between on-top and not on-top with a button press.
private void button1_Click(object sender, EventArgs e)
if (on)
button1.Text = "yes on top";
IntPtr HwndTopmost = new IntPtr(-1);
SetWindowPos(this.Handle, HwndTopmost, 0, 0, 0, 0, TopmostFlags);
on = false;
button1.Text = "not on top";
IntPtr HwndTopmost = new IntPtr(-2);
SetWindowPos(this.Handle, HwndTopmost, 0, 0, 0, 0, TopmostFlags);
on = true;
If you just want to Have Window Forms on top of a Game:(CSGOYour game needs to be in Fulscreen WINDOWED mode) or while you open different programs.
Just use TopMost = true;
In the:
private void Forms1_Load(object sender, EventArgs e)
TopMost = true;
In the Latest Version of .Net 6 Visual studio 2022
Just wanted to point this one if you are trying to do this for games :D
I did something i little bit differnt kinda found it much easier
so first on Form Load
private void Form1_Load(object sender, EventArgs e)
this.Shown += new EventHandler(Form1_Shown);//let your form show up here
private void Form1_Shown(Object sender, EventArgs e)
Form1.ActiveForm.TopMost = true //and then do your TopMost logic
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.