<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Coding4Fun</title><link>http://blogs.msdn.com/coding4fun/default.aspx</link><description>&lt;div id="menuContainer"&gt;&lt;/div&gt;</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>INotify on new changes</title><link>http://blogs.msdn.com/coding4fun/archive/2009/11/29/9930051.aspx</link><pubDate>Mon, 30 Nov 2009 06:57:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9930051</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9930051.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9930051</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9930051</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/jaimer/archive/2009/09/22/wpf-discussion-090922.aspx"&gt;Jaime Rodriguez has a great post on some of the interesting things we at Microsoft have on one of our internal discussions, namely the WPF one.&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;The big one I noticed was that my favorite was smack at the top.&amp;#160; INotifyCollection is now going to be part of system.dll so you can make your now see if stuff gets modified!&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;Subject:&lt;/b&gt; Any chance of INotifyCollectionChanged moving to the core .NET libraries? &lt;/p&gt;    &lt;p&gt;The&amp;#160; System.Collections.Specialized.INotifyCollectionChanged interface is defined in WindowsBase.dll (primarily a WPF assembly) but my customer believes it should be pushed down into the core BCL so that other project types can benefit from it without requiring a reference to WPF/WindowsBase.&lt;/p&gt;    &lt;p&gt;Is this planned for 4.0 or later?&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Answer:        &lt;br /&gt;&lt;/strong&gt;INotifyCollectionChanged, ObservableCollection&amp;lt;T&amp;gt;, and ReadOnlyObservableCollection&amp;lt;T&amp;gt; have been type forwarded into System.dll for .NET 4.&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9930051" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category></item><item><title>Silverlight Development</title><link>http://blogs.msdn.com/coding4fun/archive/2009/11/18/9922257.aspx</link><pubDate>Wed, 18 Nov 2009 23:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9922257</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9922257.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9922257</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9922257</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/SilverlightDevelopment_9377/sliverPlusLight_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="sliverPlusLight" border="0" alt="sliverPlusLight" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/SilverlightDevelopment_9377/sliverPlusLight_thumb.jpg" width="483" height="164" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;With Silverlight 4.0 just announced, here are some great posts / helpful tips on getting started with Silverlight in general.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://r.ch9.ms/sl4cl"&gt;Channel9 has a training course&lt;/a&gt;.&lt;/li&gt;    &lt;li&gt;Tim Heuer has a 7-part series “&lt;a href="http://timheuer.com/blog/articles/getting-started-with-silverlight-development.aspx"&gt;Getting Started with Silverlight&lt;/a&gt;”.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.shinedraw.com/"&gt;Shine Draw is an awesome “Flash vs Silverlight” repository&lt;/a&gt; that can show you how to do an event in either technology.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://silverlight.net/"&gt;Silverlight.net&lt;/a&gt; has an abundance of information.&amp;#160; They also have &lt;a href="http://silverlight.net/community/samples/silverlight-samples"&gt;Community Samples&lt;/a&gt; as well.&lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9922257" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Getting+Started/default.aspx">Getting Started</category></item><item><title>Coding4Fun at PDC!</title><link>http://blogs.msdn.com/coding4fun/archive/2009/11/17/9923716.aspx</link><pubDate>Tue, 17 Nov 2009 18:09:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9923716</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9923716.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9923716</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9923716</wfw:comment><description>&lt;p&gt;Coding4Fun is in attendance at the Microsoft Professional Developer Conference!&amp;#160; We are demoing 5 projects that will have full how-to’s and will be open-sourced as well.&amp;#160; Drinktendr, Mind Blaster, Laser Graffiti, Augmented Reality, and Wi-Fi Warthogs are powered by .Net, XNA, WPF, Ling2Sql, WiiMote, MSMQ, Power Wheels, a Mind Set and a giant freaking laser!&lt;/p&gt;  &lt;h3&gt;Drinktendr&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4372.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="IMG_4372" border="0" alt="IMG_4372" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4372_thumb.jpg" width="240" height="160" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Ever get tired of pouring your own drink?&amp;#160; Have someone get upset at you since it was too strong or too weak?&amp;#160; Well, why not have a machine pour you the perfect beverage every time!&amp;#160; Drinktendr uses Linq2Sql and SQL Server to know what drinks it can make with what is on hand.&amp;#160; Combine this with WPF; the end user is given a top end experience.&lt;/p&gt;  &lt;h3&gt;Mind Blaster&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4328.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="IMG_4328" border="0" alt="IMG_4328" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4328_thumb.jpg" width="240" height="160" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;With aliens threatening to invade Earth, it’s your job to travel into outer space and destroy the alien threat…with your mind!&amp;#160; Wearing a brainwave detecting headset, coupled with head tracking hardware using a wiimote, use only your brain to destroy alien ships before they destroy you and the rest of humanity.&lt;/p&gt;  &lt;h3&gt;Laser Graffiti&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4323.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="IMG_4323" border="0" alt="IMG_4323" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4323_thumb.jpg" width="240" height="160" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Putting graffiti on something is not a very nice thing to do but what if with a flick of a switch, it was gone.&amp;#160; With a projector, an off the shelf webcam and a laser pointer, you can do just that.&amp;#160; Aim the laser at the building and start drawing.&amp;#160; Turn off the laser and it all goes away!&amp;#160; Using WPF and XNA, we can apply a variety of effects including fire, paint, and various particles.&amp;#160; This project was influenced by the Graffiti Research Lab.&lt;/p&gt;  &lt;h3&gt;Augmented Reality&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4340.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="IMG_4340" border="0" alt="IMG_4340" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4340_thumb.jpg" width="240" height="160" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We’ll be showing off two AR games.&amp;#160; ARroller and AR Domino Knockdown. ARroller is a single-player “marble game” experienced through a 3DOF-tracked video–see-through head-worn display. The player holds a tracked board on which a virtual marble must be manipulated through a maze of obstacles by tilting and moving the board. AR Domino Knockdown is a two-player first-person-shooter. Players hold 6DOF-tracked UMPCs through which they fire virtual balls at a configuration of virtual dominos on a shared table.&lt;/p&gt;  &lt;h3&gt;Wi-Fi Warthogs&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4311.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="IMG_4311" border="0" alt="IMG_4311" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Coding4FunatPDC_8947/IMG_4311_thumb.jpg" width="240" height="160" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Go big or go home.&amp;#160; After seeing Halo, we decided we had to make some remote control wart hogs to play laser tag with.&amp;#160; Using Xbox controllers, a wireless network, and Power Wheel cars, we’ve made a game of laser tag like no other.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923716" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/hardware/default.aspx">hardware</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/XNA/default.aspx">XNA</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/wiimote/default.aspx">wiimote</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/PDC/default.aspx">PDC</category></item><item><title>XNA Role Playing Game (RPG) Starter Kit</title><link>http://blogs.msdn.com/coding4fun/archive/2009/11/16/9922196.aspx</link><pubDate>Mon, 16 Nov 2009 20:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9922196</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9922196.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9922196</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9922196</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/charlie/archive/2009/09/27/xna-role-playing-game.aspx"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="Figure04-WorldMap_2[1]" border="0" alt="Figure04-WorldMap_2[1]" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/XNARolePlayingGameRPGStarterKit_B013/Figure04-WorldMap_2%5B1%5D_39a576b6-43dd-4aa2-aa5b-1f0fe4674485.png" width="240" height="140" /&gt; Charlie Calvert has created great post&lt;/a&gt; covering the &lt;a href="http://creators.xna.com/en-US/starterkit/roleplayinggame"&gt;XNA Role Playing Game Starter Kit from the XNA team&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Charlie talks about the tile engine and the quest engine.&amp;#160; The tile engine supports several layers to create a complex final level.&amp;#160; The first layer allows you to define a basic landscape or the interior of a building. A second layer allows you to decorate it with trees, chairs, or other objects. A third layer contains your sprites, and a fourth layer defines the boundaries inside which the sprites can move.&lt;/p&gt;  &lt;p&gt;The downloads for the &lt;a href="http://creators.xna.com/en-US/starterkit/roleplayinggame"&gt;RGP Starter Kit&lt;/a&gt; are broken out into versions for XNA Game Studio 2.0 and 3.0. There is also a distinction between code that targets Windows and code for the XBox:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://creators.xna.com/downloads/?id=220"&gt;For XNA Game Studio 3.0 Windows&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://creators.xna.com/downloads/?id=221"&gt;For XNA Game Studio 3.0 XBox 360&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://creators.xna.com/downloads/?id=83"&gt;For XNA Game Studio 2.0 Windows&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://creators.xna.com/downloads/?id=84"&gt;For XNA Game Studio 2.0 XBox 360&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Here are some additional links&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://creators.xna.com/en-US/starterkit/roleplayinggame"&gt;Home page and some documentation&lt;/a&gt; for the starter kit. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://forums.xna.com/forums/t/11880.aspx"&gt;Forum thread for discussing the kit&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;Information on the &lt;a href="http://creators.xna.com/en-US/tutorial/roleplayinggametutorial1"&gt;quest engine&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;Information the the &lt;a href="http://creators.xna.com/en-US/tutorial/roleplayinggametutorial2"&gt;tile engine&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9922196" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/XNA/default.aspx">XNA</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Getting+Started/default.aspx">Getting Started</category></item><item><title>Facebook SDK</title><link>http://blogs.msdn.com/coding4fun/archive/2009/11/11/9920962.aspx</link><pubDate>Wed, 11 Nov 2009 18:26:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9920962</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9920962.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9920962</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9920962</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/FacebookSDK_92C5/facebook_logo%5B1%5D_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="facebook_logo[1]" border="0" alt="facebook_logo[1]" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/FacebookSDK_92C5/facebook_logo%5B1%5D_thumb.png" width="240" height="240" /&gt;&lt;/a&gt;Microsoft just released a Facebo ok client library to help make it easier for everyone to create some interesting applications.&amp;#160; The SDK is broken into a few core DLLs, each serving a core purpose.&amp;#160; You can download the SDK from &lt;a title="Download the SDK" href="http://facebooktoolkit.codeplex.com/"&gt;Download the SDK&lt;/a&gt;.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Facebook.dll&lt;/strong&gt;: This is the main assembly that will be used by all applications. This has all the logic to handle communication with the Facebook application. This assembly also has specific support of XAML applications (Silverlight and WPF) to enhance the Facebook platform to make databinding and data caching easier. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Facebook.Silverlight.dll&lt;/strong&gt;: This is the Silverlight version of the main assembly that will be used by all Silverlight applications. This has all the logic to handle communication with the Facebook application. This assembly also has specific support of XAML applications to enhance the Facebook platform to make databinding and data caching easier. The REST API in this assembly is Asynchronous only. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Facebook.Web.dll&lt;/strong&gt;: This assembly should be used by Canvas applications. The main functionality supported in this assembly is to encapsulate the handshake between the Facebook application and a canvas application (both FBML and IFrame) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Facebook.Web.Mvc.dll&lt;/strong&gt;: Provide a support building canvas applications using ASP.NET MVC. Separated from Facebook.Web.dll to avoid all developers from needing to install the MVC bits. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Facebook.Winforms.dll&lt;/strong&gt;: This assembly provides support for writing Facebook applications using Winform technology. This provides a Component that wraps the API to make it easier to use from Winforms. This also contains some user controls to help display Facebook data easily.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;If you want some helpful starting points, the Facebook Developer Wiki has some help too.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://wiki.developers.facebook.com/index.php/Anatomy_of_a_Facebook_App"&gt;Anatomy_of_a_Facebook_App&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://wiki.developers.facebook.com/index.php/Platform_Core_Components"&gt;Platform_Core_Components&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://wiki.developers.facebook.com/index.php/How-to_Guides"&gt;How-to_Guides&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://wiki.developers.facebook.com/index.php/Creating_a_Platform_Application"&gt;Creating_a_Platform_Application&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9920962" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Facebook/default.aspx">Facebook</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/ASP.Net+MVC/default.aspx">ASP.Net MVC</category></item><item><title>Does the S in SQL stand for Scary?</title><link>http://blogs.msdn.com/coding4fun/archive/2009/11/09/9919667.aspx</link><pubDate>Mon, 09 Nov 2009 17:54:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9919667</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9919667.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9919667</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9919667</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/DoestheSinSQLstandforScary_8B3B/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/DoestheSinSQLstandforScary_8B3B/image_thumb.png" width="240" height="138" /&gt;&lt;/a&gt; Nope, it stands for structured actually.&amp;#160; But if you are a bit afraid of SQL, MSDev.com has &lt;a href="http://www.msdev.com/Directory/SeriesDescription.aspx?CourseId=124"&gt;20 how-to videos about SQL Server 2008 Express&lt;/a&gt;!&amp;#160; This series of short how-to-videos will touch on SQL Server Express 2008 features such as: how to backup a SQL Express database, how to backup a remote SQL Express database, how to restore a SQL Express database, how to update SQL Server Express 2005 to SQL Server Express 2008 and more.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9919667" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/starter+kit/default.aspx">starter kit</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/SQL/default.aspx">SQL</category></item><item><title>Halloween Gremlins</title><link>http://blogs.msdn.com/coding4fun/archive/2009/10/31/9915768.aspx</link><pubDate>Sun, 01 Nov 2009 01:37:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9915768</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9915768.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9915768</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9915768</wfw:comment><description>&lt;p&gt;This article describes a quick and easy application to play Halloween tricks on the PC.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="157"&gt;         &lt;p&gt;Randall Maas&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="481"&gt;         &lt;p&gt;&lt;b&gt;Run It:&lt;/b&gt; &lt;a href="http://gremlin.codeplex.com/Release/ProjectReleases.aspx"&gt;Download&lt;/a&gt;&lt;b&gt;              &lt;br /&gt;Code It:&lt;/b&gt; &lt;a href="http://gremlin.codeplex.com/SourceControl/ListDownloadableCommits.aspx"&gt;Download&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;b&gt;Difficulty:&lt;/b&gt; Intermediate             &lt;br /&gt;&lt;b&gt;Time Required:&lt;/b&gt; 4 hours             &lt;br /&gt;&lt;b&gt;Cost:&lt;/b&gt; Free!             &lt;br /&gt;&lt;b&gt;Software Needed:&lt;/b&gt; &lt;a href="http://www.microsoft.com/express/download/"&gt;Visual Basic or Visual C# Express&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/HalloweenGremlins_105FE/clip_image001_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/HalloweenGremlins_105FE/clip_image001_thumb.jpg" width="282" height="135" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;This article describes “Gremlin”, a quick and easy application that lets you play Halloween tricks. When your victim's computer is idle, Gremlin moves windows around on the screen, changes the focus window, moves your mouse, scrolls windows, and types nonsensical stuff. When there is background noise – like someone talking – it will shake the screen, even as your victim is typing away.&lt;/p&gt;  &lt;h3&gt;Deployment&lt;/h3&gt;  &lt;p&gt;&lt;b&gt;Run it right away&lt;/b&gt;. You can download, copy theGremlin.exe executable and NAudio.dll to the victim’s computer (say in c:\ directory), and then double click on the executable to run it.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Run it later.&lt;/b&gt; The other option is to copy the executable and dll files (or a shortcut to it) to the Startup folder on the victim's machine and watch the fun begin when they start up their machine in the morning!&lt;/p&gt;  &lt;p&gt;If the computer you're using runs on Windows XP the path is: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;C:\Documents and Settings\All Users\Start Menu\Programs\Startup&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;With Vista and Windows 7 the path looks like: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;C:\Users\&lt;i&gt;USERNAME&lt;/i&gt;\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Just remember to change &lt;i&gt;USERNAME&lt;/i&gt; to the name of the user on your machine.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h4&gt;Commandline&lt;/h4&gt;  &lt;p&gt;Gremlin is compiled as a windows application, so it won't popup a terminal window if you double click on it, etc. But you can run it from the command line with flags:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;-aggressive&lt;/b&gt; will make the gremlin's actions more obvious&lt;/p&gt;    &lt;p&gt;&lt;b&gt;-help&lt;/b&gt; will display the command line options&lt;/p&gt;    &lt;p&gt;&lt;b&gt;-name&lt;/b&gt; &lt;i&gt;NAME&lt;/i&gt; is useful for testing. Gremlin will only use windows with this specific title or from this specific application. (Remember to drop the &amp;quot;.exe&amp;quot; from the application filename)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;To stop the program, press CTRL+F2.&lt;/p&gt;  &lt;h3&gt;And now … the dodgy bits&lt;/h3&gt;  &lt;p&gt;The overall structure of the program is broken down into three kinds of functionality – actions, triggers and some interstitial glue:&lt;/p&gt;  &lt;p&gt;Actions&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The screen-shaker is a window that makes the monitor look like it is shaking. Sort of like a loose cable on the back of the monitor. &lt;/li&gt;    &lt;li&gt;A random event might kick the windows around—either friction will slow them down, or... &lt;/li&gt;    &lt;li&gt;Gremlin will type nonsensical messages from the keyboard. These messages are then sent from a virtual keyboard, or they: &lt;/li&gt;    &lt;li&gt;Move the mouse around, or &lt;/li&gt;    &lt;li&gt;Press the mouse buttons, or &lt;/li&gt;    &lt;li&gt;Randomly switch the focus to another window &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Triggers&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;An audio module listens for sounds that trigger the module that shakes your screen. &lt;/li&gt;    &lt;li&gt;Otherwise, the software uses a p/invoke to &lt;strong&gt;GetLastInputInfo()&lt;/strong&gt; and waits for the user to be idle for a minute or two. When it detects that the user is inactive, it randomly selects and carries out actions. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Other&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A hidden window receives key press events. I tend to reuse this module a lot, as a way to &lt;i&gt;stop&lt;/i&gt; experimental programs that may have made my machine unusable. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For fun, I’ll describe a couple of these modules below.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h4&gt;Screen shaker&lt;/h4&gt;  &lt;p&gt;My favorite bit is the screen shaker. It grabs a picture of the screens, creates a window that spreads across them, and then moves that image back and forth a few pixels every 30ms or so, with a little bit of random rotation. (Faster computers, of course, get a better effect).&lt;/p&gt;  &lt;p&gt;The screen shaker is special in four ways:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It is a top-level window – no other windows are allowed to go over it. &lt;/li&gt;    &lt;li&gt;This top-level window never becomes the focus window (the window that gets the keyboard events). &lt;/li&gt;    &lt;li&gt;Mouse button events (e.g. clicks and double-clicks) are passed through to the windows and desktop underneath. This gives the illusion that this is the &amp;quot;real&amp;quot; desktop shaking, by allowing a person to click on a button or text that passes the click thru to the &lt;i&gt;real&lt;/i&gt; button or text. &lt;/li&gt;    &lt;li&gt;It shakes each of the monitor's screens independently &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Some background: to create a window that looks like the shaking screen, I used two classes. The first is ScrShake (in ScreenShake.cs), which derives from the second class UnfocusableForm.&amp;#160; I’ll describe ScrShake first.&lt;/p&gt;  &lt;p&gt;The screen shaking process requires five instance variables:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;i&gt;animTimer&lt;/i&gt; is a System.Windows.Forms.Timer used to force painting of a new frame on the screen. &lt;/li&gt;    &lt;li&gt;&lt;i&gt;bx&lt;/i&gt;, and &lt;i&gt;by &lt;/i&gt;are how far the screen has shaken up or down, left or right. &lt;/li&gt;    &lt;li&gt;&lt;i&gt;angle &lt;/i&gt;is how much the screen has twisted during shaking. &lt;/li&gt;    &lt;li&gt;&lt;i&gt;screenBitmap&lt;/i&gt; is an array of bitmaps, one for each of the monitors. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This creates a window without a border or other trappings, then makes it the topmost window and sets a flag in the method variable ExStyle to ignore mouse clicks. More on this flag in a little while.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;C#      &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ScrShake : UnfocusableForm
{
   &lt;span class="kwrd"&gt;public&lt;/span&gt; ScrShake(&lt;span class="kwrd"&gt;double&lt;/span&gt; ShakeCoef, &lt;span class="kwrd"&gt;double&lt;/span&gt; AngleCoef) : &lt;span class="kwrd"&gt;base&lt;/span&gt;(&lt;span class="kwrd"&gt;true&lt;/span&gt;)
   {
      &lt;span class="kwrd"&gt;this&lt;/span&gt;.SuspendLayout();
      … other setup code …
      &lt;span class="rem"&gt;// This is needed since we're over the whole display, and we don't&lt;/span&gt;
      &lt;span class="rem"&gt;// want the other areas to be blurry&lt;/span&gt;
      TransparencyKey =  BackColor = ForeColor = System.Drawing.Color.Fuchsia;
      DoubleBuffered = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
      TopMost = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
      FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

      ClientSize = &lt;span class="kwrd"&gt;new&lt;/span&gt; System.Drawing.Size(300, 300);
      Name = &lt;span class="str"&gt;&amp;quot;topimage&amp;quot;&lt;/span&gt;;
      ResumeLayout(&lt;span class="kwrd"&gt;false&lt;/span&gt;);

      &lt;span class="rem"&gt;// This is need to pass mouse clicks thru to lower layers&lt;/span&gt;
      ExStyle |= (&lt;span class="kwrd"&gt;int&lt;/span&gt;) WS . EX_TRANSPARENT;

      … More code that will be described later…
   }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;When the timer has done a given number of animations, it will call the Stop() method. This will stop the animation, clean it up, and hide the window:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; Stop()
{
   animTimer . Stop();
   Hide();
   screenBitmap = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;When the main loops that start the animated screen shaking process, it calls the Screens() method. This grabs an image of the screens, determines the shape of each monitor, and starts the animation for 10 frames.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Screens()
{
   &lt;span class="kwrd"&gt;if&lt;/span&gt; (Visible)
   {
      Stop();
      &lt;span class="kwrd"&gt;return&lt;/span&gt; ;
   }
   &lt;span class="rem"&gt;// Grab the screens&lt;/span&gt;
   screenBitmap = Program.GrabScreens();
   CountDown = 10;

   animTimer.Start();
   angle = 0.0f;
   … code to display the window and get shape of monitors (see below)…
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;The screen capture portion is in ScreenCapture.cs. The method GrabScreens() creates an individual bitmap for each monitor and returns them as an array.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Screens()
{
   &lt;span class="kwrd"&gt;if&lt;/span&gt; (Visible)
   {
      Stop();
      &lt;span class="kwrd"&gt;return&lt;/span&gt; ;
   }
   &lt;span class="rem"&gt;// Grab the screens&lt;/span&gt;
   screenBitmap = Program.GrabScreens();
   CountDown = 10;

   animTimer.Start();
   angle = 0.0f;
   … code to display the window and get shape of monitors (see below)…
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;The code below determines the bounds of each screen and builds up a size of all of the screens put together. The window will be set to be this size. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;Screen[] AllScreens = Screen.AllScreens;

&lt;span class="rem"&gt;// full width/height of all monitors combined&lt;/span&gt;
Rectangle fullSize = AllScreens[0].Bounds;

&lt;span class="rem"&gt;// find a rectangle that will encompass all monitors on the system&lt;/span&gt;
&lt;span class="rem"&gt;// (assuming the primary monitor is on the left/top!)&lt;/span&gt;
&lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 1; i &amp;lt; AllScreens.Length &amp;amp;&amp;amp; i &amp;lt; screenBitmap.Length; i++)
{
    Rectangle Bounds = AllScreens[i].Bounds;

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (Bounds.Left &amp;lt; fullSize.Left)
        fullSize.X = Bounds.X;

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (Bounds.Right &amp;gt; fullSize.Right)
        fullSize.Width = Bounds.Right - fullSize.X;

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (Bounds.Top &amp;lt; fullSize.Top)
        fullSize.Y = Bounds.Y;

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (Bounds.Bottom &amp;gt; fullSize.Bottom)
        fullSize.Height = Bounds.Bottom - fullSize.Y;
}&lt;/pre&gt;

&lt;p&gt;The code to show the window, fill the whole screen, and move it to the top looks like:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;Show();
WindowState = FormWindowState.Normal;
&lt;span class="rem"&gt;// cover all monitors with one gigantic window&lt;/span&gt;
Location = &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(fullSize.Left, fullSize.Top);
Size = &lt;span class="kwrd"&gt;new&lt;/span&gt; Size(fullSize.Width, fullSize.Height);

&lt;span class="rem"&gt;// bring it to the top&lt;/span&gt;
BringToFront();&lt;/pre&gt;

&lt;p&gt;The constructor also created a timer that drives the screen shaking effect. The timer has a delegate that randomly selects the angle of rotation and the offset of the image, and triggers a repaint of the window. (The amount of shaking is controlled by two external variables called &lt;i&gt;AngleCoef&lt;/i&gt; and &lt;i&gt;ShakeCoef&lt;/i&gt;).&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;animTimer = &lt;span class="kwrd"&gt;new&lt;/span&gt; System.Windows.Forms.Timer();
animTimer.Tick += &lt;span class="kwrd"&gt;delegate&lt;/span&gt;(&lt;span class="kwrd"&gt;object&lt;/span&gt; A, EventArgs E)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (--CountDown &amp;lt; 1)
        Stop();

    angle += (&lt;span class="kwrd"&gt;float&lt;/span&gt;)((Program.Rnd.NextDouble() - 0.5) * AngleCoef);
    bx = (&lt;span class="kwrd"&gt;float&lt;/span&gt;)((Program.Rnd.NextDouble() - 0.5) * ShakeCoef);
    by = (&lt;span class="kwrd"&gt;float&lt;/span&gt;)((Program.Rnd.NextDouble() - 0.5) * ShakeCoef);
    Invalidate();
};

&lt;span class="rem"&gt;// Sets the timer interval to 30 milliseconds.&lt;/span&gt;
animTimer.Interval = 30;&lt;/pre&gt;

&lt;p&gt;Although each monitor shifts up &amp;amp; down, left &amp;amp; right by the same amount, and rotates by the same angle, they are painted independently. This gives the illusion that each monitor has a shaky image. Paint the window is using the following code. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnPaint(PaintEventArgs e)
{
    &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnPaint(e);
    Graphics g = e.Graphics;
    g.CompositingQuality = CompositingQuality.HighQuality;

    &lt;span class="rem"&gt;// for each monitor, draw the effect&lt;/span&gt;
    Screen[] AllScreens = Screen.AllScreens;
    &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; screenBitmap.Length; i++)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; == screenBitmap[i])&amp;#160;&amp;#160; &lt;span class="kwrd"&gt;continue&lt;/span&gt;;
        g.SmoothingMode = SmoothingMode.HighQuality;

        &lt;span class="rem"&gt;// grab the size of the current monitor&lt;/span&gt;
        Rectangle region = AllScreens[i].Bounds;

        &lt;span class="kwrd"&gt;double&lt;/span&gt; ImWidth = screenBitmap[i].Width  * &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e.Graphics.DpiX / screenBitmap[i].HorizontalResolution;
        &lt;span class="kwrd"&gt;double&lt;/span&gt; ImHeight= screenBitmap[i].Height * &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e.Graphics.DpiY / screenBitmap[i].VerticalResolution;
        Matrix m = &lt;span class="kwrd"&gt;new&lt;/span&gt; Matrix();
        m.Translate( (&lt;span class="kwrd"&gt;float&lt;/span&gt;)(- ImWidth  /2), 
                  (&lt;span class="kwrd"&gt;float&lt;/span&gt;)(- ImHeight /2), MatrixOrder.Append);

        &lt;span class="rem"&gt;// rotate the bitmap about the center&lt;/span&gt;
        m.RotateAt(angle, &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(0,0), MatrixOrder.Append);

        &lt;span class="rem"&gt;// center the image no matter what its size is&lt;/span&gt;
        m.Translate( region.Width /2 - bx, 
                  region.Height/2 - by, MatrixOrder.Append);

        &lt;span class="rem"&gt;// assign our transformation matrix&lt;/span&gt;
        g.Transform = m;

        &lt;span class="rem"&gt;// draw it&lt;/span&gt;
        g.DrawImage(screenBitmap[i], region.Left, region.Top);
    }&lt;/pre&gt;

