3

这让我感到困惑,我开始相信这是核心 winapi 或 WPF 中的错误。如果这里没有人知道问题的可能原因,我将在 Microsoft Connect 上提交错误报告。

一旦我调用,问题就会出现Window.Show(),但根本原因可能出在不同的地方,包括之前对 user32.dll 的调用。一旦我调用Show()我的窗口,我的窗口确实会显示出来,但另一个窗口会在任务栏上弹出但不可见。此外,单击它不会使该窗口可见。

我试图显示的窗口设置了以下属性,这似乎是导致这种奇怪行为所必需的。更改其中任何一个“修复”此问题。

WindowStyle="None"
WindowState="Maximized"
ShowInTaskbar="False"

我正在创建一个虚拟桌面管理器 (VDM),因此我通过 user32.dll 隐藏/显示窗口。如果我在显示我想要的窗口之前没有隐藏任何窗口,问题也不会出现。VDM 的完整代码可在 github 上找到。特定的 user32 调用发生在包装器中,该包装器也可以在 github 上找到

// Hide windows.
var hideWindows = _windows
    .Select( w => new RepositionWindowInfo( w.Info ) { Visible = false } );
WindowManager.RepositionWindows( hideWindows.ToList() );

RepositionWindows方法在这里发布有点长,但是您可以在 github 上看到它的全部内容。它使用BeginDeferWindowPos和。DeferWindowPosEndDeferWindowPos

Visibility最后,当我使用属性而不是使用来Show()显示/隐藏我的窗口Hide()时,在某些情况下也不会发生所描述的行为(稍后会详细介绍)。但是,根据 msdn 上的文档

调用 Show 实现与将 Window 对象的 Visibility 属性设置为 Visible 相同的最终结果。但是,从时间的角度来看,两者之间存在差异。调用 Show 是一个同步操作,仅在子窗口上的 Loaded 事件引发后才返回 [...]

这似乎与同步或异步执行的操作非常相关。在某些情况下,我使用 user32's 隐藏一个特定的窗口ShowWindow。如果在我显示我的窗口(使用快捷键)之后立即再次出现问题,无论我是使用Visibility还是Show()显示窗口。但是,如果我使用 隐藏窗口ShowWindowAsync(),一切都很好。

最后......(这么多如果......我知道,对不起)当我在显示我的窗口之前点击任何窗口(选择它)时,问题也不会发生。如果我不使用快捷键来显示窗口,我永远不会发现这一点。

这个问题的根本原因可能是什么?

4

1 回答 1

0

我想我已经确定了导致这种情况的核心问题。当窗口被隐藏时,另一个窗口被激活。但是,似乎只有任务栏上的窗口处于活动状态。当我隐藏所有窗口然后调用GetActiveWindow它表示没有窗口处于活动状态(返回值 null)。

当随后显示一个不应显示在任务栏上的窗口时(无论是否Show()使用Visibility),隐藏的窗口将显示在任务栏上。

解决此问题的解决方法是在延迟窗口定位操作后检查是否有任何窗口处于活动状态。如果没有,我现在将重点放在任务栏上。下次显示非任务栏窗口时,该错误不会出现!

succeeded = User32.EndDeferWindowPos( windowsPositionInfo );
if ( succeeded && User32.GetActiveWindow() == IntPtr.Zero )
{
    WindowInfo startBar = GetWindows()
        .Where( w => w.GetClassName() == "Shell_TrayWnd" ).FirstOrDefault();
    if ( startBar != null )
    {
        User32.SwitchToThisWindow( startBar.Handle, false );
    }
}
于 2013-06-05T14:40:10.283 回答