<?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; Interop</title>
	<atom:link href="http://huddledmasses.org/tag/interop/feed/" rel="self" type="application/rss+xml" />
	<link>http://huddledmasses.org</link>
	<description>You can do more than breathe for free...</description>
	<lastBuildDate>Fri, 27 Apr 2012 05:42:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</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/' 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>How to get the Char(acter) and VirtualKey from a WPF KeyDown event</title>
		<link>http://huddledmasses.org/how-to-get-the-character-and-virtualkey-from-a-wpf-keydown-event/</link>
		<comments>http://huddledmasses.org/how-to-get-the-character-and-virtualkey-from-a-wpf-keydown-event/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 05:02:34 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[Char]]></category>
		<category><![CDATA[EventHandler]]></category>
		<category><![CDATA[Interop]]></category>
		<category><![CDATA[KeyDown]]></category>
		<category><![CDATA[PInvoke]]></category>
		<category><![CDATA[ScanCode]]></category>
		<category><![CDATA[VirtualKey]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=699</guid>
		<description><![CDATA[While working on my WPF PowerShell console, I&#8217;m working on implementing PSRawUserInterface, and had to implement a method called ReadKey which returns a KeyInfo object. KeyInfo is a pretty simple struct class with four properties: VirtualKeyCode Character ControlKeyState KeyDown So it doesn&#8217;t seem like it would be a real problem &#8230; just handle the KeyDown [...]]]></description>
			<content:encoded><![CDATA[	<p>While working on my <span class="caps">WPF</span> <a href="http://www.microsoft.com/powershell" title="Windows PowerShell" rel="homepage" class="zem_slink">PowerShell</a> console, I&#8217;m working on implementing <a href="http://msdn.microsoft.com/en-us/library/system.management.automation.host.pshostrawuserinterface.aspx">PSRawUserInterface</a>, and had to implement a method called <a href="http://msdn.microsoft.com/en-us/library/system.management.automation.host.pshostrawuserinterface.readkey.aspx">ReadKey</a> which returns a <a href="http://msdn.microsoft.com/en-us/library/system.management.automation.host.keyinfo.aspx">KeyInfo</a> object.  KeyInfo is a pretty simple struct class with four properties:</p>

	<ul>
		<li>VirtualKeyCode</li>
		<li>Character </li>
		<li>ControlKeyState</li>
	</ul>
	<ul>
		<li>KeyDown</li>
	</ul>

	<p>So it doesn&#8217;t seem like it would be a real problem &#8230; just handle the <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.keydown.aspx">KeyDown</a> <a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.keydown.aspx">event</a> or <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.previewkeydown.aspx">PreviewKeyDown</a> <a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.previewkeydown.aspx">event</a> on the <span class="caps">WPF</span> control, right? Well, no. Because all of these just use a <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.keyeventargs.aspx">KeyEventArgs</a> parameter which has a <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.key.aspx">Key</a> property which doesn&#8217;t map to a virtual key code (why isn&#8217;t the <span class="caps">WPF</span> Key enumeration in the right order? It&#8217;s ridiculous), and there&#8217;s no character information at all.</p>

	<p>Thankfully, it <strong>is</strong> possible to get this information using PInvoke, but I wouldn&#8217;t want to try to do this in <a href="http://www.microsoft.com/silverlight/default.aspx" title="Microsoft Silverlight" rel="homepage" class="zem_slink">Silverlight</a>.  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt=';)' class='wp-smiley' />  </p>

	<p>Here&#8217;s how it goes:</p>

	<p>First, you need to get the VirtualKey code. Thankfully, there&#8217;s a simple class called <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.keyinterop.aspx">KeyInterop</a>, which exposes a static method <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.keyinterop.virtualkeyfromkey.aspx">VirtualKeyFromKey</a> that gets us this information.</p>

	<p>Then, we need to get the character. This is much trickier.  First we have to <a href="http://msdn.microsoft.com/en-us/library/ms646299.aspx">get the keyboard state</a> and then we have to <a href="http://msdn.microsoft.com/en-us/library/ms646306.aspx">map that VirtualKey</a> we got in the first step to a ScanCode, and finally, convert all of that <a href="http://msdn.microsoft.com/en-us/library/ms646320.aspx">to Unicode</a>, because .Net doesn&#8217;t really speak <span class="caps">ASCII</span>  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt=';)' class='wp-smiley' /> </p>

	<p>The rest of the code is pretty clear, I hope&#8230;<span id="more-699"></span> you can find the <em>current</em> version of <a href="https://poshconsole.svn.codeplex.com/svn/trunk/Huddled/Interop/Keyboard.cs">Keyboard.cs</a> on CodePlex in the PoshCode source repository, but to make this complete, here&#8217;s the version as it stands now:</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Management.Automation.Host</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Runtime.InteropServices</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Text</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Windows.Input</span><span style="color: #008000;">;</span><br />
<br />
<span style="color: #0600FF;">namespace</span> Huddled.<span style="color: #0000FF;">Interop</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">class</span> Keyboard<br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;The set of valid MapTypes used in MapVirtualKey</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// &lt;remarks&gt;&lt;/remarks&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">enum</span> MapType <span style="color: #008000;">:</span> <span style="color: #FF0000;">uint</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;uCode is a virtual-key code and is translated into a scan code.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// If it is a virtual-key code that does not distinguish between left- and</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// right-hand keys, the left-hand scan code is returned.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// If there is no translation, the function returns 0.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;remarks&gt;&lt;/remarks&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MAPVK_VK_TO_VSC <span style="color: #008000;">=</span> 0x0,<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;uCode is a scan code and is translated into a virtual-key code that</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// does not distinguish between left- and right-hand keys. If there is no</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// translation, the function returns 0.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;remarks&gt;&lt;/remarks&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MAPVK_VSC_TO_VK <span style="color: #008000;">=</span> 0x1,<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;uCode is a virtual-key code and is translated into an unshifted</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// character value in the low-order word of the return value. Dead keys (diacritics)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// are indicated by setting the top bit of the return value. If there is no</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// translation, the function returns 0.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;remarks&gt;&lt;/remarks&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MAPVK_VK_TO_CHAR <span style="color: #008000;">=</span> 0x2,<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;Windows NT/2000/XP: uCode is a scan code and is translated into a</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// virtual-key code that distinguishes between left- and right-hand keys. If</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// there is no translation, the function returns 0.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;remarks&gt;&lt;/remarks&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MAPVK_VSC_TO_VK_EX <span style="color: #008000;">=</span> 0x3,<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;Not currently documented</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008080; font-style: italic;">/// &lt;remarks&gt;&lt;/remarks&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MAPVK_VK_TO_VSC_EX <span style="color: #008000;">=</span> 0x4,<br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// The ToUnicode function translates the specified virtual-key code and keyboard state </span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// to the corresponding Unicode character or characters. To specify a handle to the keyboard layout </span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// to use to translate the specified code, use the ToUnicodeEx function.</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// </span></div>

<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/4d89ee6c-d3c1-45fd-a043-eaef925688b6/" title="Zemified by Zemanta"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_e.png?x-id=4d89ee6c-d3c1-45fd-a043-eaef925688b6" alt="Reblog this post [with Zemanta]" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/how-to-get-the-character-and-virtualkey-from-a-wpf-keydown-event/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