&lt;h4&gt;The Form that does nothing!&lt;/h4&gt;

&lt;p&gt;The ScrShaker class uses a help class called UnfocusableForm (in UnfocusableForm.cs) to create a window that never becomes the focus window – it never receives key presses, etc.&lt;/p&gt;

&lt;p&gt;This window has no trappings – no border, no resize gripper, no icon, no minimize / maximize buttons, no title bar.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UnfocusableForm : Form
{
   &lt;span class="kwrd"&gt;public&lt;/span&gt; UnfocusableForm(&lt;span class="kwrd"&gt;bool&lt;/span&gt; X) : &lt;span class="kwrd"&gt;base&lt;/span&gt;()
   {
      &lt;span class="kwrd"&gt;if&lt;/span&gt; (X)
        {
           ControlBox = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
           FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
           ShowInTaskbar = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
           ShowIcon = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
           MinimizeBox = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
           SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
           StartPosition = System.Windows.Forms.FormStartPosition.Manual;
        }
   }&lt;/pre&gt;

&lt;p&gt;Then it overrides the ShowWithoutActivation method so that the window will &lt;i&gt;not&lt;/i&gt; become the active when it is shown.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; ShowWithoutActivation
{ get {  &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;; } }&lt;/pre&gt;

&lt;p&gt;The UnfocusableForm class also overrides the CreateParams() method to set extra styles when creating the window. I haven't found a way to set these styles flexibly. Instead, the UnfocusableForm uses a method variable called ExStyle that allows derived classes to specify what flags they desire. In this case, The ScrShake class used the method variable to set a flag that ignore mouse clicks:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; CreateParams CreateParams
{
  get
  {
     CreateParams cp=&lt;span class="kwrd"&gt;base&lt;/span&gt;.CreateParams;
     cp . ExStyle |= ExStyle;
     &lt;span class="kwrd"&gt;return&lt;/span&gt; cp;
  }
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;Finally, it captures a couple of events that ask a window if it would like to become the active window. (These usually happen when the user clicks on an inactive window):&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; MA_NOACTIVATE = 0x0003;
&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WndProc(&lt;span class="kwrd"&gt;ref&lt;/span&gt; Message m)
{
  &lt;span class="kwrd"&gt;if&lt;/span&gt; (m.Msg == (&lt;span class="kwrd"&gt;int&lt;/span&gt;) WM.MOUSEACTIVATE)
  {
     m.Result = (IntPtr) MA_NOACTIVATE;
     &lt;span class="kwrd"&gt;return&lt;/span&gt;;
  }
  &lt;span class="kwrd"&gt;if&lt;/span&gt; (m.Msg == (&lt;span class="kwrd"&gt;int&lt;/span&gt;) WM.FOCUS)
  {
     m.Result = (IntPtr)1;
     &lt;span class="kwrd"&gt;return&lt;/span&gt;;
  }
  &lt;span class="kwrd"&gt;base&lt;/span&gt;.WndProc(&lt;span class="kwrd"&gt;ref&lt;/span&gt; m);
}&lt;/pre&gt;

&lt;h4&gt;Sending Mouse Events&lt;/h4&gt;

&lt;p&gt;Sending Mouse Events is simple, but not trivial. The wiki at Pinvoke.net provides the signature to the procedures and structures we need to pass to it. (Note: these structures are a bit different, based on &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2009/08/13/9867383.aspx"&gt;a blog posting by Raymond Chen&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;[DllImport(&lt;span class="str"&gt;&amp;quot;user32.dll&amp;quot;&lt;/span&gt;, EntryPoint = &lt;span class="str"&gt;&amp;quot;SendInput&amp;quot;&lt;/span&gt;, SetLastError = &lt;span class="kwrd"&gt;true&lt;/span&gt;)]
&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;extern&lt;/span&gt; &lt;span class="kwrd"&gt;uint&lt;/span&gt; SendInput(&lt;span class="kwrd"&gt;uint&lt;/span&gt; nInputs, INPUT[] Inputs, &lt;span class="kwrd"&gt;int&lt;/span&gt; cbSize);
[DllImport(&lt;span class="str"&gt;&amp;quot;user32.dll&amp;quot;&lt;/span&gt;, EntryPoint = &lt;span class="str"&gt;&amp;quot;GetMessageExtraInfo&amp;quot;&lt;/span&gt;, SetLastError = &lt;span class="kwrd"&gt;true&lt;/span&gt;)]
&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;extern&lt;/span&gt; IntPtr GetMessageExtraInfo();

[StructLayout(LayoutKind.Sequential)]
&lt;span class="kwrd"&gt;struct&lt;/span&gt; INPUT
{
   &lt;span class="kwrd"&gt;internal&lt;/span&gt; INPUTTYPE   type;
   &lt;span class="kwrd"&gt;internal&lt;/span&gt; INPUT_UNION i;
}

 &lt;span class="rem"&gt;// This generates the anonymous union&lt;/span&gt;
[StructLayout(LayoutKind.Explicit)]
&lt;span class="kwrd"&gt;struct&lt;/span&gt; INPUT_UNION
{
   [FieldOffset(0)]
   &lt;span class="kwrd"&gt;public&lt;/span&gt; MOUSEINPUT mi;
   [FieldOffset(0)]
   &lt;span class="kwrd"&gt;public&lt;/span&gt; KEYBDINPUT ki;
   [FieldOffset(0)]
   &lt;span class="kwrd"&gt;public&lt;/span&gt; HARDWAREINPUT hi;
};

[StructLayout(LayoutKind.Sequential)]
&lt;span class="kwrd"&gt;struct&lt;/span&gt; MOUSEINPUT
{
   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;    dx;
   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;    dy;
   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;    mouseData;
   &lt;span class="kwrd"&gt;public&lt;/span&gt; MOUSEEVENTF dwFlags;
   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;    time;
   &lt;span class="kwrd"&gt;public&lt;/span&gt; IntPtr dwExtraInfo;
}

[Flags]
&lt;span class="kwrd"&gt;enum&lt;/span&gt; MOUSEEVENTF : &lt;span class="kwrd"&gt;int&lt;/span&gt;
{
   MOVE       = 0x01,
   LEFTDOWN   = 0x02,
   LEFTUP     = 0x04,
   RIGHTDOWN  = 0x08,
   RIGHTUP    = 0x10,
   MIDDLEDOWN = 0x20,
   MIDDLEUP   = 0x40,
   ABSOLUTE   = 0x8000
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Each of these pieces go together in a specific way. To do a mouse movement, a mouse event structure needs to be created. This involves setting dwFlags to the kind of mouse event (a relative movement in this case), dx and dy to the number of pixels moved. It is also important to set dwExtraInfo to whatever GetMessageExtraInfo() is set to.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;MOUSEINPUT MEvent = &lt;span class="kwrd"&gt;new&lt;/span&gt; MOUSEINPUT();
MEvent.dwFlags = MOUSEEVENTF.MOVE;
MEvent.dx = Rnd . Next(-8, 8) ;
MEvent.dy = Rnd . Next(-8, 8);
MEvent.dwExtraInfo = GetMessageExtraInfo();
Send(MEvent);&lt;/pre&gt;

&lt;p&gt;Sending the event takes a few more steps that are all wrapped in a helper methdo called Send(). Send these &lt;i&gt;human interface device&lt;/i&gt; events via the SendInput() procedure (earlier). The procedure takes an array of events, for different kinds of devices. We have to create the array, set the event type, copy the event data, and then make the call:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Send(MOUSEINPUT Event)
{
  INPUT[] Events = &lt;span class="kwrd"&gt;new&lt;/span&gt; INPUT[1];
  Events[0] . type = INPUTTYPE . MOUSE;
  Events[0] . i.mi = MEvent;
  &lt;span class="kwrd"&gt;return&lt;/span&gt; SendInput((&lt;span class="kwrd"&gt;uint&lt;/span&gt;)Events.Length, Events, Marshal.SizeOf(Events[0])) &amp;gt; 0; 
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;From here, sending a mouse button click is pretty straight forward. A mouse click is really a mouse button press event, followed by a mouse button release event. To make things interesting the mouse button is choosen at random. The “ugly” part is that each of the mouse buttons is assigned a bit, so a binary shift is used to convert a button number to its bit. And the button release is yet another bit, so the second message shifts the flags, to move the bit from the “button pressed” state to the “button released state”.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;MOUSEINPUT MEvent = &lt;span class="kwrd"&gt;new&lt;/span&gt; MOUSEINPUT();
MEvent.dwFlags = (MOUSEEVENTF) (1 &amp;lt;&amp;lt; (2*Rnd.Next(0, 3)+1)) ;
MEvent.dwExtraInfo = GetMessageExtraInfo ();
Send(MEvent);

MEvent.dwFlags = (MOUSEEVENTF)((&lt;span class="kwrd"&gt;int&lt;/span&gt;) MEvent.dwFlags &amp;lt;&amp;lt; 1);
MEvent.dwExtraInfo = GetMessageExtraInfo ();
Send(MEvent);&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;h4&gt;Generating deranged text&lt;/h4&gt;

&lt;p&gt;The gremlin can also type deranged sentences that will appear in editors, if the user left one open. The SendWait() method in the SendKeys class does the typing itself:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C#&lt;/b&gt;&amp;#160;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;SendKeys . SendWait(GenerateSentence());
SendKeys . SendWait(&lt;span class="str"&gt;&amp;quot;{ENTER}&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/HalloweenGremlins_105FE/clip_image001%5B6%5D.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image001[6]" border="0" alt="clip_image001[6]" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/HalloweenGremlins_105FE/clip_image001%5B6%5D_thumb.jpg" width="282" height="135" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generating the sentences is not difficult; I used a simplistic Markov generator. This generator starts by randomly selecting a word that can start a sentence. The &lt;i&gt;Starts&lt;/i&gt; variable is array which holds just these words. Then, in the Transition method, this word is used to find the &lt;i&gt;next&lt;/i&gt; word that can be included in the sentence. It does this by using a dictionary, called &lt;i&gt;NonStart&lt;/i&gt;, which given the word as a key, will return a list of all the words that can come after it. This process then repeats, appending the words onto the end of a string. It stops if it finds a word that can end a sentence.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;,&lt;span class="kwrd"&gt;string&lt;/span&gt;[]&amp;gt; NonStart ;
&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] Starts;
&lt;span class="kwrd"&gt;static&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;,&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Terminal ;

&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GenerateSentence()
{
  StringBuilder SB = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();
  &lt;span class="kwrd"&gt;string&lt;/span&gt; Word = Starts[ Rnd.Next(0, Starts.Length) ];

  Transition(SB, Word);
  &lt;span class="kwrd"&gt;return&lt;/span&gt; SB.ToString();
}

&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Transition(StringBuilder SB, &lt;span class="kwrd"&gt;string&lt;/span&gt; Word)
{
  &lt;span class="kwrd"&gt;while&lt;/span&gt; (&lt;span class="kwrd"&gt;true&lt;/span&gt;)
  {
     SB.Append(Word);
     SB.Append(&lt;span class="str"&gt;' '&lt;/span&gt;);

     &lt;span class="rem"&gt;// Look up word after this&lt;/span&gt;
     &lt;span class="kwrd"&gt;string&lt;/span&gt;[] Nexts;
     &lt;span class="kwrd"&gt;if&lt;/span&gt; (!NonStart.TryGetValue(Word, &lt;span class="kwrd"&gt;out&lt;/span&gt; Nexts))
       &lt;span class="kwrd"&gt;break&lt;/span&gt;;
     &lt;span class="kwrd"&gt;int&lt;/span&gt; Idx = Rnd.Next(Terminal . ContainsKey(Word) ? -1 :0, Nexts.Length);
     &lt;span class="kwrd"&gt;if&lt;/span&gt; (Idx &amp;lt; 0)
       &lt;span class="kwrd"&gt;break&lt;/span&gt;;
     Word = Nexts[Idx];
  }
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Building these two dictionaries and array is a pretty simple process. The BuildSuffixTree() method takes a string and splits it up into sentences. Then it splits each sentence into (lower case) words. The first word of the sentence goes onto the end of the &lt;i&gt;Starts&lt;/i&gt; array. Otherwise, the previous word is used to look up a list in a dictionary, and the current word is appended on to the list. This dictionary will become the &lt;i&gt;NonStarts&lt;/i&gt; dictionary. The last word of the sentence is also placed into the &lt;i&gt;Terminal&lt;/i&gt; dictionary, to indicate that this might be the end of a sentence.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; BuildSuffixTree()
{
  &lt;span class="rem"&gt;// First, build up a list of words that start sentence, and transitions&lt;/span&gt;
  List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Starts1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();
  Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;,List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; Trans = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;,List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;();
  &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; S1 &lt;span class="kwrd"&gt;in&lt;/span&gt; S.Split(&lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;char&lt;/span&gt;[]{&lt;span class="str"&gt;'.'&lt;/span&gt;,&lt;span class="str"&gt;'?'&lt;/span&gt;,&lt;span class="str"&gt;'!'&lt;/span&gt;}))
  {
     &lt;span class="kwrd"&gt;string&lt;/span&gt; Prev=&lt;span class="kwrd"&gt;null&lt;/span&gt;;
     &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; S2 &lt;span class="kwrd"&gt;in&lt;/span&gt; S1.Split(&lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;char&lt;/span&gt;[]{&lt;span class="str"&gt;' '&lt;/span&gt;,&lt;span class="str"&gt;'\n'&lt;/span&gt;,&lt;span class="str"&gt;'\r'&lt;/span&gt;,&lt;span class="str"&gt;'\t'&lt;/span&gt;,&lt;span class="str"&gt;','&lt;/span&gt;,&lt;span class="str"&gt;';'&lt;/span&gt;}))
     {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (S2 . Length &amp;lt; 1)
          &lt;span class="kwrd"&gt;continue&lt;/span&gt;;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; == Prev)
          {
             Starts1.Add(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Intern(S2.ToLower()));
             Prev = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Intern(S2.ToLower());
             &lt;span class="kwrd"&gt;continue&lt;/span&gt;;
          }
        List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; Nextsa;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (! Trans.TryGetValue(Prev, &lt;span class="kwrd"&gt;out&lt;/span&gt; Nextsa))
          Trans[Prev] = Nextsa = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();
        Prev = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Intern(S2.ToLower());
        Nextsa.Add(Prev);
     }
     &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != Prev)
       Terminal[Prev] = Prev;
 }

 &lt;span class="rem"&gt;// Next, flatten the list of words that start a sentence&lt;/span&gt;
 Starts = Starts1.ToArray();

 &lt;span class="rem"&gt;// Flatten the transition table&lt;/span&gt;
 &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; S3 &lt;span class="kwrd"&gt;in&lt;/span&gt; Trans.Keys)
  NonStart[S3] = Trans [S3].ToArray();
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;h3&gt;The things that trigger action&lt;/h3&gt;

&lt;h4&gt;The audio trigger&lt;/h4&gt;

&lt;p&gt;The audio module (in file AudioTrigger.cs) listens in on all of the microphones. It uses NAudio, with a basic setup and delegate structure swiped from Mark Heath’s article “.NET Audio Recording”. The first difference is that it registers &lt;i&gt;all&lt;/i&gt; audio input devices:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; WaveIn[] StartMics()
{
  &lt;span class="kwrd"&gt;int&lt;/span&gt; NumDevices = WaveIn.DeviceCount;
  WaveIn[] AudIns = &lt;span class="kwrd"&gt;new&lt;/span&gt; WaveIn[NumDevices];
  &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; waveInDevice = 0; waveInDevice &amp;lt; NumDevices ; waveInDevice++)
  {
     AudIns[waveInDevice] = &lt;span class="kwrd"&gt;new&lt;/span&gt; WaveIn();
     AudIns[waveInDevice].DeviceNumber = waveInDevice;
     AudIns[waveInDevice].DataAvailable += waveIn_DataAvailable;
     AudIns[waveInDevice].WaveFormat = &lt;span class="kwrd"&gt;new&lt;/span&gt; WaveFormat(8000, 1);
     AudIns[waveInDevice].StartRecording();
  }
  &lt;span class="kwrd"&gt;return&lt;/span&gt; AudIns;
}&lt;/pre&gt;

&lt;p&gt;The real magic in the trigger is a modified version of the waveIn_DataAvailable delegate. Instead of saving the audio, it checks for any sound activity. It starts by checking to see if any of the sound amplitudes are greater than a pre-defined, very high threshold. Then the samples are squared and summed up, and the result is compared with a threshold. If it exceeds the threshold, the trigger is set. These two are good at catching the kind of sound made when a person is talking, futzing on the desk, or typing.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/HalloweenGremlins_105FE/clip_image002_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/HalloweenGremlins_105FE/clip_image002_thumb.jpg" width="372" height="210" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; AudioThresh  = 0.8;
&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; AudioThresh2 = 0.09;

&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; waveIn_DataAvailable(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, WaveInEventArgs e)
{
  &lt;span class="kwrd"&gt;bool&lt;/span&gt; Tr = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
  &lt;span class="kwrd"&gt;double&lt;/span&gt; Sum2  = 0;
  &lt;span class="kwrd"&gt;int&lt;/span&gt; Count = e.BytesRecorded / 2;
  &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; index = 0; index &amp;lt; e.BytesRecorded; index += 2)
  {
     &lt;span class="kwrd"&gt;double&lt;/span&gt; Tmp = (&lt;span class="kwrd"&gt;short&lt;/span&gt;)((e.Buffer[index + 1] &amp;lt;&amp;lt; 8) | e.Buffer[index + 0]);
     Tmp /= 32768.0;
     Sum2 += Tmp*Tmp;
     &lt;span class="kwrd"&gt;if&lt;/span&gt; (Tmp &amp;gt; AudioThresh)
       Tr = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
  }
  Sum2 /= Count;

  &lt;span class="rem"&gt;// If the Mean-Square is greater than a threshold, set a flag to indicate that noise has happened&lt;/span&gt;
  &lt;span class="kwrd"&gt;if&lt;/span&gt; (Tr || Sum2 &amp;gt; AudioThresh2)
    Interlocked.Exchange(&lt;span class="kwrd"&gt;ref&lt;/span&gt; AudioTrigger, 1);
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;This sets a flag – AudioTrigger – which will be seen (and reset) in the main loop, with a bit of code that looks like:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;while&lt;/span&gt; (0 == Shutdown)
{
    &lt;span class="rem"&gt;// Do some lovely events&lt;/span&gt;
    Application . DoEvents();
    Thread . Sleep (20);

    &lt;span class="rem"&gt;//… do some other stuff ..&lt;/span&gt;

    &lt;span class="rem"&gt;// Check for a kick from the sound system&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (0 != AudioTrigger)
    {
        Interlocked . Exchange(&lt;span class="kwrd"&gt;ref&lt;/span&gt; AudioTrigger, 0);
        …
        ScreenShaker . Screens();
        &lt;span class="kwrd"&gt;continue&lt;/span&gt;;
    }
    &lt;span class="rem"&gt;//… more checks for the user idle trigger…&lt;/span&gt;
}&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/pre&gt;

&lt;h4&gt;Waiting for the user to be idle&lt;/h4&gt;

&lt;p&gt;The check to see if the user is not doing anything, the main loop uses a helper method called LastInputTime(), which returns the number of milliseconds the user did any input activity. The loop ensures that the user has been idle for long enough, and then calls the method that selects random gremlin actions:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;uint&lt;/span&gt; LastTime = Win32.LastInputTime();
&lt;span class="kwrd"&gt;if&lt;/span&gt; ((&lt;span class="kwrd"&gt;uint&lt;/span&gt;) Environment.TickCount &amp;lt; IdleTimeTrigger + LastTime)
    &lt;span class="kwrd"&gt;continue&lt;/span&gt;;&lt;/pre&gt;

&lt;p&gt;The LastInputTime() helper method uses a p/invoke call to the GetLastInputInfo() API call. The wiki at Pinvoke.net provides the signature to the procedure, and a suitable structure that we need to pass to it:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;[DllImport(&lt;span class="str"&gt;&amp;quot;User32.dll&amp;quot;&lt;/span&gt;)]
&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;extern&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; GetLastInputInfo(&lt;span class="kwrd"&gt;ref&lt;/span&gt; LASTINPUTINFO LastInfo);

[StructLayout(LayoutKind.Sequential)]
&lt;span class="kwrd"&gt;struct&lt;/span&gt; LASTINPUTINFO
{
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;uint&lt;/span&gt; cbSize;

  &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
  &lt;span class="rem"&gt;/// Number of system tickes&lt;/span&gt;
  &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;uint&lt;/span&gt; dwTime;
}&lt;/pre&gt;

&lt;p&gt;Then, these two structures are wrapped up into the LastInputTime() helper procedure, which does the dirty work of allocating and initializing a structure. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# &lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;uint&lt;/span&gt; LastInputTime()
{
  LASTINPUTINFO lastInput=&lt;span class="kwrd"&gt;new&lt;/span&gt; LASTINPUTINFO();
  lastInput.cbSize = (&lt;span class="kwrd"&gt;uint&lt;/span&gt;)Marshal.SizeOf(lastInput);
  GetLastInputInfo(&lt;span class="kwrd"&gt;ref&lt;/span&gt; lastInput);
  &lt;span class="kwrd"&gt;return&lt;/span&gt; lastInput . dwTime;
}&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/pre&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;The tricks gremlin plays are intended to be somewhat subtle. There is an aggressive option to make it react more, and move windows around more visibly. &lt;/p&gt;

&lt;p&gt;If you want to try this out, the download link for the &lt;a href="http://gremlin.codeplex.com/Release/ProjectReleases.aspx"&gt;executable&lt;/a&gt; and &lt;a href="http://gremlin.codeplex.com/SourceControl/ListDownloadableCommits.aspx"&gt;source code&lt;/a&gt; are at the top of the article!&lt;/p&gt;

&lt;h4&gt;Resources and References&lt;/h4&gt;

&lt;p&gt;This article is a blatant grab bag of experimental and reused code from earlier experiments and other demo programs. Below are some of the projects I lifted code examples from:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://pinvoke.net/"&gt;Pinvoke.net&lt;/a&gt; – a wiki-style site with many useful bits of example code related to calling the Windows API from within .NET. &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blogs.msdn.com/coding4fun/archive/2009/10/08/9905168.aspx"&gt;“.NET Audio Recorder”&lt;/a&gt; by Mark Heath, from which I stole code to make the audio trigger. &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blogs.msdn.com/coding4fun/archive/2007/10/29/5773776.aspx"&gt;“Possessed PC Pranks for Halloween”&lt;/a&gt; by Brian Peek, from which I stole the basic code for sending keystrokes. &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://blogs.msdn.com/coding4fun/archive/2007/03/29/1991785.aspx"&gt;“April Fools’ Day Application”&lt;/a&gt; by Brian Peek, from which I stole code to grab the screen and rotate it. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;About The Author&lt;/h3&gt;

&lt;p&gt;Randall Maas writes firmware for medical devices, and consults in embedded software. Before that he did a lot of other things… like everyone else in the software industry. You can contact him at &lt;a href="mailto:randym@acm.org"&gt;randym@acm.org&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9915768" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/halloween/default.aspx">halloween</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/holiday/default.aspx">holiday</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Audio/default.aspx">Audio</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Pranks/default.aspx">Pranks</category></item><item><title>wpf text blurry blues?</title><link>http://blogs.msdn.com/coding4fun/archive/2009/10/29/9914968.aspx</link><pubDate>Thu, 29 Oct 2009 21:48:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9914968</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9914968.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9914968</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9914968</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/wpftextblurryblues_D056/wpf4text_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="wpf4text" border="0" alt="wpf4text" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/wpftextblurryblues_D056/wpf4text_thumb.png" width="479" height="177" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Have you hated how WPF has blurry text depending on what happens?&amp;#160; Well, .Net 4.0 and WPF 4.0 fixes that.&amp;#160; If you try out a version after Visual Studio 2010 beta 2, you can use these fixes as well.&amp;#160; The MSDN &lt;a href="http://blogs.msdn.com/text/archive/2009/08/24/wpf-4-0-text-stack-improvements.aspx"&gt;Text blog outlines how to fix your text and the why / how of some of the blurriness&lt;/a&gt;.&amp;#160; A lot comes from display screens not having a high enough DPI and subpixel rendering.&amp;#160; But enough excuses and how can you fix it?&amp;#160; Here is an example of how to do the look of the picture above.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        Hello World ...  Ideal text formatting
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt; &lt;span class="attr"&gt;TextOptions&lt;/span&gt;.&lt;span class="attr"&gt;TextFormattingMode&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Display&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        Hello World ... Display text formatting
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;TextBlock&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;StackPanel&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span class="kwrd"&gt;The blog posting talks about additional settings as well.&lt;/span&gt;&lt;/p&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9914968" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category></item><item><title>Getting Loopy</title><link>http://blogs.msdn.com/coding4fun/archive/2009/10/26/9913286.aspx</link><pubDate>Tue, 27 Oct 2009 01:56:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9913286</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9913286.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9913286</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9913286</wfw:comment><description>&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/GettingLoopy_10A5B/fruit_loops1%5B1%5D_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/GettingLoopy_10A5B/fruit_loops1%5B1%5D_2.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: 0px" title=fruit_loops1[1] border=0 alt=fruit_loops1[1] align=right src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/GettingLoopy_10A5B/fruit_loops1%5B1%5D_thumb.jpg" width=230 height=172 mce_src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/GettingLoopy_10A5B/fruit_loops1%5B1%5D_thumb.jpg"&gt;&lt;/A&gt;Over at the Visual Basic blog, &lt;A href="http://blogs.msdn.com/vbteam/archive/2009/10/07/getting-loopy-matt-gertz.aspx" mce_href="http://blogs.msdn.com/vbteam/archive/2009/10/07/getting-loopy-matt-gertz.aspx"&gt;Matt Gertz has a great post on hidden effects with loops on stuff you may not realize&lt;/A&gt;.&amp;nbsp; He talks about how looping backwards versus forwards depending on the situation will drastically simplify your code or if you’re looping and using the array.Count how the Count property will be called on every pass.&lt;/P&gt;
&lt;P&gt;Matt also has &lt;A href="http://blogs.msdn.com/vbteam/archive/2009/10/06/hidden-costs-matt-gertz.aspx" mce_href="http://blogs.msdn.com/vbteam/archive/2009/10/06/hidden-costs-matt-gertz.aspx"&gt;another article about additional hidden costs too that is an interesting, quick read&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9913286" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Coding/default.aspx">Coding</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Visual+Basic/default.aspx">Visual Basic</category></item><item><title>Visual Studio 2010 Beta 2 released!</title><link>http://blogs.msdn.com/coding4fun/archive/2009/10/21/9910949.aspx</link><pubDate>Wed, 21 Oct 2009 21:56:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9910949</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9910949.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9910949</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9910949</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/VisualStudio2010Beta2released_D06C/logo_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="logo" border="0" alt="logo" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/VisualStudio2010Beta2released_D06C/logo_thumb.jpg" width="500" height="135" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You guys want to try out the newest and greatest Visual Studio Express?&amp;#160; The Visual Studio team just released VS 2010 Beta 2 for everyone to try out.&amp;#160; It should be out in March, 2010 for the full version as well.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Visual Basic     &lt;br /&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkID=167868"&gt;http://go.microsoft.com/fwlink/?LinkID=167868&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Visual C++     &lt;br /&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkID=167871"&gt;http://go.microsoft.com/fwlink/?LinkID=167871&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Visual C#     &lt;br /&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkID=167872"&gt;http://go.microsoft.com/fwlink/?LinkID=167872&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Visual Web Designer     &lt;br /&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkID=167874"&gt;http://go.microsoft.com/fwlink/?LinkID=167874&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;ISO with all 4 (Offline installer)     &lt;br /&gt;&lt;a href="http://go.microsoft.com/fwlink/?LinkID=167878"&gt;http://go.microsoft.com/fwlink/?LinkID=167878&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This is beta so be warned.&amp;#160; If you do have an issue, please comment / send feedback to the team so they can be resolved.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9910949" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Beta/default.aspx">Beta</category></item><item><title>The Coding4Fun Show: WPF MediaKit with Jeremiah Morrill</title><link>http://blogs.msdn.com/coding4fun/archive/2009/10/19/9909155.aspx</link><pubDate>Mon, 19 Oct 2009 16:04:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9909155</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9909155.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9909155</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9909155</wfw:comment><description>&lt;object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="500" height="375"&gt; &lt;param name="source" value="http://channel9.msdn.com/App_Themes/default/vp09_06_22.xap" /&gt; &lt;param name="initParams" value="m=http://ecn.channel9.msdn.com/o9/ch9/8/8/8/9/9/4/C4FShowE4Morrill_2MB_ch9.wmv,autostart=false,autohide=true,showembed=true, thumbnail=http://ecn.channel9.msdn.com/o9/ch9/8/8/8/9/9/4/C4FShowE4Morrill_320_ch9.png, postid=499888" /&gt; &lt;param name="background" value="#00FFFFFF" /&gt; &lt;a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"&gt; &lt;img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none" /&gt; &lt;/a&gt; &lt;/object&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px"&gt;In this episode of the &lt;a href="http://channel9.msdn.com/shows/Coding4FunTV/"&gt;Coding4Fun Show&lt;/a&gt;, &lt;a href="http://www.brianpeek.com/"&gt;Brian Peek&lt;/a&gt; interviews &lt;a href="http://jmorrill.hjtcentral.com/"&gt;Jeremiah Morrill&lt;/a&gt; who has written &lt;a href="http://wpfmediakit.codeplex.com/"&gt;WPF MediaKit&lt;/a&gt;, an amazing library to quickly build DirectShow and MediaFoundation media player controls in WPF.&amp;#160; It's amazingly powerful and, as a developer, can be used with just a few lines of XAML.&amp;#160; In fact, you can create a full-blown DVD player or webcam capture control in your application each with a single XAML tag!&amp;#160; Learn all about this great project, how it was written, and how to use it in your own creations.&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9909155" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Coding4Fun+TV/default.aspx">Coding4Fun TV</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category></item><item><title>XNA and textures</title><link>http://blogs.msdn.com/coding4fun/archive/2009/10/16/9908356.aspx</link><pubDate>Fri, 16 Oct 2009 20:11:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9908356</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9908356.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9908356</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9908356</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/XNAandtextures_B984/clip_image001_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="clip_image001" border="0" alt="clip_image001" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/XNAandtextures_B984/clip_image001_thumb.png" width="185" height="180" /&gt;&lt;/a&gt;Looking for some XNA help? &lt;a href="http://blogs.msdn.com/shawnhar/"&gt;Shawn Hargreaves’s blog&lt;/a&gt; has a bunch of answers questions like anisotropic filtering, mipmapping, and texture filtering.&lt;/p&gt;  &lt;p&gt;If you’re not sure what mipmapping is, it is precalculating a copy of an image that is smaller than the original. This way you control the rendering rather than having it computed on the fly!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9908356" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/XNA/default.aspx">XNA</category></item><item><title>.NET Voice Recorder</title><link>http://blogs.msdn.com/coding4fun/archive/2009/10/08/9905168.aspx</link><pubDate>Fri, 09 Oct 2009 00:29:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9905168</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9905168.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9905168</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9905168</wfw:comment><description>&lt;p&gt;In this article I demonstrate how to record from the microphone in .NET, with support for setting the recording level, trimming noise from the start and end, visualizing the waveform in WPF and converting to MP3.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="282"&gt;         &lt;p&gt;Mark Heath            &lt;br /&gt;&lt;a title="http://mark-dot-net.blogspot.com/" href="http://mark-dot-net.blogspot.com/"&gt;http://mark-dot-net.blogspot.com/&lt;/a&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="356"&gt;         &lt;p&gt;&lt;b&gt;Code It:&lt;/b&gt; &lt;a href="http://voicerecorder.codeplex.com"&gt;Download&lt;/a&gt;&lt;strong&gt;              &lt;br /&gt;Run It:&lt;/strong&gt; &lt;a href="http://voicerecorder.codeplex.com/Release/ProjectReleases.aspx"&gt;Download&lt;/a&gt;&lt;/p&gt;          &lt;p&gt;&lt;b&gt;Difficulty:&lt;/b&gt; Intermediate             &lt;br /&gt;&lt;b&gt;Time Required:&lt;/b&gt; 8 hours             &lt;br /&gt;&lt;b&gt;Cost:&lt;/b&gt; Free!             &lt;br /&gt;&lt;b&gt;Software Needed:&lt;/b&gt; &lt;a href="http://www.microsoft.com/express/download/"&gt;Visual Basic or Visual C# Express&lt;/a&gt;, &lt;a href="http://www.bing.com/search?q=lame.exe"&gt;Lame&lt;/a&gt; (Optional)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;h2&gt;Audio Recording in .NET&lt;/h2&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;p&gt;The .NET framework does not provide any direct support for recording audio, so I will make use of the open source &lt;a href="http://naudio.codeplex.com"&gt;NAudio&lt;/a&gt; project, which includes wrappers for a number of Windows audio recording APIs. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;It is important to point out that .NET is not an appropriate choice for high sample rate and &lt;i&gt;low latency&lt;/i&gt; audio recording, such as that found in Digital Audio Workstation software used in recording studios. This is because the .NET garbage collector can interrupt the process at any point. However, for purposes of recording speech from the microphone, the .NET framework is more than capable. By default, NAudio asks the soundcard to give us data every 100ms, which gives plenty of time for the garbage collector to run as well as our own code.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;We will make use of the wrappers for the waveIn API’s, as these are the most universally supported, and allow us freedom to choose the sample rate. We will record in mono, 16 bit at 8kHz, which is more than good enough audio quality for speech, and will not overly tax the processor, which is important as we want to visualize the waveform as well.&lt;/p&gt;  &lt;h4&gt;Choosing a Capture Device&lt;/h4&gt;  &lt;p&gt;Normally, you will be able to use the default audio capture device without any difficulties, but should you need to offer the user a choice, NAudio will allow you to do so. You can use the &lt;b&gt;WaveIn.DeviceCount&lt;/b&gt; and &lt;b&gt;WaveIn.GetDeviceCapabilities&lt;/b&gt; to find out how many recording devices are present, and query for their name and number of supported channels.&lt;/p&gt;  &lt;p&gt;On my computer, I have a single waveIn device (Microphone Array) until I plug my headset in, at which point, a new device appears and becomes the default (device 0 is always the default).&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;int&lt;/span&gt; waveInDevices = WaveIn.DeviceCount;
&lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; waveInDevice = 0; waveInDevice &amp;lt; waveInDevices; waveInDevice++)
{
    WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Device {0}: {1}, {2} channels&amp;quot;&lt;/span&gt;, 
        waveInDevice, deviceInfo.ProductName, deviceInfo.Channels);
}&lt;/pre&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;This produces the following output on my computer:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Device 0: Microphone / Line In (SigmaTel , 2 channels 
    &lt;br /&gt;Device 1: Microphone Array (SigmaTel High, 2 channels&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unfortunately these device names are truncated because the WAVEINCAPS structure only supports 31 characters. There is &lt;a href="http://stackoverflow.com/questions/1449162/get-the-full-name-of-a-wavein-device"&gt;a way of getting the full device name&lt;/a&gt;, but it is rather convoluted.&lt;/p&gt;

&lt;p&gt;Normally, you will choose Device 0 (the default), but if you wish to select a different input device, simply set the &lt;b&gt;DeviceNumber&lt;/b&gt; property on your WaveIn object to the desired number.&lt;/p&gt;

&lt;h4&gt;Checking the Recording Level&lt;/h4&gt;

&lt;p&gt;The first step in recording is usually to help the user determine if their microphone is working or not. This is especially important if the user has more than one input on their soundcard. The way we achieve this is simply by starting recording and displaying the level of audio detected to the user with a volume meter. The waveIn APIs do not write anything to disk, so no audio is actually being ‘recorded’ at this point, we are simply examining the input level and then throwing the captured audio samples away.&lt;/p&gt;

&lt;p&gt;To begin capturing audio from the soundcard, we use the &lt;b&gt;WaveIn&lt;/b&gt; class in NAudio. We configure it with the WaveFormat in which we would like to record (in our case 8kHz mono), before calling &lt;b&gt;StartRecording&lt;/b&gt;, to start capturing audio from the device.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;waveIn = &lt;span class="kwrd"&gt;new&lt;/span&gt; WaveIn();
waveIn.DeviceNumber = selectedDevice;
waveIn.DataAvailable += waveIn_DataAvailable;
&lt;span class="kwrd"&gt;int&lt;/span&gt; sampleRate = 8000; &lt;span class="rem"&gt;// 8 kHz&lt;/span&gt;
&lt;span class="kwrd"&gt;int&lt;/span&gt; channels = 1; &lt;span class="rem"&gt;// mono&lt;/span&gt;
waveIn.WaveFormat = &lt;span class="kwrd"&gt;new&lt;/span&gt; WaveFormat(sampleRate, channels);
waveIn.StartRecording();&lt;/pre&gt;

&lt;p&gt;The &lt;b&gt;DataAvailable&lt;/b&gt; event handler will notify us whenever a buffer of audio has been returned to us from the sound card. The data comes back as an array of bytes, representing PCM sample data. This is fine if we are planning to write the audio directly to disk, but what if we wish to have a look at the audio data itself? Each audio sample is 16 bits, i.e. two bytes, meaning that we will need to convert pairs of bytes into shorts to be able to make sense of the data.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; if we were recording in stereo, the 16 bit samples would themselves come in pairs, first the left sample, then the right sample.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The following code shows how we might process the raw bytes in the &lt;b&gt;DataAvailable&lt;/b&gt; event, and read the individual audio samples out. Notice that we use the &lt;b&gt;BytesRecorded&lt;/b&gt; field, not the buffer’s Length property. Also, I have chosen to convert the samples to 32 bit floating point format and scaled them so the maximum volume is 1.0f. This makes processing them through effects and visualizing them much easier.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; waveIn_DataAvailable(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, WaveInEventArgs e)
{
    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; index = 0; index &amp;lt; e.BytesRecorded; index += 2)
    {
        &lt;span class="kwrd"&gt;short&lt;/span&gt; sample = (&lt;span class="kwrd"&gt;short&lt;/span&gt;)((e.Buffer[index + 1] &amp;lt;&amp;lt; 8) | 
                                e.Buffer[index + 0]);
        &lt;span class="kwrd"&gt;float&lt;/span&gt; sample32 = sample / 32768f;
        ProcessSample(sample32);
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;One complication of using the waveIn and waveOut APIs is deciding on a callback mechanism. NAudio offers three options. First is &lt;b&gt;function&lt;/b&gt; callbacks. This means that the waveIn API is given a (pinned) function pointer which it calls back onto. This means that your DataAvailable callback will come in on a background thread. In some ways this is the cleanest approach, but you need to beware of rogue soundcard drivers that can hang in calls to waveOutReset when using function callbacks (the SoundMAX chipset found on a lot of laptops is particularly prone to this problem).&lt;/p&gt;

  &lt;p&gt;The second is to supply a &lt;b&gt;window handle&lt;/b&gt;. The waveIn APIs will post a message back to be handled on the message queue of that window handle. This method tends to be the most reliable and most commonly used. One gotcha to watch out for is that if you stop recording and &lt;i&gt;immediately&lt;/i&gt; restart, a message from the old recording session could get handled in the new session resulting in a nasty exception. &lt;/p&gt;

  &lt;p&gt;The third is to let NAudio create its own &lt;b&gt;new window&lt;/b&gt; and post messages to that. This gets round any danger of messages from one recording session getting muddled up with another. This is the callback method that NAudio will use by default if you call the default &lt;b&gt;WaveIn&lt;/b&gt; constructor. But don’t use this from a background thread or from a console application, or the new window that NAudio creates won’t actually get round to processing its message queue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;Visualizing the Recording Level&lt;/h4&gt;

&lt;p&gt;We have seen how we can begin to capture audio from the soundcard for the purposes of checking the recording level. Now we need to give the user some visual feedback. We will use WPF for our sample recording application. The simplest control we have available to display a single numeric value graphically is the &lt;b&gt;ProgressBar&lt;/b&gt;. And because it is WPF, we can fully customize the graphical appearance of the progress bar to look a little more like a volume meter. I have used a gradient going from green to red to show the current volume level. You can read more about how I created this ProgressBar template &lt;a href="http://mark-dot-net.blogspot.com/2009/09/styling-wpf-volume-meter.html"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_12.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_thumb_5.png" width="296" height="37" /&gt;&lt;/a&gt; 

  &lt;br /&gt;&lt;strong&gt;Figure 1 - A Progress Bar Showing the Current Microphone Volume Level&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To help provide the volume level to display, I have created a &lt;b&gt;SampleAggregator&lt;/b&gt; class. This is passed every audio sample value we receive and keeps track of the maximum and minimum values. Then, after a specified number of samples, it raises an event allowing the GUI components to respond. We need to be careful not to raise too many of these events or performance will be badly affected. I am raising one every 800 samples, meaning we get 10 updates per second to the screen.&lt;/p&gt;

&lt;p&gt;Because I am using data binding, when one of these updates fires, I must raise a &lt;b&gt;PropertyChangedEvent&lt;/b&gt; on my DataContext object (also known as the “ViewModel” in the MVVM pattern). Here’s the XAML syntax for binding to my &lt;b&gt;CurrentInputLevel&lt;/b&gt; property:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ProgressBar&lt;/span&gt; &lt;span class="attr"&gt;Orientation&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Horizontal&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding CurrentInputLevel, Mode=OneWay}&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;20&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;And here’s the code in the ViewModel that ensures that the GUI updates whenever we calculate a new maximum input level:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;float&lt;/span&gt; lastPeak;

&lt;span class="kwrd"&gt;void&lt;/span&gt; recorder_MaximumCalculated(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, MaxSampleEventArgs e) 
{
    lastPeak = Math.Max(e.MaxSample, Math.Abs(e.MinSample));
    RaisePropertyChangedEvent(&lt;span class="str"&gt;&amp;quot;CurrentInputLevel&amp;quot;&lt;/span&gt;);
}

&lt;span class="rem"&gt;// multiply by 100 because the Progress bar's default maximum value is 100 &lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;float&lt;/span&gt; CurrentInputLevel { get { &lt;span class="kwrd"&gt;return&lt;/span&gt; lastPeak * 100; } }&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;Model View ViewModel (MVVM) is a pattern that is growing in popularity amongst WPF and Silverlight developers. The basic idea is that you have no code behind whatsoever on your View (i.e. your xaml markup file), and simply specify all communications with your business logic by means of data binding. The ViewModel serves as an adapter to ease the process of data binding. This approach gives very good separation of appearance and behavior. For the most part, this pattern works very well, but there are a few tricky areas, for which you will need to either write a few lines of code behind, or make use of some cunning tricks such as attached dependency properties or custom triggers. There are several excellent open source helper libraries that can take some of the work out of getting an MVVM application up and running. Have a look &lt;a href="http://stackoverflow.com/questions/1409553/what-framework-for-mvvm-should-i-use"&gt;here&lt;/a&gt; for a comprehensive list.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;Adjusting the Recording Level&lt;/h4&gt;

&lt;p&gt;Suppose the current input level is too high or too soft. We would like to be able to support modifying the recording level. Again, we would like to use data binding to do so, so we will add a volume slider to our XAML:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Slider&lt;/span&gt; &lt;span class="attr"&gt;Orientation&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Horizontal&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding MicrophoneLevel, Mode=TwoWay}&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;Maximum&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;100&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;Margin&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;5&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Now we have to get hold of the &lt;b&gt;MixerLine&lt;/b&gt; that will allow us to access the input volume control for our waveIn device. This requires us to make use of the Windows mixer APIs, which also have wrappers in NAudio. Getting hold of this volume control is not always as straightforward as you might hope (and can require different approaches for XP and Vista), but the following is code that seems to work on most systems:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TryGetVolumeControl()
{
    &lt;span class="kwrd"&gt;int&lt;/span&gt; waveInDeviceNumber = 0;
    var mixerLine = &lt;span class="kwrd"&gt;new&lt;/span&gt; MixerLine((IntPtr)waveInDeviceNumber, 
                                   0, MixerFlags.WaveIn);
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var control &lt;span class="kwrd"&gt;in&lt;/span&gt; mixerLine.Controls)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (control.ControlType == MixerControlType.Volume)
        {
            volumeControl = control &lt;span class="kwrd"&gt;as&lt;/span&gt; UnsignedMixerControl;        
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        }
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now we can use the &lt;b&gt;Percent&lt;/b&gt; property on the UnsignedMixerControl to set volume to a value anywhere between 0 and 100.&lt;/p&gt;

&lt;h4&gt;Starting Recording&lt;/h4&gt;

&lt;p&gt;Now we have got our recording levels set up correctly, we are ready to actually start recording. But since we have already opened our waveIn device, all we need to do is start writing the data we have received into a file. &lt;/p&gt;

&lt;p&gt;NAudio has a class called &lt;b&gt;WaveFileWriter &lt;/b&gt;which will allow us to write our recorded data to a file. For now, we will write it to a temporary file in PCM format, and convert it later into a better compressed format such as MP3. The following code creates a new WAV file:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;writer = &lt;span class="kwrd"&gt;new&lt;/span&gt; WaveFileWriter(waveFileName, recordingFormat);&lt;/pre&gt;

&lt;p&gt;Now we can write to the file as we receive notifications from the waveIn device:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; waveIn_DataAvailable(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, WaveInEventArgs e)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (recordingState == RecordingState.Recording)
        writer.WriteData(e.Buffer, 0, e.BytesRecorded);            

   &lt;span class="rem"&gt;// ...&lt;/span&gt;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; There are three main options for how to store audio while it is being recorded. First, you can write it to a &lt;b&gt;MemoryStream&lt;/b&gt;. This saves the inconvenience of dealing with a temporary file, but you need to be careful not to run out of memory. Also, if your recording program crashes half way through, you have lost everything. At the sample rate we are using for this demo, one minute of audio takes just under 1 MB of memory, but if you were recording at 44.1kHz stereo (the standard for music), you would need about 10 MB per minute.&lt;/p&gt;

  &lt;p&gt;Second, you can write to a temporary WAV file to be converted to another format later, as we are doing here. While this is not a disk space efficient format, it is very easy to work with, and particularly useful if you are planning to apply any effects or edit the audio in any way after recording. &lt;/p&gt;

  &lt;p&gt;Third, you can pass the audio directly to an encoder (such as WMA or MP3) as it is being recorded. This might be the best option if you are making a longer recording, and have no need to edit it after recording.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;Stopping Recording&lt;/h4&gt;

&lt;p&gt;Obviously we will stop when the user clicks the stop recording button, but we might also want to set a maximum recording duration to stop the user inadvertently filling up their hard disk. For this example, we will allow one minute of recording.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;long&lt;/span&gt; maxFileLength = &lt;span class="kwrd"&gt;this&lt;/span&gt;.recordingFormat.AverageBytesPerSecond * 60;
 
&lt;span class="kwrd"&gt;int&lt;/span&gt; toWrite = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)Math.Min(maxFileLength - writer.Length, bytesRecorded);
&lt;span class="kwrd"&gt;if&lt;/span&gt; (toWrite &amp;gt; 0)
    writer.WriteData(buffer, 0, bytesRecorded);
