简体   繁体   中英

How to show a topmost window without overlapping fullscreen windows

I need to show a topmost window (a balloon from the system tray) without overlapping any fullscreen windows. For example, if my topmost window appears when a user watches a movie, the window mustn't appear on top of the movie screen. The window must appear only when a user closes his fullscreen window.

Now, I just show my window this way:

window.show()

In the style I turn on these properties:

<Setter Property="Topmost" Value="True" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="ShowActivated" Value="False" />

Could you please help to figure out how to show a topmost window without disturbing a user if he watches a movie or plays a game?

I dont know of any inbuilt support for this wpf. So if I have to implement this ,i would find if the Foreground window in my OS is running in full screen ,then don't launch my window as full screen.

To get the current Foreground window in the OS we will need to import some User32 functions

[DllImport("user32.dll")]
private static extern bool GetWindowRect(HandleRef hWnd, [In, Out] ref RECT rect);

[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();

[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

Now we will need to add reference to System.Windows.Forms and System.Drawing to get the current Screen . Below function returns if ForegroundWindow is running in FullScreen mode.

    public  bool IsAnyWindowFullScreen()
    {
        RECT rect = new RECT();
        GetWindowRect(new HandleRef(null, GetForegroundWindow()), ref rect);
        return new System.Drawing.Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top).Contains(Screen.PrimaryScreen.Bounds);
    }

So while launching my window i will just check

 if(!IsAnyWindowFullScreen())
  {
    window.Topmost = true;
  }
  window.Show();

Quite extraordinary problem, I've dealt with something similar before and I'm afraid you just can't do that as simple as you wish (Correct me if I'm wrong I'd love to know).

This is how I would have dealt with your problem:

  1. First create a thread that figures out if the current foreground window is running in fullscreen mode (again, there is no real way of knowing other than checking if the window size is bigger or equal to the screen). You can use this: How To Detect if Another Application is Running in Full Screen Mode .
  2. If the thread notices that the foreground window changes (and the current one is not in fullscreen) set run a method through Dispatcher that will set Topmost = true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM