简体   繁体   English

如何在不重叠全屏窗口的情况下显示最顶层窗口

[英]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. 我不知道对这个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. 因此,如果我必须实现这一点,我会发现我的操作系统中的Foreground窗口是全屏运行,然后不要将我的窗口作为全屏启动。

To get the current Foreground window in the OS we will need to import some User32 functions 要在OS中获取当前的Foreground窗口,我们需要导入一些User32函数

[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 . 现在我们需要添加对System.Windows.FormsSystem.Drawing引用来获取当前的Screen Below function returns if ForegroundWindow is running in FullScreen mode. 如果ForegroundWindow以全屏模式运行,则函数返回以下函数。

    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 如果线程注意到前景窗口发生了变化(并且当前窗口不是全屏),则设置通过Dispatcher运行一个方法,该方法将设置Topmost = true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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