&lt;span class="kwrd"&gt;else&lt;/span&gt;
    Stop();&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;b&gt;Note: &lt;/b&gt;Something that can be slightly confusing for users is that when using window callbacks with WaveIn, the last bit of audio you recorded comes in &lt;i&gt;after&lt;/i&gt; you have asked recording to stop, so make sure you don’t close the file you are saving to until you have got all the audio back. The &lt;b&gt;FinishedRecording&lt;/b&gt; event on the WaveIn object will help you determine when it is safe to close the WaveFileWriter and clean up your resources.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;Visualizing the Wave Form&lt;/h4&gt;

&lt;p&gt;It is often desirable to display the audio waveform to the user. Displaying the waveform while you are recording is sometimes called “confidence recording”, because it allows you to see that audio is being recorded as expected and the levels are still right.&lt;/p&gt;

&lt;p&gt;There are a variety of possible approaches for drawing audio waveforms. The simplest is to draw a vertical line showing the minimum and maximum values every time our sample aggregator fires:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_10.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_thumb_4.png" width="190" height="76" /&gt;&lt;/a&gt; 

  &lt;br /&gt;&lt;strong&gt;Figure 2 - Audio Waveform using vertical lines &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At first glance it may seem that this would be trivial to implement in WPF, but there is a real danger of consuming too many resources. For example, simply adding a new line to a Canvas every time a new maximum sample is calculated performs very badly, so it is better to have a fixed number of vertical lines and resize them dynamically.&lt;/p&gt;

