<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Huddled Masses &#187; NativeBehaviors</title>
	<atom:link href="http://huddledmasses.org/tag/nativebehaviors/feed/" rel="self" type="application/rss+xml" />
	<link>http://huddledmasses.org</link>
	<description>You can do more than breathe for free...</description>
	<lastBuildDate>Tue, 31 Aug 2010 04:13:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
<cloud domain='huddledmasses.org' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>WPF Window &#8220;Native&#8221; Behavior: The Base Class</title>
		<link>http://huddledmasses.org/wpf-window-native-behaviors/</link>
		<comments>http://huddledmasses.org/wpf-window-native-behaviors/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 21:52:18 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Interop]]></category>
		<category><![CDATA[NativeBehaviors]]></category>
		<category><![CDATA[PInvoke]]></category>
		<category><![CDATA[Windows Presentation Foundation]]></category>
		<category><![CDATA[WndProc]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=726</guid>
		<description><![CDATA[I wrote yesterday about the WPF Snap-To Behavor that I created, and showed you how simple it is, but I skipped over where the magic happens, so I thought I&#8217;d go through how I created the Native Behaviors collection class, because there are a few cool tricks in here that I wanted to share with [...]]]></description>
			<content:encoded><![CDATA[	<p>I wrote yesterday about the <a href="http://huddledmasses.org/wpf-windows-that-snap-to-screen-edges/"><span class="caps">WPF</span> Snap-To Behavor</a> that I created, and showed you how simple it is, but I skipped over where the magic happens, so I thought I&#8217;d go through how I created the Native Behaviors collection class, because there are a few cool tricks in here that I wanted to share with <span class="caps">WPF</span> developers at large (even if you&#8217;re not interested in hooking the Window Procedure).</p>

	<p>The framework for Native Bahaviors is made up of just two classes, the first of which is basically 3 lines of code.</p>

 <code>NativeBehavior</code> is the abstract base class for behaviors, and consists of just definitions for the mandatory abstract GetHandlers() method (where you return an <code>IEnumerable</code> collection of mappings from Window Messages to your delegate methods) and the two optional (virtual) methods <code>AddTo</code> and <code>RemoveFrom</code> which are called when your behavior is initially added to a window (generally <strong>before</strong> the Window is initialized).

	<p><code>NativeBehaviors</code> is an <a href="http://msdn.microsoft.com/en-us/library/ms668604.aspx">ObservableCollection</a> of <code>NativeBehavior</code>s, obviously  <img src='http://huddledmasses.org/wordpress/wp-includes/images/smilies/../../../wp-content/plugins/smilingmasses/wink.gif' alt=';)' class='wp-smiley' /> . But it&#8217;s ever so much more than that.  First of all, it has the <code>NativeBehaviors</code> attached property, but it also has the code for actually hooking a <span class="caps">WPF</span> window to get the Window Messages, and a WndProc which processes each message against the mappings retrieved from the various <code>NativeBehavior</code>s that have been registered.</p>

	<p>Lets start with the attached dependency property.  There&#8217;s a very clever (and problematic) trick in the way this property is exposed.  If you look at this code, you&#8217;ll see I create a <strong>private</strong> NativeBehavior dependency property, and then create public Get/Set accessors for &#8220;Behavior&#8221; which just call the NativeBehavior property.  The reason for this is that if the dependency property is public, or if the public accessors even have the same name &#8230; the <span class="caps">XAML</span> parser finds the dependency property and uses it directly (bypassing the get/set accesors), which means you have to have an extra element in your <span class="caps">XAML</span> markup to initialize the NativeBehaviors collection, or you get something like this screenshot.</p>

	<a href="http://HuddledMasses.org/wordpress/wp-content/uploads/2008/10/behaviorsisnull.png"><img src="http://HuddledMasses.org/wordpress/wp-content/uploads/2008/10/behaviorsisnull-300x116.png" alt="The behavior collection doesn't get created..." title="Behavior Is Null" class="size-medium wp-image-727" width="300" height="116" /></a>

	<p>So instead, we hide the dependency property, and supply a getter which is backed by the dependency property.  I should not that although this <strong>works</strong> great in the .Net Framework, it&#8217;s not recognized properly by all of the tools (including Resharper 4.1 and even Expression Blend), so you may have to fiddle with things.</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">readonly</span> DependencyProperty NativeBehaviorsProperty <span style="color: #008000;">=</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DependencyProperty.<span style="color: #0000FF;">RegisterAttached</span><span style="color: #000000;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666;">&quot;NativeBehaviors&quot;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #008000;">typeof</span></a><span style="color: #000000;">&#40;</span>NativeBehaviors<span style="color: #000000;">&#41;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #008000;">typeof</span></a><span style="color: #000000;">&#40;</span>NativeBehaviors<span style="color: #000000;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> FrameworkPropertyMetadata<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// A public setter (for the non-existent &quot;Behaviors&quot; property)</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">void</span> SetBehaviors<span style="color: #000000;">&#40;</span>Window window, NativeBehaviors behaviors<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>window <span style="color: #008000;">==</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> ArgumentNullException<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;window&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;window.<span style="color: #0000FF;">SetValue</span><span style="color: #000000;">&#40;</span>NativeBehaviorsProperty, behaviors<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// The public getter &nbsp;(for the non-existent &quot;Behaviors&quot; property)</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> NativeBehaviors GetBehaviors<span style="color: #000000;">&#40;</span>Window window<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span> &nbsp;<span style="color: #008080; font-style: italic;">// instead of GetValue, call the accessor!</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">return</span> GetNativeBehaviors<span style="color: #000000;">&#40;</span>window<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// This dependency property getter makes sure it returns a collection</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> NativeBehaviors GetNativeBehaviors<span style="color: #000000;">&#40;</span>Window window<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>window <span style="color: #008000;">==</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> ArgumentNullException<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;window&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// This is the plain old normal thing:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var behaviors <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>NativeBehaviors<span style="color: #000000;">&#41;</span>window.<span style="color: #0000FF;">GetValue</span><span style="color: #000000;">&#40;</span>NativeBehaviorsProperty<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// Our raison d'être: create a new collection if there isn't one yet</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>behaviors <span style="color: #008000;">==</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> behaviors <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> NativeBehaviors<span style="color: #000000;">&#40;</span>window<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">return</span> behaviors<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp;</div>

	<p>There&#8217;s a little more to it in the <a href="https://poshconsole.svn.codeplex.com/svn/trunk/Huddled/Wpf/NativeBehaviors.cs">actual class source code</a>, I&#8217;m glossing over the simplest parts, and leaving out all the <span class="caps">XML</span> documentation comments too.  We override the CollectionChanged event so that we can hook new Behaviors as they arrive, and we make sure to hook the WndProc whenever the Target Window is set:</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> OnCollectionChanged<span style="color: #000000;">&#40;</span>NotifyCollectionChangedEventArgs nccea<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">base</span>.<span style="color: #0000FF;">OnCollectionChanged</span><span style="color: #000000;">&#40;</span>nccea<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// design mode bailout because NativeBehaviors don't work in DesignMode</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>DesignerProperties.<span style="color: #0000FF;">GetIsInDesignMode</span><span style="color: #000000;">&#40;</span>Target<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> return<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// notify new behaviors they are being hooked up, and track their handlers</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>nccea.<span style="color: #0000FF;">Action</span> <span style="color: #008000;">==</span> NotifyCollectionChangedAction.<span style="color: #0000FF;">Add</span> <span style="color: #008000;">||</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;nccea.<span style="color: #0000FF;">Action</span> <span style="color: #008000;">==</span> NotifyCollectionChangedAction.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span>NativeBehavior behavior <span style="color: #0600FF;">in</span> nccea.<span style="color: #0000FF;">NewItems</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;behavior.<span style="color: #0000FF;">AddTo</span><span style="color: #000000;">&#40;</span>Target<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Handlers.<span style="color: #0000FF;">AddRange</span><span style="color: #000000;">&#40;</span>behavior.<span style="color: #0000FF;">GetHandlers</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// notify removed behaviors they are being unhooked, and stop tracking their handlers</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>nccea.<span style="color: #0000FF;">Action</span> <span style="color: #008000;">==</span> NotifyCollectionChangedAction.<span style="color: #0000FF;">Remove</span> <span style="color: #008000;">||</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;nccea.<span style="color: #0000FF;">Action</span> <span style="color: #008000;">==</span> NotifyCollectionChangedAction.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span>NativeBehavior behavior <span style="color: #0600FF;">in</span> nccea.<span style="color: #0000FF;">OldItems</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;behavior.<span style="color: #0000FF;">RemoveFrom</span><span style="color: #000000;">&#40;</span>Target<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span>var h <span style="color: #0600FF;">in</span> behavior.<span style="color: #0000FF;">GetHandlers</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Handlers.<span style="color: #0000FF;">Remove</span><span style="color: #000000;">&#40;</span>h<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span><br />
<br />
<span style="color: #008080; font-style: italic;">// Hook the Window when its added</span><br />
<span style="color: #008080; font-style: italic;">// but keep only a week reference to it...</span><br />
<span style="color: #0600FF;">public</span> Window Target<br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;get<br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>_owner <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">return</span> _owner.<span style="color: #0000FF;">Target</span> <span style="color: #0600FF;">as</span> Window<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF;">else</span> <span style="color: #0600FF;">return</span> null<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;set<br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// design mode bailout (in Design mode there's no window, and no wndproc)</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>DesignerProperties.<span style="color: #0000FF;">GetIsInDesignMode</span><span style="color: #000000;">&#40;</span>value<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> return<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>_owner <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span> <span style="color: #008000;">&amp;</span>amp<span style="color: #008000;">;&amp;</span>amp<span style="color: #008000;">;</span> WindowHandle <span style="color: #008000;">!=</span> IntPtr.<span style="color: #0000FF;">Zero</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HwndSource.<span style="color: #0000FF;">FromHwnd</span><span style="color: #000000;">&#40;</span>WindowHandle<span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">RemoveHook</span><span style="color: #000000;">&#40;</span>WndProc<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; Debug.<span style="color: #0000FF;">Assert</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">null</span> <span style="color: #008000;">!=</span> value<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; _owner <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> WeakReference<span style="color: #000000;">&#40;</span>value<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Check for an HWND to determine if the Window has been loaded.</span><br />
&nbsp; &nbsp; &nbsp; WindowHandle <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> WindowInteropHelper<span style="color: #000000;">&#40;</span>value<span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Handle</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>IntPtr.<span style="color: #0000FF;">Zero</span> <span style="color: #008000;">==</span> WindowHandle<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span> <span style="color: #008080; font-style: italic;">// If there's no handle, set the hook when the Source is initialised.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;value.<span style="color: #0000FF;">SourceInitialized</span> <span style="color: #008000;">+=</span> <span style="color: #000000;">&#40;</span>sender, e<span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&amp;</span>gt<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WindowHandle <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> WindowInteropHelper<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>Window<span style="color: #000000;">&#41;</span>sender<span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Handle</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// hook the WndProc </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HwndSource.<span style="color: #0000FF;">FromHwnd</span><span style="color: #000000;">&#40;</span>WindowHandle<span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">AddHook</span><span style="color: #000000;">&#40;</span>WndProc<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">else</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span> <span style="color: #008080; font-style: italic;">// hook the WndProc </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HwndSource.<span style="color: #0000FF;">FromHwnd</span><span style="color: #000000;">&#40;</span>WindowHandle<span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">AddHook</span><span style="color: #000000;">&#40;</span>WndProc<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span><br />
<span style="color: #008080; font-style: italic;">// the weak reference to the actual window...</span><br />
<span style="color: #0600FF;">private</span> WeakReference _owner<span style="color: #008000;">;</span><br />
&nbsp;</div>

	<p>And finally, the last part of the puzzle is my actual WndProc implementation, which has a minor drawback in that we can hypothetically have multiple behaviors which process the same window message &#8230; and may each return a different value (which we cannot reconcile).  For now I&#8217;m just returning the last (non-zero) result (in actuality, all of the behaviors I&#8217;ve written thus far return zero).</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #0600FF;">private</span> IntPtr WndProc<span style="color: #000000;">&#40;</span>IntPtr hwnd, <span style="color: #FF0000;">int</span> msg, IntPtr wParam, IntPtr lParam, <span style="color: #0600FF;">ref</span> <span style="color: #FF0000;">bool</span> handled<span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;Debug.<span style="color: #0000FF;">Assert</span><span style="color: #000000;">&#40;</span>hwnd <span style="color: #008000;">==</span> WindowHandle<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">// Only expecting messages for our cached HWND.</span><br />
<br />
&nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// cast and cache the message</span><br />
&nbsp; &nbsp;var message <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>NativeMethods.<span style="color: #0000FF;">WindowMessage</span><span style="color: #000000;">&#41;</span>msg<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// NOTE: we may process a message multiple times</span><br />
&nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// and we have no good way to handle that...</span><br />
&nbsp; &nbsp;var result <span style="color: #008000;">=</span> IntPtr.<span style="color: #0000FF;">Zero</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span>var handlePair <span style="color: #0600FF;">in</span> Handlers<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span> &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>handlePair.<span style="color: #0000FF;">Key</span> <span style="color: #008000;">==</span> message<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var r <span style="color: #008000;">=</span> handlePair.<span style="color: #0000FF;">Value</span><span style="color: #000000;">&#40;</span>wParam, lParam, <span style="color: #0600FF;">ref</span> handled<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// So, we'll return the last non-zero result (if any)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>r <span style="color: #008000;">!=</span> IntPtr.<span style="color: #0000FF;">Zero</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> result <span style="color: #008000;">=</span> r<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span> &nbsp;<span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">return</span> result<span style="color: #008000;">;</span><br />
<span style="color: #000000;">&#125;</span><br />
&nbsp;</div>

	<p>That pretty much covers the framework.  The actual behaviors can be fairly simple like my <a href="http://huddledmasses.org/wpf-windows-that-snap-to-screen-edges/">Snap-To</a> behavior (which is actually <em>too</em> simple), or extremely complex like my latest behavior, which is a port <a href="http://code.msdn.microsoft.com/chrome">Joe Castro&#8217;s custom Window &#8216;Chrome&#8217;</a> to my behavior framework, and I&#8217;m hoping some of you will choose to write new ones and submit them as patches to the CodePlex project (for now, I&#8217;m just piggybacking it on the <a href="http://CodePlex.com/PoshConsole">PoshConsole</a> project). But in any case, the latest code is available <a href="https://poshconsole.svn.codeplex.com/svn/trunk/Huddled">via subversion</a> on CodePlex, and you can download <a href="http://HuddledMasses.org/wordpress/wp-content/uploads/2008/10/huddledinteropwpf.7z">today&#8217;s snapshot here</a>.</p>

<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/2128e76c-26a5-40d9-8e1d-cd6d8ddd318f/" title="Zemified by Zemanta"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_e.png?x-id=2128e76c-26a5-40d9-8e1d-cd6d8ddd318f" alt="Reblog this post [with Zemanta]" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/wpf-window-native-behaviors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF Window &#8220;Native&#8221; Behavior: Snap-To Screen Edges</title>
		<link>http://huddledmasses.org/wpf-windows-that-snap-to-screen-edges/</link>
		<comments>http://huddledmasses.org/wpf-windows-that-snap-to-screen-edges/#comments</comments>
		<pubDate>Tue, 14 Oct 2008 05:06:36 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[NativeBehaviors]]></category>
		<category><![CDATA[Win32]]></category>
		<category><![CDATA[WM_WINDOWPOSCHANGING]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=718</guid>
		<description><![CDATA[There are many desirable behaviors for Windows applications that are just much harder to do than they should be with the tools that Microsoft has provided in the .Net Framework. In WPF, many of these behaviors are even harder to create than in Windows Forms because the necessary hooks take a bit more work to [...]]]></description>
			<content:encoded><![CDATA[	<p>There are many desirable behaviors for Windows applications that are just much harder to do than they should be with the tools that Microsoft has provided in the .Net Framework. In <a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation" title="Windows Presentation Foundation" rel="wikipedia" class="zem_slink">WPF</a>, many of these behaviors are even harder to create than in <a href="http://en.wikipedia.org/wiki/Windows_Forms" title="Windows Forms" rel="wikipedia" class="zem_slink">Windows Forms</a> because the necessary hooks take a bit more work to write (thanks to the fact that there&#8217;s no window handles, so dropping down to &#8220;Native&#8221; code is harder.  Luckily, <span class="caps">WPF</span> Attached Properties give us a whole new way to reuse these behaviors once they&#8217;re written.</p>

	<p>I&#8217;ve started working on a few classes I&#8217;m calling NativeBehaviors, because they rely on intercepting the native <em>Window Message</em> processing, and I&#8217;ve put together a simple framework to let me write them, which I thought I would share.  The first one I wrote is a SnapToBehavior, which implements a feature that people seem to be constantly re-implementing in apps. Basically, it makes a window snap to the screen edge when it gets close (and prevents them from being moved off-screen).  I&#8217;ve also written a Global HotkeysBehavior which lets you register Hotkeys that work whenever your app is running (even if another app is active) so you can create a Hotkey to hide your app and show it, or whatever.</p>

	<p>In the rest of this article I&#8217;ll show you how to achieve this in <span class="caps">WPF</span> using my base NativeBehavior class, and how to use it on a Window. Since some of you won&#8217;t really care how it works, let&#8217;s start with:</p>

	<h3>How to make your <span class="caps">WPF</span> Windows snap to screen edges in 3 easy steps:</h3>

	<p>Step 1. Add a reference to the Huddled.Wpf.Interop library.<br />
Step 2. Add my Xml namespace to your root Window element<br />
Step 3. Paste three lines from below&#8230;.</p>

	<div class="xml code xml" style="font-family:monospace;"><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Window</span> <span style="color: #000066;">x:Class</span>=<span style="color: #ff0000;">&quot;GlobalHotkeys.DemoWindow&quot;</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;DemoWindow&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">Title</span>=<span style="color: #ff0000;">&quot;GlobalHotkeys&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;300&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;300&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:x</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:huddled</span>=<span style="color: #ff0000;">&quot;http://schemas.huddledmasses.org/wpf&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #808080; font-style: italic;">&lt;!-- You just add a reference to the library, add the &quot;huddled&quot; namespace, and paste: --&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:Native.Behaviors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:SnapToBehavior</span> <span style="color: #000066;">SnapDistance</span>=<span style="color: #ff0000;">&quot;20&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/huddled:Native.Behaviors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #808080; font-style: italic;">&lt;!-- The rest of your window can be whatever you like. --&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Label</span> <span style="color: #000066;">Content</span>=<span style="color: #ff0000;">&quot;Drag this window near the screen edges&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Window<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp;</div>

	<p>I should point out the &#8220;SnapDistance&#8221; property of the SnapToBehavior is actually a <span class="caps">WPF</span> &#8220;Thickness&#8221; which lets you specify the distance from the screen edge as a single number to use on all sides, or as a separate number for each side: Left, Top, Right, Bottom. And that&#8217;s pretty much all there is to know.</p>

	<h3>How to implement a NativeBehavior.</h3>

	<p>The implementation of the SnapToBehavior is actually ridiculously simple, given the NativeBehavior framework.  I simply created a SnapToBehavior class which derives from NativeBehavior, and implemented the single mandatory method:</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span><br />
<span style="color: #008080; font-style: italic;">/// Gets the MessageMappings for this behavior:</span><br />
<span style="color: #008080; font-style: italic;">/// A single mapping of a handler for WM_WINDOWPOSCHANGING.</span><br />
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
<span style="color: #008080; font-style: italic;">/// &lt;returns&gt;An enumerable collection of MessageMapping objects.&lt;/returns&gt;</span><br />
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">override</span> IEnumerable<span style="color: #008000;">&lt;</span>MessageMapping<span style="color: #008000;">&gt;</span> GetHandlers<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;yield <span style="color: #0600FF;">return</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> MessageMapping<span style="color: #000000;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; NativeMethods.<span style="color: #0000FF;">WindowMessage</span>.<span style="color: #0000FF;">WindowPositionChanging</span>, <span style="color: #008080; font-style: italic;">// the message</span><br />
&nbsp; &nbsp; &nbsp; OnPreviewPositionChange<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">// the delegate which will handle that message</span><br />
<span style="color: #000000;">&#125;</span><br />
&nbsp;</div>

	<p>When my new behavior is added to the Behaviors collection, my handler will be registered, and whenever the WM_WINDOWPOSCHANGING message arrives, it will be called.  Now I defined a <a href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.aspx">DependencyProperty</a> for the SnapDistance, so that you could set that in <span class="caps">XAML</span>.  It&#8217;s extremely simple, and VisualStudio has a built-in snippet for dependency properties, but here&#8217;s the code:</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">readonly</span> DependencyProperty SnapDistanceProperty <span style="color: #008000;">=</span><br />
&nbsp; &nbsp;DependencyProperty.<span style="color: #0000FF;">Register</span><span style="color: #000000;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666;">&quot;SnapDistance&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// The name of the property (must match)</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #008000;">typeof</span></a><span style="color: #000000;">&#40;</span>Thickness<span style="color: #000000;">&#41;</span>, &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">// The type of the values</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #008000;">typeof</span></a><span style="color: #000000;">&#40;</span>SnapToBehavior<span style="color: #000000;">&#41;</span>, &nbsp; <span style="color: #008080; font-style: italic;">// The type this property shows up on</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> UIPropertyMetadata<span style="color: #000000;">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Thickness<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">20</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #008080; font-style: italic;">// The default value</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
<span style="color: #0600FF;">public</span> Thickness SnapDistance<br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> <span style="color: #000000;">&#40;</span>Thickness<span style="color: #000000;">&#41;</span>GetValue<span style="color: #000000;">&#40;</span>SnapDistanceProperty<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;set <span style="color: #000000;">&#123;</span> SetValue<span style="color: #000000;">&#40;</span>SnapDistanceProperty, value<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span><br />
&nbsp;</div>

	<p>Once I have that, the last piece of the puzzle is to actually handle the window position changing message (think of it as an event, if you&#8217;re not used to Win32 message-based programming).</p>

	<p>The basics of handling WM_WINDOWPOSCHANGING is that you get a structure passed in which has the <strong>proposed</strong> position of the Window, (including it&#8217;s z-index related to other apps) and you can basically tweak that however you like.  Obviously there are lots of possibilities for this single message: always-on-bottom windows, undraggable windows, etc., but in our case we&#8217;re just concerned about how close we are to the edge.</p>

	<p>We use the SystemParameters class to get the VirtualScreenLeft, VirtualScreenTop, and VirtualScreenWidth and VirtualScreenHeight which define the rectangle we&#8217;ll use for snapping.  In the case of non-rectangular arrangements of multiple monitors this isn&#8217;t quite sufficient, but for our example anything more would be a distraction.  Then we just check to see if the proposed position is within the &#8220;SnapDistance&#8221; of any of the edges, and if so, we change the position to be against the edge.  That&#8217;s really all there is to it.</p>

	<p>If you look at the code example below you&#8217;ll see I have to &#8220;Marshal&#8221; the WindowPosition structure in and out of an IntPtr which is passed in the WindowMessage &#8230; that&#8217;s the downside of intercepting window messages that the framework doesn&#8217;t already translate for us, but in this particular case, it&#8217;s actually fairly trivial.</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;lParam for WindowPositionChanging</span><br />
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
<span style="color: #000000;">&#91;</span>StructLayout<span style="color: #000000;">&#40;</span>LayoutKind.<span style="color: #0000FF;">Sequential</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span><br />
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">struct</span> WindowPosition<br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> IntPtr Handle<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> IntPtr HandleInsertAfter<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Left<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Top<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Width<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Height<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> WindowPositionFlags Flags<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Right <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> Left <span style="color: #008000;">+</span> Width<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">int</span> Bottom <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> Top <span style="color: #008000;">+</span> Height<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span> &nbsp; <br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">private</span> IntPtr OnPreviewPositionChange<span style="color: #000000;">&#40;</span>IntPtr wParam, IntPtr lParam, <span style="color: #0600FF;">ref</span> <span style="color: #FF0000;">bool</span> handled<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #FF0000;">bool</span> updated <span style="color: #008000;">=</span> false<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var windowPosition <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>NativeMethods.<span style="color: #0000FF;">WindowPosition</span><span style="color: #000000;">&#41;</span>Marshal.<span style="color: #0000FF;">PtrToStructure</span><span style="color: #000000;">&#40;</span>lParam, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #008000;">typeof</span></a><span style="color: #000000;">&#40;</span>NativeMethods.<span style="color: #0000FF;">WindowPosition</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Flags</span> <span style="color: #008000;">&amp;</span> NativeMethods.<span style="color: #0000FF;">WindowPositionFlags</span>.<span style="color: #0000FF;">NoMove</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// If we use the WPF SystemParameters, these should be &quot;Logical&quot; pixels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Rect validArea <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Rect<span style="color: #000000;">&#40;</span>SystemParameters.<span style="color: #0000FF;">VirtualScreenLeft</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemParameters.<span style="color: #0000FF;">VirtualScreenTop</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemParameters.<span style="color: #0000FF;">VirtualScreenWidth</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SystemParameters.<span style="color: #0000FF;">VirtualScreenHeight</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Rect snapToBorder <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Rect<span style="color: #000000;">&#40;</span>SystemParameters.<span style="color: #0000FF;">VirtualScreenLeft</span> <span style="color: #008000;">+</span> SnapDistance.<span style="color: #0000FF;">Left</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemParameters.<span style="color: #0000FF;">VirtualScreenTop</span> <span style="color: #008000;">+</span> SnapDistance.<span style="color: #0000FF;">Top</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemParameters.<span style="color: #0000FF;">VirtualScreenWidth</span> <span style="color: #008000;">-</span> <span style="color: #000000;">&#40;</span>SnapDistance.<span style="color: #0000FF;">Left</span> <span style="color: #008000;">+</span> SnapDistance.<span style="color: #0000FF;">Right</span><span style="color: #000000;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SystemParameters.<span style="color: #0000FF;">VirtualScreenHeight</span> <span style="color: #008000;">-</span> <span style="color: #000000;">&#40;</span>SnapDistance.<span style="color: #0000FF;">Top</span> <span style="color: #008000;">+</span> SnapDistance.<span style="color: #0000FF;">Bottom</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Enforce left boundary</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Left</span> <span style="color: #008000;">&lt;</span> snapToBorder.<span style="color: #0000FF;">Left</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;windowPosition.<span style="color: #0000FF;">Left</span> <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span>validArea.<span style="color: #0000FF;">Left</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;updated <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Enforce top boundary</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Top</span> <span style="color: #008000;">&lt;</span> snapToBorder.<span style="color: #0000FF;">Y</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;windowPosition.<span style="color: #0000FF;">Top</span> <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span>validArea.<span style="color: #0000FF;">Top</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;updated <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Enforce right boundary</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Right</span> <span style="color: #008000;">&gt;</span> snapToBorder.<span style="color: #0000FF;">Right</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;windowPosition.<span style="color: #0000FF;">Left</span> <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#40;</span>validArea.<span style="color: #0000FF;">Right</span> <span style="color: #008000;">-</span> windowPosition.<span style="color: #0000FF;">Width</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;updated <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// Enforce bottom boundary</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>windowPosition.<span style="color: #0000FF;">Bottom</span> <span style="color: #008000;">&gt;</span> snapToBorder.<span style="color: #0000FF;">Bottom</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;windowPosition.<span style="color: #0000FF;">Top</span> <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#40;</span>validArea.<span style="color: #0000FF;">Bottom</span> <span style="color: #008000;">-</span> windowPosition.<span style="color: #0000FF;">Height</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;updated <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>updated<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Marshal.<span style="color: #0000FF;">StructureToPtr</span><span style="color: #000000;">&#40;</span>windowPosition, lParam, <span style="color: #0600FF;">true</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">return</span> IntPtr.<span style="color: #0000FF;">Zero</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp;</div>

	<h3>Download it, or get the source code</h3>

	<p>If you&#8217;d like, you can download the current <a href='http://HuddledMasses.org/wordpress/wp-content/uploads/2008/10/huddledinteropwpf.dll'>Huddled Interop for <span class="caps">WPF</span> library</a> right now, or you can check out the source from CodePlex <a href="https://poshconsole.svn.codeplex.com/svn/trunk/Huddled/">SVN</a> or just download the <a href="http://www.codeplex.com/PoshConsole/SourceControl/ListDownloadableCommits.aspx">most recent commit</a> (You are only interested in the &#8220;Huddled&#8221; project which is in the &#8220;trunk&#8221;, not the &#8220;trunk-3.5&#8221;).  <span class="emph1">The source is licensed freely under the <span class="caps">BSD</span> or <span class="caps">GPL</span> v2</span> (and a few other licenses, see the top of the source code files).</p>

	<p>Either way you&#8217;ll get not just the SnapToBehavior but also the global HotkeysBehavior, and the Native Behaviors framework which I&#8217;ll write more about later, but for now, in case you want to try to use it, here&#8217;s an example using both the SnapTo and HotkeysBehavior (you can find this in the <a href="https://poshconsole.svn.codeplex.com/svn/trunk/GlobalHotkeys">GlobalHotkeys</a> demo project, which includes some sample code for handling hotkey conflicts).  Enjoy.</p>

	<div class="xml code xml" style="font-family:monospace;"><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Window</span> <span style="color: #000066;">x:Class</span>=<span style="color: #ff0000;">&quot;GlobalHotkeys.DemoWindow&quot;</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;window&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:x</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">xmlns:huddled</span>=<span style="color: #ff0000;">&quot;http://schemas.huddledmasses.org/wpf&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000066;">Title</span>=<span style="color: #ff0000;">&quot;Demo Window!&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;300&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;200&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:Native.Behaviors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:SnapToBehavior</span> <span style="color: #000066;">SnapDistance</span>=<span style="color: #ff0000;">&quot;80,20,80,10&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;huddled:HotkeysBehavior<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;KeyBinding</span> <span style="color: #000066;">Command</span>=<span style="color: #ff0000;">&quot;huddled:GlobalCommands.ActivateWindow&quot;</span> <span style="color: #000066;">Key</span>=<span style="color: #ff0000;">&quot;K&quot;</span> &nbsp;<span style="color: #000066;">Modifiers</span>=<span style="color: #ff0000;">&quot;Win&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;KeyBinding</span> <span style="color: #000066;">Command</span>=<span style="color: #ff0000;">&quot;huddled:GlobalCommands.CloseWindow&quot;</span> &nbsp; &nbsp;<span style="color: #000066;">Key</span>=<span style="color: #ff0000;">&quot;F4&quot;</span> <span style="color: #000066;">Modifiers</span>=<span style="color: #ff0000;">&quot;Win&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;KeyBinding</span> <span style="color: #000066;">Command</span>=<span style="color: #ff0000;">&quot;huddled:GlobalCommands.ToggleWindow&quot;</span> &nbsp; <span style="color: #000066;">Key</span>=<span style="color: #ff0000;">&quot;S&quot;</span> &nbsp;<span style="color: #000066;">Modifiers</span>=<span style="color: #ff0000;">&quot;Win&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/huddled:HotkeysBehavior<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/huddled:Native.Behaviors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Label</span> <span style="color: #000066;">Content</span>=<span style="color: #ff0000;">&quot;Drag this window near the screen edges&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Window<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/wpf-windows-that-snap-to-screen-edges/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
