2009-05-29 38 views
10

WPFアプリケーションを処理する前に、最小化する直前に処理する必要があります。 WindowオブジェクトStateChangedに見つかりましたが、Windowオブジェクトが既に最小化状態にあるときに起動しますが、それは遅すぎます。WPFのウィンドウStateChangingイベント

したがって、Windowオブジェクトは以前の状態のままですが、処理するには "StateChanging"イベントのようなものが必要です。

このようなイベントを作成することはできますか?

答えて

11

Spy ++の使用を最小限にする前に、ウィンドウの右側にウィンドウのメッセージが表示されました。最初に呼び出されるのはWM_WINDOWPOSCHANGINGです。 私はウィンドーを最小化するときにウィンドウが-32000、-32000の位置ポイントを移動していることを知らなかった。それらはWM_WINDOWPOSCHANGINGのパラメーターだった。しかし、私はVista上でのみテストされています。ここで使用http://blogs.msdn.com/oldnewthing/archive/2004/10/28/249044.aspx

コードは、NIRにより投稿されたhereここ

は、サンプルコードにある

XAML

<Window x:Class="WindowStateTest2.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"></RowDefinition> 

     <RowDefinition Height="*"></RowDefinition> 
    </Grid.RowDefinitions> 
     <Button Click="btnClear_Click" Grid.Row="0" x:Name="btnClear">Clear</Button>    

     <TextBox Name="txt" VerticalScrollBarVisibility="Visible" Grid.Row="2"></TextBox> 
</Grid> 
</Window> 

C#

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Windows.Interop; 
using System.Runtime.InteropServices; 

namespace WindowStateTest2 
{ 
/// <summary> 
/// Interaction logic for Window1.xaml 
/// </summary> 
public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 

     this.StateChanged += new EventHandler(Window1_StateChanged); 
     this.SourceInitialized += new EventHandler(Window1_SourceInitialized); 

    } 

    #region Event handlers 

    void btnClear_Click(object sender, RoutedEventArgs e) 
    { 
     this.txt.Text = string.Empty; 
    } 
    void Window1_SourceInitialized(object sender, EventArgs e) 
    { 
     AttachWndProc(); 
    } 

    void Window1_StateChanged(object sender, EventArgs e) 
    { 
     if (this.WindowState == WindowState.Minimized) 
      Console.WriteLine("SC: " + this.WindowState); 
    } 

    #endregion 

    #region Const 

    private int SYSCOMMAND = 0x0112; 
    private int SC_MINIMIZE = 0xf020; 
    private int WINDOWPOSCHANGING = 0x0046; 

    #endregion 

    private void AttachWndProc() 
    { 
     HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); 
     source.AddHook(new HwndSourceHook(WndProc)); 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    internal struct WINDOWPOSPARAMS 
    { 
     public IntPtr hwnd; 
     public IntPtr hwndInsertAfter; 
     public int x; 
     public int y; 
     public int cx; 
     public int cy; 
     public int flags; 
    } 


    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == WINDOWPOSCHANGING)    
     { 
      WINDOWPOSPARAMS param = (WINDOWPOSPARAMS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOSPARAMS)); 
      if (param.x == -32000 && param.y == -32000) 
      { 
       Output(""); 

            // EVENT WOULD BE RAISED HERE 

       Output("State before minimize:"); 
       Output(string.Format("CurrentState: {0}", this.WindowState)); 
       Output(string.Format("Location {0} {1}: ", this.Top, this.Left)); 
       Output(""); 
      } 
     } 

     // process minimize button 
     if (msg == SYSCOMMAND && SC_MINIMIZE == wParam.ToInt32()) 
     { 
      Output("Minimize clicked");    
     } 

     handled = false; 
     return IntPtr.Zero; 
    } 

    public void Output(object output) 
    { 
     this.txt.Text += output.ToString(); 
     this.txt.Text += Environment.NewLine;   
    }  

} 
} 
0

私はあなたがそれを直接行うことはできないと思います。

ウィンドウの呼び出しを最小限に抑えるには、ウィンドウクロムの最小化ボタン(タスクバーやWindowsタスクマネージャーを右クリックするなど)とAFAIKだけでなく、AFAIKを使用する方法もありませんウィンドウクロムから発したボタンイベントを直接処理します(もし誰かがこれをやる方法を知っていたら、教えてください)。

良いニュースは、あなたがそれを偽造することができますが、それは自明ではないので、それが価値があるかどうかを判断する必要があります。まず、標準のWindow Chromeをあなた自身のものに置き換える必要があります。あなたはそれを行う方法を見つけることができますhere

第2に、「最大化/最小化/閉じる」ボタンを作成し、イベントを適切な動作に結びつける必要があります。これは独自のUIなので、自由にボタンイベントを聴いたりキャンセルしたりできます。

TaskBar/Windowsタスクマネージャを使用してユーザーを最小化できないようにすることはできませんので、探しているものと正確に異なる可能性があります。

+0

ありがとうございます。私はすでにウィンドウにカスタムクロムを持っており、システムメニューからボタンを最小限に抑えてウィンドウメッセージをキャッチしています:タイトルバー、タスクバーのシステムメニュー、Alt +スペースのシステムメニュー。しかし、私はまだToggle Desktop(Win + D)とMinimize All(Win + M)のアプリケーションでイベントをキャプチャできません... –