&lt;p&gt;Another approach is to create a polygon. This requires us to add two points to a Polygon’s Points collection every time we receive a new sample. The trick is to add these points in the middle of the Points collection, rather than at the end, so that the end result is a single shape. This means our waveform can have a different outline color and fill color. To stop the edges from appearing too jagged, we plot points two units apart along on the X axis.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_thumb_3.png" width="383" height="105" /&gt;&lt;/a&gt;&lt;strong&gt;
    &lt;br /&gt;Figure 3 - Audio Waveform rendered using a Polygon&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Like the microphone volume meter, the waveform drawing control needs to receive several notifications a second of the maximum and minimum sample values received by the SampleAggregator. When each sample value is received, we either insert new points into our polygon, or, if the whole screen is full, we go back to the left-hand edge and continue drawing from there.&lt;/p&gt;

&lt;p&gt;For the confidence recording display I have used the Polygon method, which is in a class called &lt;b&gt;PolygonWaveFormControl&lt;/b&gt;. Here’s the code which calculates the new points or updated point locations as we receive a new maximum sample:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AddValue(&lt;span class="kwrd"&gt;float&lt;/span&gt; maxValue, &lt;span class="kwrd"&gt;float&lt;/span&gt; minValue)
{
    &lt;span class="kwrd"&gt;int&lt;/span&gt; visiblePixels = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)(ActualWidth / xScale);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (visiblePixels &amp;gt; 0)
    {
        CreatePoint(maxValue, minValue);

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (renderPosition &amp;gt; visiblePixels)
        {
            renderPosition = 0;
        }
        &lt;span class="kwrd"&gt;int&lt;/span&gt; erasePosition = (renderPosition + blankZone) % visiblePixels;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (erasePosition &amp;lt; Points)
        {
            &lt;span class="kwrd"&gt;double&lt;/span&gt; yPos = SampleToYPosition(0);
            waveForm.Points[erasePosition] = 
               &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(erasePosition * xScale, yPos);
            waveForm.Points[BottomPointIndex(erasePosition)] = 
               &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(erasePosition * xScale, yPos);
        }
    }
}

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CreatePoint(&lt;span class="kwrd"&gt;float&lt;/span&gt; topValue, &lt;span class="kwrd"&gt;float&lt;/span&gt; bottomValue)
{
    &lt;span class="kwrd"&gt;double&lt;/span&gt; topYPos = SampleToYPosition(topValue);
    &lt;span class="kwrd"&gt;double&lt;/span&gt; bottomYPos = SampleToYPosition(bottomValue);
    &lt;span class="kwrd"&gt;double&lt;/span&gt; xPos = renderPosition * xScale;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (renderPosition &amp;gt;= Points)
    {
        &lt;span class="kwrd"&gt;int&lt;/span&gt; insertPos = Points;
        waveForm.Points.Insert(insertPos, &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(xPos, topYPos));
        waveForm.Points.Insert(insertPos + 1, &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(xPos, bottomYPos));
    }
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
    {
        waveForm.Points[renderPosition] = &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(xPos, topYPos);
        waveForm.Points[BottomPointIndex(renderPosition)] = 
              &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(xPos, bottomYPos);
    }
    renderPosition++;
}&lt;/pre&gt;

