8

I have a clock application. I have set the Window's TopMost property. But, randomly, some other window or visual studio comes above clock.

Is there any other way to make my window (clock app) to display always on top of all other applications.

Prince Ashitaka
  • 8,623
  • 12
  • 48
  • 71

4 Answers4

23

I know that this question is old, but I don't quite understand why the accepted answer has received up votes... or why it was accepted... it doesn't really answer the question, or provide a solution and answers posted these days that are that short are almost always down voted and/or deleted by the community. Ah well, I guess it was posted in different times.

Either way, as old as it is, I have a possible solution for anyone who may come across this post in the future. You can simply handle the Window.Deactivated Event and/or the Application.Deactivated Event. The Window.Deactivated Event occurs when a window becomes a background window and the Application.Deactivated Event occurs when an application stops being the foreground application.

The idea is to set the relevant TopMost property to true each time your application or Window loses focus:

private void Window_Deactivated(object sender, EventArgs e)
{
    // The Window was deactivated 
    this.TopMost = true;
}

It's worth noting that other developers can also use this technique, so this doesn't guarantee that your Window will always remain on top, but it works for me and the situation is still certainly improved by using it.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • 5
    This doesn't work for me. To make it work, the key is to set `Topmost = false` first and then again set `Tompost = true` – Riz Oct 04 '19 at 12:58
4

This should do the trick in most cases

private void Window_Deactivated(object sender, EventArgs e)
{
    // The Window was deactivated 
    Topmost = false; // set topmost false first
    Topmost = true; // then set topmost true again.
}
Riz
  • 6,746
  • 16
  • 67
  • 89
  • The legacy code I have to support does the opposite: sets it to true, then immediately sets it to false. Wonder why? – Sabuncu Nov 25 '21 at 13:49
3

I also had this problem when setting Window.Topmost = true on already existing window sometimes worked, sometimes not. Below is my workaround, you can probably combine it with Window_Deactivated approach mentioned by other people, if WS_EX_TOPMOST style is lost at runtime.

App.Current.MainWindow.Topmost = true;

// Get this window's handle
IntPtr hwnd = new WindowInteropHelper(App.Current.MainWindow).Handle;

// Intentionally do not await the result
App.Current.Dispatcher.BeginInvoke(new Action(async () => await RetrySetTopMost(hwnd)));

Extra code:

private const int RetrySetTopMostDelay = 200;
private const int RetrySetTopMostMax = 20;

// The code below will retry several times before giving up. This always worked with one retry in my tests.
private static async Task RetrySetTopMost(IntPtr hwnd)
{
    for (int i = 0; i < RetrySetTopMostMax; i++)
    { 
        await Task.Delay(RetrySetTopMostDelay);
        int winStyle = GetWindowLong(hwnd, GWL_EXSTYLE);

        if ((winStyle & WS_EX_TOPMOST) != 0)
        {
            break;
        }

        App.Current.MainWindow.Topmost = false;
        App.Current.MainWindow.Topmost = true;
    }
}

internal const int GWL_EXSTYLE = -20;
internal const int WS_EX_TOPMOST = 0x00000008;

[DllImport("user32.dll")]
internal static extern int GetWindowLong(IntPtr hwnd, int index);
  • Useful little snippet of code, it's a frustrating bug. – Joe Apr 27 '18 at 13:03
  • worked for me. problem is, when i now click on my window that is now on top of the full screen program. the fullscreen program is minimized. i think the whole thing is a hen-egg-problem. the full screen program wants to be in the foreground but we try to force some window on top of it. – Welcor Jun 28 '21 at 13:02
-2

Are you sure it's a random window? If another window is also a topmost window, it is possible for it to come above your window.

casablanca
  • 69,683
  • 7
  • 133
  • 150
  • Yeah. What I'm seeking is, what ever the other window state may be, my clock app should be in the TopMost. Like the "SlinkRun" application. – Prince Ashitaka Sep 16 '10 at 18:09
  • 11
    There is no SuperDuperTopMost option. It would obviously be used by *everybody*, defeating the reason for having it. – Hans Passant Sep 16 '10 at 18:31
  • 2
    @Hans thanks. But, possibly how some apps like SlickRun and other desktop clocks are displaying themselves in topmost of all possible windows? Is there anything other then "Window" could provide me that effect? – Prince Ashitaka Sep 16 '10 at 18:45