I agree with Jonas's answer but would modify it to use an event instead of a timer.
/// Get the topmost window handle
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
/// Trigger event when topmost window changed
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, TopmostWindowChangedDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
/// Set the topmost window
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
/// Show a window
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hwind, int cmd);
// Constant variables for topmost window changed event
private const uint WINEVENT_OUTOFCONTEXT = 0;
private const uint EVENT_SYSTEM_FOREGROUND = 3;
/// Keep track of the last topmost window with a name
private static IntPtr topWinHandle { get; set; }
/// Implementation of topmost window changed delegate
private TopmostWindowChangedDelegate TopmostWindowChanged { get; set; }
Then set up the handlers in one of your startup methods
// Set topmost window changed event handler
TopmostWindowChanged = new TopmostWindowChangedDelegate(WinEventProc);
// Set event hook for topmost window changed
IntPtr hook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, TopmostWindowChanged, 0, 0, WINEVENT_OUTOFCONTEXT);
And then move your window to topmost when the other topmost changes
/// Make sure this window stays on top
public void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
// Get current window name from handle
IntPtr handle = GetForegroundWindow();
if(handle != YOUR_WINDOW'S_HANDLE)
{
// Move your window back to the top
SetForegroundWindow(YOUR_WINDOW'S_HANDLE);
ShowWindow(YOUR_WINDOW'S_HANDLE, 5);
}
}