2013-05-30 43 views
3

這一個讓我感到困惑,我開始相信這是一個核心winapi,或可能在WPF中的錯誤。如果沒有人知道這個問題的可能原因,我會在Microsoft Connect上提交錯誤報告。錯誤的窗口顯示在任務欄上時,調用`顯示()`

問題出現本身,一旦我呼叫Window.Show(),但根本原因可能在於不同的地方,包括之前調用user32.dll。一旦我在窗口上調用Show(),我的窗口顯示出來,但另一個窗口在任務欄上彈出,但不可見。而且,點擊它不會使該窗口可見。

我試圖展示的窗口具有以下屬性集,這似乎是造成這種奇怪行爲所必需的。改變他們中的任何一個'修復'這個問題。

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

我正在創建一個虛擬桌面管理器(VDM),因此我通過user32.dll隱藏/顯示窗口。如果我在顯示我想要的窗口之前沒有隱藏任何窗口,問題也不會出現。 VDM的全部代碼is available on github。特定的user32調用發生在包裝which can also be found on github中。

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

RepositionWindows方法是有點長,張貼在這裏,但你可以看到它in its entirety on github。它使用BeginDeferWindowPos,DeferWindowPosEndDeferWindowPos

最後,當我使用Visibility屬性顯示/隱藏我的窗口而不是使用Show()Hide()時,所描述的行爲在某些情況下(稍後更多)不會發生。然而,according to the documentation on msdn

調用顯示達到相同的最終結果設置能見度Window對象 屬性可見。然而,從時間角度來看,這兩者之間存在差異。調用顯示的是,只有子窗口已經上調 Loaded事件後返回

這似乎是有很大關係的操作執行同步或異步 同步操作[...]。在某些情況下,我使用user32的ShowWindow來隱藏一個特定窗口。如果在顯示我的窗口(使用快捷鍵)後立即再次出現問題,無論是使用Visibility還是Show()來顯示窗口。但是,如果我使用ShowWindowAsync()來隱藏窗口,一切都會好起來的。當我在顯示窗口之前點擊任何窗口(選擇它)時,問題也不會發生。最後...(很多if ...的...我知道,對不起)在顯示我的窗口之前單擊任何窗口(選擇它)時,問題也不會發生。如果我不會使用快捷鍵來顯示窗口,我將永遠不會發現這個。

什麼可能是這個問題的根源?

+0

你寫:「*這其中有我百思不得其解,我開始相信這是無論是在覈心WINAPI,或可能在WPF中的錯誤*」評論沒有進一步閱讀:這是*非常*您不太可能在覈心WINAPI中發現了一個真正的bug,其代碼路徑與窗口可見性一樣常見......並且*極其不可能我的意思是基本上不可能。 –

+0

@NikBougalis ...這就是爲什麼我在這裏發佈它。 ,p –

回答

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); 
    } 
} 
相關問題