&lt;p&gt;The erase position calculation is to blank out some previous sample values to make it obvious where the new data is appearing after we have wrapped around once:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_14.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_thumb_6.png" width="291" height="53" /&gt;&lt;/a&gt; 

  &lt;br /&gt;&lt;strong&gt;Figure 4 PolygonWaveForm control's “blank zone”&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; There are faster ways to perform rendering in WPF. One option is to use the &lt;b&gt;WriteableBitmap&lt;/b&gt; class and draw directly onto it. This could be a good approach if you were using the vertical lines method of rendering. The second is to use &lt;b&gt;DrawingVisual&lt;/b&gt; objects, which are lightweight drawing objects offering better performance than using classes derived from Shape. The down-side is the loss of features such as DataBinding and the ability to fully describe the picture in XAML, but for WaveForm drawing this is not really a drawback. I use the DrawingVisual method in the Save Audio part of this application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another challenge was how the waveform drawing control could receive notifications since I am using MVVM so I have no direct access to the SampleAggregator. A simple way around this was to create a Dependency Property on PolygonWaveFormControl:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; DependencyProperty SampleAggregatorProperty = 
       DependencyProperty.Register(
          &lt;span class="str"&gt;&amp;quot;SampleAggregator&amp;quot;&lt;/span&gt;, 
          &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(SampleAggregator), 
          &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(PolygonWaveFormControl), 
          &lt;span class="kwrd"&gt;new&lt;/span&gt; PropertyMetadata(&lt;span class="kwrd"&gt;null&lt;/span&gt;, OnSampleAggregatorChanged));

