2013-06-25 130 views
5

我試圖保持一個特定的WPF窗口的焦點,這意味着它不應該在失去焦點時(例如標準的Windows任務欄)更改窗口樣式。爲了達到這個目的,我勾選了WndProc來檢查WM_NCACTIVATEWM_ACTIVATE是否設置爲false(wParam == 0),然後將該郵件標記爲handled = true;以阻止窗口不活動。下面是一些示例代碼:在啓動窗口中處理WM_NCACTIVATE阻止所有其他窗口

void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    var source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); 
    if (source != null) source.AddHook(WndProc); 
} 

private const uint WM_NCACTIVATE = 0x0086; 
private const int WM_ACTIVATE = 0x0006; 
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    if (msg == WM_NCACTIVATE) 
    { 
     if (wParam == new IntPtr(0)) 
      handled = true; 
    } 
    if (msg == WM_ACTIVATE) 
    { 

     if (wParam == new IntPtr(0)) 
      handled = true; 
    } 
    return IntPtr.Zero; 
} 

然而,這樣做,是從這個主窗口中創建的所有其他WPF窗口

var f = new Window(); 
f.ShowDialog(); 

從不接收焦點,儘管它們是可見的,窗口不對客戶區域中的用戶輸入沒有反應,但對於Windows最小化,最大化和關閉按鈕也是如此。我顯然做錯了,所以任何建議或指導如何以正確的方式做到這一點?

+0

代碼只是沒有做你希望它做什麼。它只是防止WPF看到消息。該窗口仍然被激活,但WPF不知道它。所以變得絕望困惑。防止窗口停用需要一個更大的武器,WPF沒有。 –

+0

是的,那是我的預期。那麼怎樣才能更好地解決這個問題呢? – dsfgsho

+0

方法*什麼*?任務欄沒有「樣式」,因此完全不清楚你想要解決什麼問題。 WPF不直接支持創建任務欄,您可以通過pinvoking SHAppBarMessage()創建一個任務欄。這谷歌很好。 –

回答

4

的解決方案,以保持WPF窗口的視覺風格爲主動,即使該窗口失去焦點是處理WM_NCACTIVATE這樣的:

private const uint WM_NCACTIVATE = 0x0086; 

private IntPtr WndProc(IntPtr hwnd, int msg, 
     IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    var returnvalue = IntPtr.Zero; 
    if (msg == WM_NCACTIVATE) 
    { 
     //replace the wParam (true/false) which indicates 
      //active/inactive with always true 
     returnvalue = DefWindowProc(hwnd, WM_NCACTIVATE, 
        new IntPtr(1), new IntPtr(-1)); 
     handled = true; 
    } 
} 


[DllImport("user32.dll")] 
static extern IntPtr DefWindowProc(IntPtr hWnd, WindowsMessages uMsg, IntPtr wParam, IntPtr lParam); 
相關問題