在WPF窗口StateChanging事件 [英] Window StateChanging event in WPF

查看:598
本文介绍了在WPF窗口StateChanging事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要处理的WPF应用程序的权利之前,它会最小化,而不是当它已经存在。 我发现Window对象StateChanged,但它触发时,Window对象是已经在最小化状态,那么一切都太迟了。

I need to handle WPF application right before it goes Minimize, not when it's already there. I found on Window object StateChanged, but it fires when Window object is already in Minimize state, then it's too late.

所以,我需要的东西,如StateChanging事件来处理,而Window对象仍处于previous状态。

So, I need something like "StateChanging" event to handle, while Window object is still in previous state.

是否有可能创造这样的事件?

Is it possible to create such event ?

推荐答案

找到Windows消息呼吁窗口右侧前尽量减少使用间谍++。第一个被称为是WM_WINDOWPOSCHANGING。 我不知道窗户上-32000移动窗口时,最大限度地减少寡妇,这些都是在WM_WINDOWPOSCHANGING的PARAMS -32000定位点。虽然,我已经测试只有在Vista上。 <一href="http://blogs.msdn.com/oldnewthing/archive/2004/10/28/249044.aspx">http://blogs.msdn.com/oldnewthing/archive/2004/10/28/249044.aspx

Found windows messages called on window right before minimize using Spy++. First one that is called is WM_WINDOWPOSCHANGING. I didn't know windows is moving window on -32000, -32000 location point when minimizing widow, and those were the params in WM_WINDOWPOSCHANGING. Though, I have tested is only on Vista. http://blogs.msdn.com/oldnewthing/archive/2004/10/28/249044.aspx

这里使用code被张贴由尼尔<一href="http://stackoverflow.com/questions/386484/how-can-i-only-allow-uniform-resizing-in-a-wpf-window/696266#696266">here

code used here was posted by Nir here

下面是示例code

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;			
	}		

}
}

这篇关于在WPF窗口StateChanging事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