&lt;span class="kwrd"&gt;public&lt;/span&gt; SampleAggregator SampleAggregator
{
    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; (SampleAggregator)&lt;span class="kwrd"&gt;this&lt;/span&gt;.GetValue(SampleAggregatorProperty); }
    set { &lt;span class="kwrd"&gt;this&lt;/span&gt;.SetValue(SampleAggregatorProperty, &lt;span class="kwrd"&gt;value&lt;/span&gt;); }
}
        
&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnSampleAggregatorChanged(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DependencyPropertyChangedEventArgs e)
{
    PolygonWaveFormControl control = (PolygonWaveFormControl)sender;
    control.Subscribe();
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This allows us to bind the PolygonWaveFormControl to the SampleAggregator made public on our DataContext:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;my:PolygonWaveFormControl&lt;/span&gt; 
    &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;40&amp;quot;&lt;/span&gt; 
    &lt;span class="attr"&gt;SampleAggregator&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;{Binding SampleAggregator}&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h4&gt;Trimming the Audio&lt;/h4&gt;

&lt;p&gt;We have created a temporary WAV file, but before the user saves it to a file of their choosing, we want to allow them to trim off any unwanted parts from the start and end of the recording. To do this I would like to display the entire recorded waveform, with a selection rectangle superimposed on top to allow a sub-range to be selected.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_16.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/78334719da26.NETVoiceRecorder_C433/image_thumb_7.png" width="289" height="159" /&gt;&lt;/a&gt; 

  &lt;br /&gt;&lt;strong&gt;Figure 5 - GUI to allow selection of a portion of the recorded audio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To accomplish this kind of interface we need three components. The first is a &lt;b&gt;ScrollViewer&lt;/b&gt;. The ScrollViewer allows us to scroll left and right through the WaveForm if it is too big to fit onto a screen, which is likely if you record more than a few seconds of audio. &lt;/p&gt;

&lt;p&gt;The second is a new type of WaveForm renderer that will render an entire file, rather than my PolygonWaveFormControl which started again at the left when the screen filled up. For this I created &lt;b&gt;WaveFormVisual&lt;/b&gt; which uses DrawingVisual objects to draw the entire WaveForm. Obviously if we wanted to record for a long period, this approach would need to be optimised as the polygon it creates would have thousands of points, but for short recordings, it works fine.&lt;/p&gt;

&lt;p&gt;The third piece was the hardest to get right – the selection rectangle to support mouse dragging selection of the waveform. For this I created the &lt;b&gt;RangeSelectionControl&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;b&gt;RangeSelectionControl&lt;/b&gt; is simply a blue rectangle with a solid outline and semi-transparent fill sitting on a Canvas. The magic occurs in the mouse handler. We need to detect when the user hovers over the left or right edge of the rectangle, and set the cursor to show a horizontal resizing icon. This can be done in the MouseMove event, checking the X coordinate and then setting the Cursor property:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;Cursor = Cursors.SizeWE;&lt;/pre&gt;

&lt;p&gt;When the user clicks the left-button while over the edge, we begin to drag. Key to this is calling &lt;b&gt;Canvas.CaptureMouse&lt;/b&gt;. If we don’t do this, as soon as you try to drag the rectangle bigger, the mouse move events are lost to other controls underneath.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; RangeSelectionControl_MouseDown(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, MouseButtonEventArgs e)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (e.LeftButton == MouseButtonState.Pressed)
    {
        Point position = e.GetPosition(&lt;span class="kwrd"&gt;this&lt;/span&gt;);
        Edge edge = EdgeAtPosition(position.X);
        DragEdge = edge;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (DragEdge != Edge.None)
        {
            mainCanvas.CaptureMouse();
        }
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now in the MouseMove methods, we can change the Canvas.Left and Width properties of the rectangle to resize it.&lt;/p&gt;

&lt;p&gt;The &lt;b&gt;ScrollViewer&lt;/b&gt; is quite straightforward to use, but you must remember to set CanContentScroll property to true, and also to set the size of the items within the ScrollViewer correctly.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ScrollViewer&lt;/span&gt; &lt;span class="attr"&gt;CanContentScroll&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;True&amp;quot;&lt;/span&gt; 
         &lt;span class="attr"&gt;HorizontalScrollBarVisibility&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Visible&amp;quot;&lt;/span&gt; 
         &lt;span class="attr"&gt;VerticalScrollBarVisibility&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Hidden&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;my:WaveFormVisual&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;100&amp;quot;&lt;/span&gt; 
           &lt;span class="attr"&gt;HorizontalAlignment&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Left&amp;quot;&lt;/span&gt; 
           &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;waveFormRenderer&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;my:RangeSelectionControl&lt;/span&gt; 
           &lt;span class="attr"&gt;HorizontalAlignment&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Left&amp;quot;&lt;/span&gt; 
           &lt;span class="attr"&gt;x:Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;rangeSelection&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Grid&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ScrollViewer&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;We set the appropriate Width of the WaveFormVisual and RangeSelectionControl based on the total number of points we have drawn in the waveform. &lt;/p&gt;

&lt;h4&gt;Saving the Audio&lt;/h4&gt;

&lt;p&gt;So we are finally ready to save the audio. We will offer the user two choices of format to save in. The first is simply to save as a WAV file. If the user has selected the entire recording, we only need to copy the audio across to their desired location. If, however, the user has selected a sub-range, then we need to trim the WAV file. This can be quickly accomplished using a &lt;b&gt;TrimWavFile&lt;/b&gt; utility function that copies from a WAV file reader to a WAV file writer, skipping over a certain number of bytes from the beginning and end.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TrimWavFile(&lt;span class="kwrd"&gt;string&lt;/span&gt; inPath, &lt;span class="kwrd"&gt;string&lt;/span&gt; outPath, 
                TimeSpan cutFromStart, TimeSpan cutFromEnd)
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt; (WaveFileReader reader = &lt;span class="kwrd"&gt;new&lt;/span&gt; WaveFileReader(inPath))
    {
        &lt;span class="kwrd"&gt;using&lt;/span&gt; (WaveFileWriter writer = 
               &lt;span class="kwrd"&gt;new&lt;/span&gt; WaveFileWriter(outPath, reader.WaveFormat))
        {
            &lt;span class="kwrd"&gt;int&lt;/span&gt; bytesPerMillisecond = 
                reader.WaveFormat.AverageBytesPerSecond / 1000;

            &lt;span class="kwrd"&gt;int&lt;/span&gt; startPos = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)cutFromStart.TotalMilliseconds * 
                           bytesPerMillisecond;
            startPos = startPos - startPos % reader.WaveFormat.BlockAlign;

            &lt;span class="kwrd"&gt;int&lt;/span&gt; endBytes = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)cutFromEnd.TotalMilliseconds * 
                           bytesPerMillisecond;
            endBytes = endBytes - endBytes % reader.WaveFormat.BlockAlign;
            &lt;span class="kwrd"&gt;int&lt;/span&gt; endPos = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)reader.Length - endBytes; 

            TrimWavFile(reader, writer, startPos, endPos);
        }
    }
}

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TrimWavFile(WaveFileReader reader, 
                    WaveFileWriter writer, &lt;span class="kwrd"&gt;int&lt;/span&gt; startPos, &lt;span class="kwrd"&gt;int&lt;/span&gt; endPos)
{
    reader.Position = startPos;
    &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] buffer = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[1024];
    &lt;span class="kwrd"&gt;while&lt;/span&gt; (reader.Position &amp;lt; endPos)
    {
        &lt;span class="kwrd"&gt;int&lt;/span&gt; bytesRequired = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)(endPos - reader.Position);
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (bytesRequired &amp;gt; 0)
        {
            &lt;span class="kwrd"&gt;int&lt;/span&gt; bytesToRead = Math.Min(bytesRequired, buffer.Length);
            &lt;span class="kwrd"&gt;int&lt;/span&gt; bytesRead = reader.Read(buffer, 0, bytesToRead);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (bytesRead &amp;gt; 0)
            {
                writer.WriteData(buffer, 0, bytesRead);
            }
        }
    }
}&lt;/pre&gt;

