2009-05-29 4 views
10

이미 WPF가 적용될 때가 아니라 최소화하기 전에 WPF 애플리케이션을 처리해야합니다. Window 객체 StateChanged에서 찾았지만 Window 객체가 이미 최소화 상태에있을 때 발생합니다. 너무 늦었습니다.WPF의 Window StateChanging 이벤트

Window 개체가 이전 상태 인 동안 처리 할 "StateChanging"이벤트와 같은 것이 필요합니다.

이러한 이벤트를 만들 수 있습니까?

답변

11

Spy ++ 사용을 최소화하기 전에 오른쪽 창에서 발견 된 창 메시지가 발견되었습니다. 호출 된 첫 번째 것은 WM_WINDOWPOSCHANGING입니다. 위젯을 최소화 할 때 윈도우가 -32000, -32000 위치 점을 이동한다는 것을 알지 못했습니다. WM_WINDOWPOSCHANGING의 매개 변수였습니다. 하지만, 나는 비스타에서만 테스트되었습니다. 여기에 사용 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

직접 할 수 없을 것이라고 생각합니다.

A 윈도우 최소화 버튼은 윈도우 크롬의 최소화 버튼 (예 : 작업 표시 줄이나 Windows 작업 관리자에서 오른쪽 버튼 클릭)과 AFAIK뿐만 아니라 여러 위치에서 발생할 수 있습니다. 창 크롬에서 발생하는 버튼 이벤트를 직접 처리합니다 (누군가가이 작업을 수행하는 방법을 알고 있다면 알려 주시기 바랍니다!).

좋은 소식은 가짜 일 수 있지만 사소한 것이 아니므로 가치가 있는지 판단해야합니다. 먼저, 표준 윈도우 크롬을 자신의 것으로 교체해야합니다. 그 방법을 찾을 수 있습니다 here.

둘째, "최대화/최소화/닫기"버튼을 만들어 이벤트를 적절한 행동으로 연결해야합니다. 자신 만의 UI이므로 버튼 이벤트를 자유롭게 듣고 취소 할 수 있습니다.

작업 표시 줄/Windows 작업 관리자를 통해 사용자가 최소화하지 못하도록 검색하거나 사용자를 차단할 수 없으므로 사용자가 찾고자하는 것이 정확하지 않을 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 나는 이미 윈도우에서 사용자 정의 크롬을 가지고 있으며, 시스템 메뉴에서 버튼 최소화에 대한 윈도우 메시지를 잡았다 : 제목 표시 줄, 작업 표시 줄의 시스템 메뉴, Alt + Space의 시스템 메뉴. 하지만 Toggle Desktop (Win + D) 및 Minimize All (Win + M) 응용 프로그램에서 이벤트를 캡처 할 수 없습니다. –