2011-09-14 27 views
1

ユーザーがデスクトップボタンをクリックしたときにWPFウィンドウが最小化されないようにするにはどうすればよいですか?ウィンドウが最小化するのを防ぐ方法は?

+2

なぜあなたは自分のデスクトップを見ているユーザーを知りたくないのですか? – BoltClock

+0

私はデスクトップのカレンダーを開発していますので、ウィンドウの背景に似ています –

+1

[デスクトップ上のウィンドウ](http://stackoverflow.com/questions/365094/window-on-desktop) –

答えて

2

このリンクはあなたを助ける:Get the minimize box click of a WPF window

あなたがイベントをキャッチし、それを自分で処理する必要があります。

編集:状態が変更されると、このメソッドは警告を表示しますので、「最適な」解決策ではない可能性がありますが、機能する可能性があります。

+0

これはうまくいかないでしょう、私は前に試しました –

+0

あなたはすでにあなたが試したものを見せてくれますか? – Drahakar

+0

私はタイマーを使って状態を取得しようとしましたが動作しますが、それは良い考えではないと思います。 –

-2

あなたのウィンドウの親をShow Desktopの影響を受けないように変更することができます。 (ここで述べたように: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から 'Show Desktop'を使用すると、フォーカスを当てていないアプリケーションがウィンドウを表示させようとしたときにオーバーライドされます。これは設計によるものです。 – BillW

0

のWindowsは最小化されていません。代わりに、 "WorkerW"と "Desktop"ウィンドウが前面に表示されます。

私は自分のソリューションを開発しました。 私は答えを見つけようと数週間インターネットを磨きました。私はこれを誇りに思います。

私たちは、EVENT_SYSTEM_FOREGROUNDウィンドウイベントのフックを作成するためにpinvokeを使用します。 このイベントは、フォアグラウンドウィンドウが変更されるたびにトリガされます。

私が気づいたのは、「Show Desktop」コマンドが発行され、WorkerWウィンドウクラスがフォアグラウンドになったときです。

このWorkerWウィンドウはデスクトップではなく、このWorkerWウィンドウのhwndがデスクトップhwndではないことを確認しました。

私たちは、WorkerWウィンドウがフォアグラウンドになるたびに、「WPFガジェットウィンドウ」を一番上に設定します。

WorkerW以外のウィンドウがフォアグラウンドになるたびに、「WPFガジェットウィンドウ」から最上位を削除します。

これをさらに進めたい場合は、新しいフォアグラウンドウィンドウがデスクトップウィンドウである「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; } 
    } 
} 
関連する問題