&lt;p&gt;We also want to offer the ability to save as MP3. The easiest way to create MP3 files is to use the open source LAME MP3 encoder (do a web search for lame.exe to get hold of this application if you haven’t already got it). Our application will look in the current directory, and prompt the user to find lame.exe if it is not present, as we do not include it in the application download. Assuming you do provide a valid path, we can then convert our (trimmed) WAV file to MP3 by simply calling lame.exe with the appropriate parameters.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ConvertToMp3(&lt;span class="kwrd"&gt;string&lt;/span&gt; lameExePath, 
     &lt;span class="kwrd"&gt;string&lt;/span&gt; waveFile, &lt;span class="kwrd"&gt;string&lt;/span&gt; mp3File)
{
   Process converter = Process.Start(lameExePath, &lt;span class="str"&gt;&amp;quot;-V2 \&amp;quot;&amp;quot;&lt;/span&gt; + waveFile 
                            + &lt;span class="str"&gt;&amp;quot;\&amp;quot; \&amp;quot;&amp;quot;&lt;/span&gt; + mp3File + &lt;span class="str"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;);
   converter.WaitForExit();
}&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;We end up with a nice compact MP3 file containing the selected portion of our microphone recording.&lt;/p&gt;

&lt;h4&gt;Exploring the Sample Code Solution&lt;/h4&gt;

