我使用小窗口作为工具提示,在我的应用程序中显示“正在播放”信息。当然我在窗口声明中设置Topmost = "True"
,当新歌开始播放时,我会tooltip.Show()
。问题是,当我将全屏应用程序置于焦点(例如游戏)时,.Show()
调用使全屏窗口变为非全屏,窗口化,带边框和顶栏(就像我按Alt + Enter)并且它看起来喜欢它也失去了焦点。因此,要恢复全屏我需要在窗口中单击以将其聚焦并手动按Alt-Enter。
ShowActivated
已设置为"False"
。
所以,我看到了三个解决方案:
1)以某种方式使Topmost
选项不会导致专注于.Show()
2)使用一些解决方法使工具提示窗口“永远在顶部”而不使用Topmost
选项(我不需要在全屏应用程序上弹出工具提示,因为它可以(并且可能会)通过D3D绘制或的OpenGL)
3)检测系统现在是否具有全屏窗口,并且不要尝试显示工具提示。
我不知道如何用这些选项修复行为,或者有更优雅的东西?
答案 0 :(得分:1)
所以...如果有人有兴趣,这是我的“研究”。
解决方案1)失败。我发现了一些关于这种行为的讨论,有些人说这是一个错误,而其他人则是一个功能,但是他们中的任何一个都认为它无法在托管代码中解决。我也尝试过 Sheridan 的答案而没有运气。
解决方案2)失败。我对P / Invoke有一些经验,但如果出现问题我通常会失败。在这个特殊情况下,我尝试使用
this.Handle = new WindowInteropHelper(this).Handle;
SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
正如它在网上建议的那样。此代码不显示窗口。所以我试着用来展示它
ShowWindow(this.Handle, 4); // I also tried SHOW_NORMAL and few other flags
但窗口仍然不可见
如果我this.Visibility = /*visible*/
或this.Show()
,我就会看到它,我真的看到窗口是最顶层的,但它并没有解决问题和全屏逃逸。如果有人知道.Show()
如何在内部工作以及如何用P / Invoke显示WPF窗口,请告诉我。
解决方案3)成功。我发现了一些谷歌搜索工作代码here并略微缩短了它:
internal class FullscreenCheck
{
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetShellWindow();
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowRect(IntPtr hwnd, out RECT rc);
// I hope this handles never changes
private static IntPtr hndlDesktop = GetDesktopWindow();
private static IntPtr hndlShell = GetShellWindow();
public static bool IsFullscreen()
{
var hndlForeground = GetForegroundWindow();
if (hndlForeground == null || hndlForeground == IntPtr.Zero || hndlForeground == hndlDesktop || hndlForeground == hndlShell)
{
return false;
}
RECT appBounds;
GetWindowRect(hndlForeground, out appBounds);
var screenBounds = System.Windows.Forms.Screen.FromHandle(hndlForeground).Bounds;
return ((appBounds.Bottom - appBounds.Top) == screenBounds.Height && (appBounds.Right - appBounds.Left) == screenBounds.Width);
}
因此,如果.Show()
IsFullscreen() == true
答案 1 :(得分:0)
我对此并不完全确定,但尝试这个怎么样?:
tooltip.Owner = referenceToParentWindow;
如果您从MainWindow.xaml.cs
启动此功能,那么您将使用此功能:
tooltip.Owner = this;
如果你从MainWindow.xaml.cs
文件外面启动它,那么你可以(也许)使用它:
tooltip.Owner = Application.Current.MainWindow;