2011-09-14 70 views
1

當用戶點擊顯示桌面按鈕時,如何防止WPF窗口最小化?如何防止窗口最小化?

+2

爲什麼要阻止用戶看到他們的桌面? – BoltClock

+0

我正在開發一個桌面日曆,所以它就像窗口的背景 –

+1

可能重複的[Window「在桌面上」](http://stackoverflow.com/questions/365094/window-on-desktop) –

回答

2

此鏈接將幫助您:Get the minimize box click of a WPF window

你需要捕捉該事件並自己處理。

編輯:一旦狀態發生變化,此方法會提醒您,因此它可能不是「最佳」解決方案,但它可以工作。

+0

那不行,我以前試過 –

+0

你能告訴我們你已經試過了嗎? – Drahakar

+0

我嘗試使用計時器來獲得狀態,但它的工作原理,但它認爲這不是一個好主意。 –

-2

您可以將窗口的父級更改爲不受顯示桌面影響。 (如下所述:Window "on desktop"

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     Loaded += MainWindowLoaded; 
    } 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 
    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 
    [DllImport("user32.dll", SetLastError = true)] 
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 

    private void MainWindowLoaded(object sender, RoutedEventArgs e) 
    { 
     var hwnd = new WindowInteropHelper(this).Handle; 
     var ProgmanHwnd = FindWindowEx(FindWindowEx(FindWindow("Progman", "Program Manager"), IntPtr.Zero, "SHELLDLL_DefView",""), IntPtr.Zero,"SysListView32", "FolderView"); 
     SetParent(hwnd, ProgmanHwnd); 
    } 

} 
+0

不正確。使用TaskBar中的「顯示桌面」將覆蓋任何未聚焦的應用程序嘗試使窗口可見的情況。這是設計。 – BillW

0

的Windows發行時, 「顯示桌面」 沒有最小化。相反,「WorkerW」和「桌面」窗口被帶到了前臺。

我最終開發了自己的解決方案。 我在網上搜索了幾個星期,試圖找到答案,所以我爲這個問題感到自豪。

因此,我們所做的是使用pinvoke爲EVENT_SYSTEM_FOREGROUND窗口事件創建一個鉤子。 無論何時前景窗口改變,都會觸發此事件。

現在我注意到當發出「顯示桌面」命令時,WorkerW窗口類變爲前景。

注意這個WorkerW窗口不是桌面,我確認這個WorkerW窗口的hwnd不是桌面hwnd。

因此,我們所做的就是每當WorkerW窗口變爲前景時,我們將「WPF小工具窗口」設置爲最頂層!

每當其他WorkerW窗口以外的窗口變爲前景時,我們會從「WPF Gadget窗口」中刪除最頂層。

如果您想更進一步,您可以取消註釋部分,我檢查新的前景窗口是否也是「PROGMAN」,即桌面窗口。

但是,如果用戶在不同的顯示器上單擊桌面,這將導致您的窗口成爲最高層。在我的情況下,我不想要這種行爲,但我想你可能會有一些。

確認可以在Windows 10中使用。應該可以在Windows的舊版本中使用。

using System; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Windows; 

namespace YourNamespace 
{ 
    internal static class NativeMethods 
    { 
     [DllImport("user32.dll")] 
     internal static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, ShowDesktop.WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags); 

     [DllImport("user32.dll")] 
     internal static extern bool UnhookWinEvent(IntPtr hWinEventHook); 

     [DllImport("user32.dll")] 
     internal static extern int GetClassName(IntPtr hwnd, StringBuilder name, int count); 
    } 

    public static class ShowDesktop 
    { 
     private const uint WINEVENT_OUTOFCONTEXT = 0u; 
     private const uint EVENT_SYSTEM_FOREGROUND = 3u; 

     private const string WORKERW = "WorkerW"; 
     private const string PROGMAN = "Progman"; 

     public static void AddHook(Window window) 
     { 
      if (IsHooked) 
      { 
       return; 
      } 

      IsHooked = true; 

      _delegate = new WinEventDelegate(WinEventHook); 
      _hookIntPtr = NativeMethods.SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, _delegate, 0, 0, WINEVENT_OUTOFCONTEXT); 
      _window = window; 
     } 

     public static void RemoveHook() 
     { 
      if (!IsHooked) 
      { 
       return; 
      } 

      IsHooked = false; 

      NativeMethods.UnhookWinEvent(_hookIntPtr.Value); 

      _delegate = null; 
      _hookIntPtr = null; 
      _window = null; 
     } 

     private static string GetWindowClass(IntPtr hwnd) 
     { 
      StringBuilder _sb = new StringBuilder(32); 
      NativeMethods.GetClassName(hwnd, _sb, _sb.Capacity); 
      return _sb.ToString(); 
     } 

     internal delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime); 

     private static void WinEventHook(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) 
     { 
      if (eventType == EVENT_SYSTEM_FOREGROUND) 
      { 
       string _class = GetWindowClass(hwnd); 

       if (string.Equals(_class, WORKERW, StringComparison.Ordinal) /*|| string.Equals(_class, PROGMAN, StringComparison.Ordinal)*/) 
       { 
        _window.Topmost = true; 
       } 
       else 
       { 
        _window.Topmost = false; 
       } 
      } 
     } 

     public static bool IsHooked { get; private set; } = false; 

     private static IntPtr? _hookIntPtr { get; set; } 

     private static WinEventDelegate _delegate { get; set; } 

     private static Window _window { get; set; } 
    } 
}