&lt;p&gt;The main WPF sample application is found in the &lt;b&gt;VoiceRecorder&lt;/b&gt; project. This contains the main window along with the three views and their associated ViewModels. &lt;b&gt;VoiceRecorder.Core&lt;/b&gt; contains some WPF helper classes and user controls to help with the plumbing and GUI of the application, while &lt;b&gt;VoiceRecorder.Audio&lt;/b&gt; contains the classes that actually perform the recording, editing and converting of audio.&lt;/p&gt;

&lt;h4&gt;About the Author&lt;/h4&gt;

&lt;p&gt;Mark Heath is a software developer currently working for NICE CTI Systems in Southampton, UK. He specializes in .NET development with a particular focus on client side technologies and audio playback. He blogs about audio, WPF, Silverlight and software engineering best practices at &lt;a href="http://mark-dot-net.blogspot.com"&gt;http://mark-dot-net.blogspot.com&lt;/a&gt;. He is the author of several open source projects hosted at CodePlex, including NAudio, a low-level .NET audio toolkit (&lt;a href="http://www.codeplex.com/naudio"&gt;http://www.codeplex.com/naudio&lt;/a&gt;).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9905168" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Audio/default.aspx">Audio</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Model-View-ViewModel/default.aspx">Model-View-ViewModel</category></item><item><title>Creating Photo Stacks</title><link>http://blogs.msdn.com/coding4fun/archive/2009/10/05/9903340.aspx</link><pubDate>Mon, 05 Oct 2009 20:00:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9903340</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9903340.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9903340</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9903340</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/CreatingPhotoStacks_8CD1/sizey-100%5B1%5D_2.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 0px 5px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="sizey-100[1]" border="0" alt="sizey-100[1]" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/CreatingPhotoStacks_8CD1/sizey-100%5B1%5D_thumb.jpg" width="138" height="100" /&gt;&lt;/a&gt; &lt;a href="http://niknak.org/blog/631-say-goodbye-to-gdi-on-the-web"&gt;Simon Hoade liked how Windows had 3D photo stacks and wanted to recreate the effect&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;He shows how he used threads and calling WPF code from a web server without actually having a WPF application!&lt;/p&gt;  &lt;p&gt;He mentioned he used two tutorials also that helped aid him.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a title="http://www.codeproject.com/KB/WPF/WPFImageEffects.aspx" href="http://www.codeproject.com/KB/WPF/WPFImageEffects.aspx"&gt;http://www.codeproject.com/KB/WPF/WPFImageEffects.aspx&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="http://www.codeproject.com/KB/WPF/WPFImageEffects.aspx" href="http://www.codeproject.com/KB/WPF/WPFImageEffects.aspx"&gt;http://www.codeproject.com/KB/WPF/WPFImageEffects.aspx&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9903340" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/WPF/default.aspx">WPF</category></item><item><title>Fluids and edge detection in Silverlight</title><link>http://blogs.msdn.com/coding4fun/archive/2009/09/30/9900361.aspx</link><pubDate>Wed, 30 Sep 2009 20:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9900361</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9900361.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9900361</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9900361</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/FluidsandedgedetectioninSilverlight_9684/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/FluidsandedgedetectioninSilverlight_9684/image_thumb.png" width="240" height="125" /&gt;&lt;/a&gt; Rick Barraza has 3 amazing examples in Silverlight.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.cynergysystems.com/blogs/page/rickbarraza?entry=advanced_render_techniques_with_writeablebitmaps"&gt;Writable Bitmaps&lt;/a&gt;       &lt;br /&gt;This example shows how to use pixel shader displacement with line drawing to create some amazing effects. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.cynergysystems.com/blogs/page/rickbarraza?entry=fluid_dynamics_in_silverlight"&gt;Fluid Dynamics&lt;/a&gt;       &lt;br /&gt;Rick talks about how to do dynamic visuals, why they matter. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.cynergysystems.com/blogs/page/rickbarraza?entry=rendering_vector_fields_in_silverlight"&gt;Vector Fields&lt;/a&gt;       &lt;br /&gt;This example shows how to gray scale an image, do edge detection then use that information to draw vectors on the image for additional effects. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you want additional information with Rick, &lt;a href="http://blogs.msdn.com/coding4fun/archive/2009/09/21/9896902.aspx"&gt;Brian Peek did an interview with him regarding Silverlight advance rendering techniques as well.&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9900361" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/c4fnews/default.aspx">c4fnews</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Silverlight/default.aspx">Silverlight</category></item></channel></rss>