<?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 : events</title><link>http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx</link><description>Tags: events</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>April Fools' Day Application</title><link>http://blogs.msdn.com/coding4fun/archive/2007/03/29/1991785.aspx</link><pubDate>Fri, 30 Mar 2007 04:03:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1991785</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/1991785.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=1991785</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=1991785</wfw:comment><description>&lt;span&gt; &lt;table cellspacing="0" cellpadding="1" width="100%" border="0"&gt; &lt;tbody&gt; &lt;tr class="entry_overview"&gt; &lt;td width="50"&gt;&lt;img src="http://www.coding4fun.net/images/AprilFoolsDayApplication_C903/rotate_thumb6.png" width="50"&gt;&lt;/td&gt; &lt;td&gt;&lt;span class="entry_description"&gt;In this article, Brian Peek builds an application that will annoy your friends for April Fools' Day! &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td colspan="2"&gt; &lt;div class="entry_author"&gt;Brian Peek&lt;/div&gt; &lt;div class="entry_company"&gt;&lt;a href="http://www.aspsoft.com/"&gt;ASPSOFT, Inc.&lt;/a&gt;&lt;/div&gt;&lt;br&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Difficulty: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Easy&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Time Required:&lt;/b&gt; &lt;span class="entry_details_input"&gt;Less than 1 hour&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Cost: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Free&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Software: &lt;/b&gt;&lt;span class="entry_details_input"&gt;&lt;a href="http://msdn.com/express/"&gt;Visual Basic or Visual C# Express Editions&lt;/a&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Hardware: &lt;/b&gt;&lt;span class="entry_details_input"&gt;None&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Download: &lt;/b&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=296498"&gt;Download&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt; &lt;div class="entry_details"&gt;&amp;nbsp;&lt;/div&gt; &lt;h3&gt;Introduction&lt;/h3&gt; &lt;p&gt;You may recall my previous &lt;a href="http://msdn.microsoft.com/coding4fun/events/halloween/article.aspx?articleid=905508&amp;amp;title=Scary+Halloween+Application" target="_blank"&gt;Halloween article&lt;/a&gt; which involved dripping animated blood down a victim's screen.&amp;nbsp; For April Fools' Day, I wrote an application that uses the same basic framework, and provides an equal amount of annoyance for the intended victim.&lt;/p&gt; &lt;p&gt;This time around, the application will lay in wait until the assigned time and then run one of two (or both!) effects:&amp;nbsp; desktop zoom in/out and desktop rotate.&lt;/p&gt; &lt;p&gt;Some of this article will be a bit of a rehash from the previous article, but for the sake of being complete, I will be&amp;nbsp;describing the duplicated portions here.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.coding4fun.net/images/AprilFoolsDayApplication_C903/rotate3.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="312" src="http://www.coding4fun.net/images/AprilFoolsDayApplication_C903/rotate_thumb1.png" width="500" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;&lt;b&gt;The Form&lt;/b&gt; &lt;/h3&gt; &lt;p&gt;We will be creating a full-screen, always-on-top, transparent form that will overlay the entire screen. This will be our display surface for the animation.  &lt;p&gt;The form can be created as described by modifying the following properties:  &lt;p&gt;&lt;b&gt;BackColor&lt;/b&gt; – Fuchsia  &lt;p&gt;&lt;b&gt;FormBorderStyle&lt;/b&gt; – None  &lt;p&gt;&lt;b&gt;DoubleBuffered&lt;/b&gt; – True  &lt;p&gt;&lt;b&gt;Text&lt;/b&gt; - &amp;lt;empty string&amp;gt;  &lt;p&gt;&lt;b&gt;WindowState&lt;/b&gt; – Normal  &lt;p&gt;&lt;b&gt;ShowInTaskbar&lt;/b&gt; – False  &lt;p&gt;&lt;b&gt;TransparencyKey&lt;/b&gt; – Fuchsia  &lt;p&gt;&lt;b&gt;TopMost&lt;/b&gt; - True  &lt;p&gt;This will create our full-screen, transparent form with no visible name, no icon in the task bar, no border that will remain on top of all other windows. With this in place, we can draw whatever we want to on to the form and it will be displayed over whatever happens to be on the screen.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Multiple Monitors&lt;/h3&gt; &lt;p&gt;One feature I did not implement in the previous Halloween application was support for systems with multiple monitors.&amp;nbsp; This application will attempt to support a basic&amp;nbsp;multi-mon configuration.&amp;nbsp; When the animation starts, the application must cover the entire display area across all monitors.&lt;/p&gt; &lt;p&gt;One can get information about every monitor attached to a system by using the &lt;strong&gt;Screen.AllScreens&lt;/strong&gt; property.&amp;nbsp; So, to find the maximum "viewport" of the system, the application enumerates all monitors and finds the maximum width/height:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// full width/height of all monitors combined&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Rectangle fullSize;

&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; Screen.AllScreens.Length; i++)
{
    &lt;span style="color: #008000"&gt;// find a rectangle that will encompass all monitors on the system&lt;/span&gt;
    &lt;span style="color: #008000"&gt;// (assuming the primary monitor is on the left/top!)&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Screen.AllScreens[i].Bounds.Left &amp;lt; fullSize.Left)
        fullSize.X = Screen.AllScreens[i].Bounds.Left;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Screen.AllScreens[i].Bounds.Right &amp;gt; fullSize.Right)
        fullSize.Width = Screen.AllScreens[i].Bounds.Right;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Screen.AllScreens[i].Bounds.Top &amp;lt; fullSize.Top)
        fullSize.Y = Screen.AllScreens[i].Bounds.Top;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Screen.AllScreens[i].Bounds.Bottom &amp;gt; fullSize.Bottom)
        fullSize.Height = Screen.AllScreens[i].Bounds.Bottom;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/div&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;' full width/height of all monitors combined&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; fullSize &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Rectangle

&lt;span style="color: #0000ff"&gt;For&lt;/span&gt; i &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = 0 &lt;span style="color: #0000ff"&gt;To&lt;/span&gt; Screen.AllScreens.Length - 1
    &lt;span style="color: #008000"&gt;' find a rectangle that will encompass all monitors on the system&lt;/span&gt;
    &lt;span style="color: #008000"&gt;' (assuming the primary monitor is on the left/top!)&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Screen.AllScreens(i).Bounds.Left &amp;lt; fullSize.Left &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        fullSize.X = Screen.AllScreens(i).Bounds.Left
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Screen.AllScreens(i).Bounds.Right &amp;gt; fullSize.Right &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        fullSize.Width = Screen.AllScreens(i).Bounds.Right
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Screen.AllScreens(i).Bounds.Top &amp;lt; fullSize.Top &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        fullSize.Y = Screen.AllScreens(i).Bounds.Top
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Screen.AllScreens(i).Bounds.Bottom &amp;gt; fullSize.Bottom &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        fullSize.Height = Screen.AllScreens(i).Bounds.Bottom
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; i
&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h3&gt;Screen Capture&lt;/h3&gt;
&lt;p&gt;When the animation starts, a screen capture of each monitor is taken and stored in an array.&amp;nbsp; The animation acts upon these images to produce the rotating and zooming effect.&amp;nbsp; Taking a full screen capture in .NET is quite easy:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// an array of bitmaps, one per monitor on the system&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Bitmap[] screenBitmap;

&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; Screen.AllScreens.Length; i++)
{
    &lt;span style="color: #008000"&gt;// grab the size of the current monitor&lt;/span&gt;
    Rectangle region = Screen.AllScreens[i].Bounds;

    &lt;span style="color: #008000"&gt;// create a bitmap of that size&lt;/span&gt;
    screenBitmap[i] = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Bitmap(region.Width, region.Height, 
                        PixelFormat.Format32bppArgb);

    &lt;span style="color: #008000"&gt;// copy the current screen image to the bitmap for the current monitor&lt;/span&gt;
    Graphics bitmapGraphics = Graphics.FromImage(screenBitmap[i]);
    bitmapGraphics.CopyFromScreen(region.Left, region.Top, 0, 0, region.Size);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/div&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;' an array of bitmaps, one per monitor on the system&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; screenBitmap &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Bitmap()

&lt;span style="color: #0000ff"&gt;For&lt;/span&gt; i &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = 0 &lt;span style="color: #0000ff"&gt;To&lt;/span&gt; Screen.AllScreens.Length - 1
    &lt;span style="color: #008000"&gt;' grab the size of the current monitor&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; region &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Rectangle = Screen.AllScreens(i).Bounds

    &lt;span style="color: #008000"&gt;' create a bitmap of that size&lt;/span&gt;
    screenBitmap(i) = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Bitmap(region.Width, region.Height,
                        PixelFormat.Format32bppArgb)

    &lt;span style="color: #008000"&gt;' copy the current screen image to the bitmap for the current monitor&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; bitmapGraphics &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Graphics = Graphics.FromImage(screenBitmap(i))
    bitmapGraphics.CopyFromScreen(region.Left, region.Top, 0, 0, region.Size)
&lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; i
&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h3&gt;Drawing&lt;/h3&gt;
&lt;p&gt;In creating this application, I decided to stay entirely within the framework so deployment would be as simple as copying a single executable to your victim’s machine. Therefore, I decided to use standard GDI+ calls for drawing, instead of Managed DirectX or some other method.&lt;/p&gt;
&lt;p&gt;Drawing is done through the use of a timer.&amp;nbsp; The timer ticks once very 100ms and calls the &lt;strong&gt;Invalidate&lt;/strong&gt; method on the form.&amp;nbsp; When invalidated, the form calls its &lt;b&gt;OnPaint&lt;/b&gt; handler, which is overridden.&lt;/p&gt;
&lt;p&gt;The application currently supports two effects:&amp;nbsp; zooming the desktop into and out of the screen, and rotation.&amp;nbsp; Both effects are obtained using standard GDI+ drawing calls in .NET.&lt;/p&gt;
&lt;p&gt;Two dimensional transforms can be easily done using methods from the &lt;strong&gt;System.Drawing.Drawing2D&lt;/strong&gt; namespace.&amp;nbsp; Rotation can be handled using the &lt;strong&gt;Rotate&lt;/strong&gt; and &lt;strong&gt;RotateAt&lt;/strong&gt; methods, and scaling can be done using the &lt;strong&gt;Scale&lt;/strong&gt; method.&amp;nbsp; The effects for this application will be done on a per-monitor basis using the screen captures taken with the above code:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// rotation angle&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;float&lt;/span&gt; angle = 0.0f;

&lt;span style="color: #008000"&gt;// scale indexer&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;float&lt;/span&gt; scaleIndex = 0.0f;

&lt;span style="color: #008000"&gt;// black background&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.BackColor = Color.Black;

&lt;span style="color: #008000"&gt;// for each monitor, draw the effect&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; screenBitmap.Length; i++)
{
    &lt;span style="color: #008000"&gt;// grab the size of the current monitor&lt;/span&gt;
    Rectangle region = Screen.AllScreens[i].Bounds;

    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(screenBitmap[i] != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
    {
        Matrix m = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Matrix();

        &lt;span style="color: #008000"&gt;// rotate the bitmap about the center&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Properties.Settings.Default.Rotate)
            m.RotateAt(angle, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Point((Screen.AllScreens[i].Bounds.Width / 2), (Screen.AllScreens[i].Bounds.Height / 2)));

        &lt;span style="color: #008000"&gt;// scale the image based on the absolute value of cos (gives us a nice in/out effect with minimal effort&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Properties.Settings.Default.Zoom)
        {
            scale = Math.Abs((&lt;span style="color: #0000ff"&gt;float&lt;/span&gt;)Math.Cos(scaleIndex));
            m.Scale(scale, scale);
        }

        &lt;span style="color: #008000"&gt;// center the image no matter what its size is&lt;/span&gt;
        m.Translate(Screen.AllScreens[i].Bounds.Left + (Screen.AllScreens[i].Bounds.Width * (1.0f - scale)/2), Screen.AllScreens[i].Bounds.Top + (Screen.AllScreens[i].Bounds.Height * (1.0f - scale)/2), MatrixOrder.Append);

        &lt;span style="color: #008000"&gt;// assign our transformation matrix&lt;/span&gt;
        e.Graphics.Transform = m;

        &lt;span style="color: #008000"&gt;// draw it&lt;/span&gt;
        e.Graphics.DrawImage(screenBitmap[i], 0, 0);

        &lt;span style="color: #008000"&gt;// increment our values&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Properties.Settings.Default.Zoom)
            scaleIndex += 0.07f;

        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Properties.Settings.Default.Rotate)
            angle += 2.0f;
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/div&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;' rotation angle&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; angle &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Single&lt;/span&gt; = 0.0f

&lt;span style="color: #008000"&gt;' scale indexer&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; scaleIndex &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Single&lt;/span&gt; = 0.0

&lt;span style="color: #008000"&gt;' black background&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.BackColor = Color.Black

&lt;span style="color: #008000"&gt;' for each monitor, draw the effect&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;For&lt;/span&gt; i &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = 0 &lt;span style="color: #0000ff"&gt;To&lt;/span&gt; screenBitmap.Length - 1
    &lt;span style="color: #008000"&gt;' grab the size of the current monitor&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; region &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Rectangle = Screen.AllScreens(i).Bounds

    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Not&lt;/span&gt; screenBitmap(i) &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; m &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Matrix = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Matrix()

        &lt;span style="color: #008000"&gt;' rotate the bitmap about the center&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; My.Settings.&lt;span style="color: #0000ff"&gt;Default&lt;/span&gt;.Rotate &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
            m.RotateAt(angle, &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Point((Screen.AllScreens(i).Bounds.Width / 2), (Screen.AllScreens(i).Bounds.Height / 2)))
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' scale the image based on the absolute value of cos (gives us a nice in/out effect with minimal effort&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; My.Settings.&lt;span style="color: #0000ff"&gt;Default&lt;/span&gt;.Zoom &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
            scale = Math.Abs(&lt;span style="color: #0000ff"&gt;CSng&lt;/span&gt;(Math.Cos(scaleIndex)))
            m.Scale(scale, scale)
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' center the image no matter what its size is&lt;/span&gt;
        m.Translate(Screen.AllScreens(i).Bounds.Left + (Screen.AllScreens(i).Bounds.Width * (1.0f - scale)/2), Screen.AllScreens(i).Bounds.Top + (Screen.AllScreens(i).Bounds.Height * (1.0f - scale)/2), MatrixOrder.Append)

        &lt;span style="color: #008000"&gt;' assign our transformation matrix&lt;/span&gt;
        e.Graphics.Transform = m

        &lt;span style="color: #008000"&gt;' draw it&lt;/span&gt;
        e.Graphics.DrawImage(screenBitmap(i), 0, 0)

        &lt;span style="color: #008000"&gt;' increment our values&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; My.Settings.&lt;span style="color: #0000ff"&gt;Default&lt;/span&gt;.Zoom &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
            scaleIndex += 0.07f
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; My.Settings.&lt;span style="color: #0000ff"&gt;Default&lt;/span&gt;.Rotate &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
            angle += 2.0f
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; i
&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;The code above starts out by setting the background of the window to black.&amp;nbsp; Then for each monitor, an affect is applied.&amp;nbsp; If rotation is enabled, the bitmap is rotated by an ever-increasing angle parameter about the screen's center point.&amp;nbsp; If scaling is enabled, the image is scaled based on the absolute value of the cosine of an ever increasing value, starting at 0.&amp;nbsp; As you may recall from high-school trig, cos(0)&amp;nbsp;= 1.&amp;nbsp; Starting here, will start our scaling factor at 1, which will provide no change.&amp;nbsp; By increasing the value passed to the &lt;strong&gt;cos&lt;/strong&gt; method, we will get decreasing values to 0 after which we will get values which are negative.&amp;nbsp; By taking the absolute value of these numbers, we get a series of decreasing/increasing numbers between 0 and 1.&lt;/p&gt;
&lt;p&gt;With the scale and rotation worked out, the images are then translated to the center of the screen before being drawn, which is necessary due to the scaling procedure.&lt;/p&gt;
&lt;p&gt;The final calculated matrix is passed to the &lt;strong&gt;Graphics.Transform&lt;/strong&gt; property and the resulting image is finally drawn to the screen, after which the scale and rotation factors are incremented.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;b&gt;The Scheduler&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;The final piece of the puzzle was to allow a user to select the date and time that the animation would start on the victim’s PC. I created a simple configuration dialog box that is displayed the first time the application is run. The dialog allows the person setting up the application to choose the date and time the animation should be fired, as well as the effects to run. 
&lt;p&gt;&lt;a href="http://www.coding4fun.net/images/AprilFoolsDayApplication_C903/config2.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="173" src="http://www.coding4fun.net/images/AprilFoolsDayApplication_C903/config_thumb.png" width="230" border="0"&gt;&lt;/a&gt; 
&lt;p&gt;These settings are&amp;nbsp;saved using the &lt;b&gt;Settings&lt;/b&gt; object of the project. This way, the user can put the application in the startup group, or create a registry key to load it on startup, so if the PC is rebooted before the desired time is reached, the application will restart and wait for the time to occur. 
&lt;p&gt;Settings can be added by right-clicking the project in the &lt;b&gt;Solution Explorer&lt;/b&gt; and choosing &lt;b&gt;Properties&lt;/b&gt;. Select the &lt;b&gt;Settings&lt;/b&gt; tab and a new value can be entered. The one for this application looks like the following: 
&lt;p&gt;&lt;a href="http://www.coding4fun.net/images/AprilFoolsDayApplication_C903/settings8.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="227" src="http://www.coding4fun.net/images/AprilFoolsDayApplication_C903/settings_thumb2.png" width="480" border="0"&gt;&lt;/a&gt; 
&lt;p&gt;Now, on application startup, the application’s &lt;b&gt;Settings&lt;/b&gt; can be checked to determine if the configuration dialog needs to be shown, or just wait for the time specified. 
&lt;p&gt;When the application is started, a scheduler timer is created which ticks every minute. The &lt;b&gt;Tick &lt;/b&gt;method for this timer looks at the current time, and if it is greater than or equal to the specified time, it will disable the scheduler timer, maximize the hidden window, take the screen captures,&amp;nbsp;and start the animation timer, which will automatically start the animation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;// called once per minute to check whether it's time to run the show&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; tmrScheduler_Tick(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
{
    &lt;span style="color: #008000"&gt;// if the current time is greater than the time set by the user&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(DateTime.Now &amp;gt;= Properties.Settings.Default.Time)
    {
        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; Screen.AllScreens.Length; i++)
        {
            &lt;span style="color: #008000"&gt;// grab the size of the current monitor&lt;/span&gt;
            Rectangle region = Screen.AllScreens[i].Bounds;

            &lt;span style="color: #008000"&gt;// create a bitmap of that size&lt;/span&gt;
            screenBitmap[i] = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Bitmap(region.Width, region.Height, PixelFormat.Format32bppArgb);

            &lt;span style="color: #008000"&gt;// copy the current screen image to the bitmap for the current monitor&lt;/span&gt;
            Graphics bitmapGraphics = Graphics.FromImage(screenBitmap[i]);
            bitmapGraphics.CopyFromScreen(region.Left, region.Top, 0, 0, region.Size);
        }

        &lt;span style="color: #008000"&gt;// bring up the window&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.WindowState = FormWindowState.Normal;

        &lt;span style="color: #008000"&gt;// cover all monitors with one gigantic window&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Location = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Point(fullSize.Left, fullSize.Top);
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Size = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Size(fullSize.Width, fullSize.Height);

        &lt;span style="color: #008000"&gt;// disable this timer&lt;/span&gt;
        tmrScheduler.Enabled = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;

        &lt;span style="color: #008000"&gt;// enable the animation timer&lt;/span&gt;
        tmrAnim.Enabled = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;

        &lt;span style="color: #008000"&gt;// bring it to the top&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.BringToFront();
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/div&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;' called once per minute to check whether it's time to run the show&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; tmrScheduler_Tick(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; EventArgs) &lt;span style="color: #0000ff"&gt;Handles&lt;/span&gt; tmrScheduler.Tick
    &lt;span style="color: #008000"&gt;' if the current time is greater than the time set by the user&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; DateTime.Now &amp;gt;= My.Settings.&lt;span style="color: #0000ff"&gt;Default&lt;/span&gt;.Time &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; i &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = 0 &lt;span style="color: #0000ff"&gt;To&lt;/span&gt; Screen.AllScreens.Length - 1
            &lt;span style="color: #008000"&gt;' grab the size of the current monitor&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; region &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Rectangle = Screen.AllScreens(i).Bounds

            &lt;span style="color: #008000"&gt;' create a bitmap of that size&lt;/span&gt;
            screenBitmap(i) = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Bitmap(region.Width, region.Height, PixelFormat.Format32bppArgb)

            &lt;span style="color: #008000"&gt;' copy the current screen image to the bitmap for the current monitor&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; bitmapGraphics &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Graphics = Graphics.FromImage(screenBitmap(i))
            bitmapGraphics.CopyFromScreen(region.Left, region.Top, 0, 0, region.Size)
        &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; i

        &lt;span style="color: #008000"&gt;' bring up the window&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.WindowState = FormWindowState.Normal

        &lt;span style="color: #008000"&gt;' cover all monitors with one gigantic window&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.Location = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Point(fullSize.Left, fullSize.Top)
        &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.Size = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Size(fullSize.Width, fullSize.Height)

        &lt;span style="color: #008000"&gt;' disable this timer&lt;/span&gt;
        tmrScheduler.Enabled = &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' enable the animation timer&lt;/span&gt;
        tmrAnim.Enabled = &lt;span style="color: #0000ff"&gt;True&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' bring it to the top&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.BringToFront()
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;h3&gt;&lt;b&gt;Deployment&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;As mentioned earlier, one of the main goals of this project was to have an extremely easily deployable application. In order to achieve this, all code was kept inside the framework with no dependencies on things like Managed DirectX. 
&lt;p&gt;When you are ready to&amp;nbsp;annoy your friend, simply copy the AprilFoolsDay.exe and AprilFoolsDay.exe.config files to his or her PC. (You may want to enlist someone as the “lookout” so you don’t get caught while doing so!) Create a shortcut to it in the Startup program group, or set it up to run via the registry using the following key for the logged in user: 
&lt;ul&gt;
&lt;li&gt;HKCU\Software\Microsoft\Windows\CurrentVersion\Run&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Simply create a new string key with any Name, and a Data value of the path to the executable. 
&lt;p&gt;Next, start the application once on their PC to setup the date and time for the show to begin. Once that is done, the application will remain running in the background. If the PC is restarted, and the application is setup to run at startup as described above, it will start silently and remain running, waiting for the date and time specified.&lt;/p&gt;
&lt;p&gt;If you need to reset the configuration for any reason, simply run the application from the command line with the &lt;strong&gt;-config&lt;/strong&gt; switch and it will display the configuration dialog box again.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;b&gt;Summary&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;And there we have it. A very simple application requiring very little code that will elicit quite a reaction from your victim. The code can be very easily modified to include new features and&amp;nbsp;different animation effects.&amp;nbsp; Give it a try!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;b&gt;Thanks&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;A special thank you&amp;nbsp;to&amp;nbsp;&lt;a href="http://www.markzaugg.com/" target="_blank"&gt;Mark Zaugg&lt;/a&gt;&amp;nbsp;for testing on a few machines outside my house to ensure things were working as expected.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Bio&lt;/h3&gt;
&lt;p&gt;Though Brian is a recognized .NET expert with over 6 years experience developing .NET solutions, and over 9 years of professional experience architecting and developing solutions using Microsoft technologies and platforms, he has been "coding for fun" for as long as he can remember.&amp;nbsp; Outside the world of .NET and&amp;nbsp;business applications, Brian enjoys developing&amp;nbsp;both hardware and software projects in the areas of gaming, robotics, and&amp;nbsp;whatever else strikes his fancy for the next ten minutes.&amp;nbsp;He rarely passes up an opportunity to dive into a C/C++&amp;nbsp;or assembly language project.&amp;nbsp; You can reach Brian via his blog at &lt;a href="http://www.brianpeek.com/" target="_blank"&gt;http://www.brianpeek.com/&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1991785" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx">events</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/april+fools+day/default.aspx">april fools day</category></item><item><title>Have You Been Naughty or Nice?</title><link>http://blogs.msdn.com/coding4fun/archive/2006/12/14/1287528.aspx</link><pubDate>Thu, 14 Dec 2006 21:47:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1287528</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/1287528.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=1287528</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=1287528</wfw:comment><description> &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;span id="c4fmetadata"&gt; &lt;table cellspacing="0" cellpadding="1" width="100%" border="0"&gt; &lt;tbody&gt; &lt;tr class="entry_overview"&gt; &lt;td width="50"&gt;&lt;a href="http://www.coding4fun.net/images/Hesknowsifyouvebeennaughtyorniceevenonli_C826/thumb5.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="50" src="http://www.coding4fun.net/images/Hesknowsifyouvebeennaughtyorniceevenonli_C826/thumb_thumb1.jpg" width="50" border="0"&gt;&lt;/a&gt; &lt;/td&gt; &lt;td&gt;&lt;span class="entry_description"&gt;Is Santa paying you a visit this year? Find out how naughty or nice you are based on what you say on your blog or personal web site!&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td colspan="2"&gt; &lt;div class="entry_author"&gt;Arian Kulp&lt;/div&gt; &lt;div class="entry_company"&gt;&lt;a href="http://www.ariankulp.com"&gt;Arian Kulp's Blog&lt;/a&gt;&lt;/div&gt;&lt;br&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Difficulty: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Intermediate&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Time Required:&lt;/b&gt; &lt;span class="entry_details_input"&gt;1-3 hours&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Cost: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Free&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Software: &lt;/b&gt;&lt;span class="entry_details_input"&gt;&lt;a href="http://msdn.com/express/"&gt;Visual Basic or Visual C# Express Editions&lt;/a&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Hardware: &lt;/b&gt;&lt;span class="entry_details_input"&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;strong&gt;Download: &lt;/strong&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=266250"&gt;Sample Code&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt; &lt;blockquote&gt; &lt;p&gt;He's making a list and checking it twice,&lt;br&gt;Gonna find out who's naughty and nice,&lt;br&gt;Santa Claus is coming to town.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Did this song creep you out as a kid?&amp;nbsp; It did me!&amp;nbsp; Now that you're all grown up (well, some of us anyway!) you may think that it doesn't apply to you anymore.&amp;nbsp; Do you really want to take that chance though?&amp;nbsp; I didn't think so!&amp;nbsp; This article helps to evaluate your level of naughtiness/niceness based on your blog (or other personal web site).  &lt;p&gt;Read the article for some background information, then explore the code yourself.&amp;nbsp; This application uses the &lt;strong&gt;BackgroundWorker&lt;/strong&gt;, &lt;strong&gt;WebClient&lt;/strong&gt;, and works with regular expressions with the &lt;strong&gt;Regex&lt;/strong&gt; object.&amp;nbsp; In order to open the project, you will need Visual Studio Express Editions (either C# or Visual Basic) or higher.&amp;nbsp; You can download the Express editions for free from &lt;a href="http://msdn.microsoft.com/vstudio/express"&gt;here&lt;/a&gt;.  &lt;h2&gt;Background&lt;/h2&gt; &lt;p&gt;An ancient Chinese proverb states that "The entries in your blog reveal your inner self."&amp;nbsp; Even though I just made that up, it's no less true.&amp;nbsp; Are you grumpy, happy, hopeful, crazy?&amp;nbsp; Chances are it's obvious from your blog posts.&amp;nbsp; This application will take a URL, scan it for a list of "naughty" and "nice" words, and come up with a score of niceness.&amp;nbsp; But beware: pages linked from the given URL will also be scanned and taken into account.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.coding4fun.net/images/Hesknowsifyouvebeennaughtyorniceevenonli_C826/image19.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="176" src="http://www.coding4fun.net/images/Hesknowsifyouvebeennaughtyorniceevenonli_C826/image18.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;b&gt;(click image to zoom)&lt;/b&gt;&lt;/p&gt; &lt;h2&gt;Downloading the URL&lt;/h2&gt; &lt;p&gt;So the first step is to download the given URL.&amp;nbsp; This can be accomplished by opening a socket, issuing an HTTP GET request, and reading back the resulting stream of bytes one at a time.&amp;nbsp; On the other hand, it can also be performed in two lines of code using the &lt;strong&gt;System.Net.WebClient&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;object.&amp;nbsp; For me, the choice was simple.&amp;nbsp; The &lt;strong&gt;WebClient&lt;/strong&gt; has a number of methods to download a file synchronously or asynchronously, either as a string, a byte array, or directly to a file.&amp;nbsp; Once the object is instantiated, a single line of code does the actual work.&amp;nbsp; It's so easy, you'll be adding URL download functionality into every application before you know it!&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;NOTE: &lt;/strong&gt;You must specify a complete URL, that is, beginning with HTTP.&amp;nbsp; You won't get an error otherwise, it just won't appear to work right.&lt;/p&gt; &lt;p&gt;&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;&lt;b&gt;Visual Basic&lt;/b&gt; 
&lt;p&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Dim&lt;/span&gt; wc &lt;span class="kwrd"&gt;As&lt;/span&gt; WebClient = &lt;span class="kwrd"&gt;New&lt;/span&gt; WebClient
body = wc.DownloadString(url)&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Visual C#&lt;/b&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;WebClient wc = &lt;span class="kwrd"&gt;new&lt;/span&gt; WebClient();
body = wc.DownloadString(url);&lt;/pre&gt;
&lt;h2&gt;Searching for Patterns&lt;/h2&gt;
&lt;p&gt;Once you have the contents of the URL in a string, you can anything with it as with any other string.&amp;nbsp; Perform &lt;strong&gt;IndexOf&lt;/strong&gt; searches, save it to a database, or apply regular expressions.&amp;nbsp; This is the use of interest for this application.&amp;nbsp; Regular expression support is found in the &lt;strong&gt;System.Text.RegularExpressions&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;namespace with the &lt;strong&gt;Regex&lt;/strong&gt; object.&amp;nbsp; Using the &lt;strong&gt;Regex &lt;/strong&gt;object is pretty easy, but coming up with the expression itself can be a challenge.&lt;/p&gt;
&lt;p&gt;If you haven't used regular expressions before, you may want to take a few minutes to read about them.&amp;nbsp; I good place to start is the MSDN reference page, &lt;a href="http://msdn.microsoft.com/library/en-us/cpguide/html/cpconcomregularexpressions.asp"&gt;.NET Framework Regular Expressions&lt;/a&gt;.&amp;nbsp; Unfortunately, regular expressions aren't very intuitive at first (or ever for some people!).&amp;nbsp; Creating your own expression can be difficult, but you can often find pre-built ones online.&amp;nbsp; Note that regular expressions are used in conjunction with string verification, formatting, searching, and replacing.&amp;nbsp; This application will use three different expressions.&amp;nbsp; One will be used to search for "nice" keywords, another for "naughty" keywords.&amp;nbsp; The third expression will locate hyperlinks based on the &lt;strong&gt;href&lt;/strong&gt; attribute of the &lt;strong&gt;a&lt;/strong&gt; element found in HTML.&lt;/p&gt;
&lt;p&gt;Creating a &lt;strong&gt;Regex&lt;/strong&gt; object incurs some overhead, not only from object creation, but also from parsing the expression.&amp;nbsp; To minimize this, all three &lt;strong&gt;Regex&lt;/strong&gt; objects are created when the application starts up.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Dim&lt;/span&gt; REGEX_NICE_WORDS &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;"love|great|good|rocks|awesome|nice"&lt;/span&gt;
&lt;span class="kwrd"&gt;Dim&lt;/span&gt; REGEX_NAUGHTY_WORDS &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;"damn|sucks|hate|stupid|dumb|bad"&lt;/span&gt;
&lt;span class="kwrd"&gt;Dim&lt;/span&gt; REGEX_HYPERLINKS &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;"href\s*=\s*(?:\"&lt;/span&gt;&lt;span class="str"&gt;""&lt;/span&gt;&lt;span class="str"&gt;"(?&amp;lt;1&amp;gt;[^"&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="str"&gt;"|(?&amp;lt;1&amp;gt;\S+))"&lt;/span&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Private&lt;/span&gt; urlRegex, niceregex, naughtyregex &lt;span class="kwrd"&gt;As&lt;/span&gt; Regex&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Visual C#&lt;/b&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; REGEX_NICE_WORDS = &lt;span class="str"&gt;"love|great|good|rocks|awesome|nice"&lt;/span&gt;;
&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; REGEX_NAUGHTY_WORDS = &lt;span class="str"&gt;"damn|sucks|hate|stupid|dumb|bad"&lt;/span&gt;;
&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; REGEX_HYPERLINKS = &lt;span class="str"&gt;"href\\s*=\\s*(?:\"\"(?&amp;lt;1&amp;gt;[^\"\"]*)\"\"|(?&amp;lt;1&amp;gt;\\S+))"&lt;/span&gt;;

&lt;span class="kwrd"&gt;private&lt;/span&gt; Regex niceRegex, naughtyRegex, urlRegex;&lt;/pre&gt;
&lt;p&gt;The basic flow will be: search for nice words, search for naughty keywords, search for hyperlinks, repeat the nice/naughty search for each linked page.&amp;nbsp; Linked pages are not scanned for additional links to avoid overload.&amp;nbsp; As it is, some sites already take a full minute to process!&amp;nbsp; The process of downloading a page then performing the searches is contained in the &lt;strong&gt;DetermineScore &lt;/strong&gt;method.&lt;/p&gt;
&lt;p&gt;In order to actually perform the search, invoke the &lt;strong&gt;Matches&lt;/strong&gt; method.&amp;nbsp; This returns a &lt;strong&gt;MatchCollection&lt;/strong&gt; object for iteration.&amp;nbsp; There's no need to iterate the actual words found, so the &lt;strong&gt;Count&lt;/strong&gt; property is sufficient:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;niceCount = niceregex.Matches(body).Count
naughtyCount = naughtyregex.Matches(body).Count&lt;/pre&gt;&lt;b&gt;Visual C#&lt;/b&gt; &lt;pre class="csharpcode"&gt;niceCount = niceRegex.Matches(body).Count;
naughtyCount = naughtyRegex.Matches(body).Count;
&lt;/pre&gt;
&lt;p&gt;Another one line of code performing lots of work!&amp;nbsp; If you needed the information, you could then use the returned &lt;strong&gt;MatchCollection&lt;/strong&gt; to determine specifically which words were returned, along with much other information about each match.&amp;nbsp; The expression for nice and naughty words is simple: the vertical pipe (bar) acts like an OR Boolean operator.&amp;nbsp; In other words, the regular expression parser will scan the entire input string (the downloaded HTML) and add a &lt;strong&gt;Match&lt;/strong&gt; object each time one of the words is found.&lt;/p&gt;
&lt;h2&gt;Looking a Level Deeper&lt;/h2&gt;
&lt;p&gt;After analyzing the given URL, it's time to take a look at linked pages.&amp;nbsp; After all, the types of sites you link to also say something about how naughty or nice you probably are!&amp;nbsp; That third regular expression is much more complex than the first two.&amp;nbsp; Showing it again, we have:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;href\s*=\s*(?:""(?&amp;lt;1&amp;gt;[^""]*)""|(?&amp;lt;1&amp;gt;\S+))&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This is complicated a bit by the way that strings must be escaped in Visual C# and Visual Basic.&amp;nbsp; In both languages, you can't just have quotes within a quoted string (you'll notice that this expression is slight different in the VB and C# code samples above).&amp;nbsp; In C#, you precede the double&amp;nbsp;quote with a backslash (\").&amp;nbsp; If you actually need a backslash, you need to double that as well (\\).&amp;nbsp; In Visual Basic, you double the doublequote ("").&amp;nbsp; What does this mess mean?&amp;nbsp; Well, suffice to say that is looking for the &lt;strong&gt;href&lt;/strong&gt; attribute, and the quotes and brackets after it.&amp;nbsp; Unfortunately, the resulting match is always more than we actually want.&amp;nbsp; For example, a link to my site would be returned as:&lt;/p&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;p&gt;href="http://ariankulp.com/rss.aspx"&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;It also returns returns relative links, CSS/RSS links, and others that aren't all that interesting.&amp;nbsp; It's easy to filter out the relative links by checking to see if each match begins with &lt;strong&gt;href="http&lt;/strong&gt;.&amp;nbsp; The CSS/RSS links, if using an absolute host, are more complicated, so I don't filter them out.&amp;nbsp; For each valid match found, I call the &lt;strong&gt;DetermineScore &lt;/strong&gt;method to count up naughty and nice words.&amp;nbsp; Note that the scores on linked pages are cut in half.&amp;nbsp; More weight is given to your own site!&lt;/p&gt;
&lt;h2&gt;Putting it All Together&lt;/h2&gt;
&lt;p&gt;Performing all of the URL downloads and pattern matching takes some time.&amp;nbsp; A site with many links can really slow things down.&amp;nbsp; When you click the button to start things off, any work that you perform will occur on the user interface thread.&amp;nbsp; All of a sudden, the application is unresponsive.&amp;nbsp; The solution to this is to run the analyzing in a separate, background&amp;nbsp;thread.&amp;nbsp; The &lt;strong&gt;BackgroundWorker&lt;/strong&gt; object makes this easy.&amp;nbsp; When you invoke the &lt;strong&gt;RunWorkerAsync&lt;/strong&gt; method, the &lt;strong&gt;DoWork&lt;/strong&gt; event fires on a different thread.&amp;nbsp; The event handler then makes the necessary calls to download and analyze the given URL and discovered URL's.&lt;/p&gt;
&lt;p&gt;As each link is analyzed, progress is reported by raising the &lt;strong&gt;ProgressChanged&lt;/strong&gt; event.&amp;nbsp; This is responsible for adding the links, along with naughty/nice count, to the &lt;strong&gt;ListView&lt;/strong&gt; control.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Dim&lt;/span&gt; ls &lt;span class="kwrd"&gt;As&lt;/span&gt; LinkScore = &lt;span class="kwrd"&gt;CType&lt;/span&gt;(e.UserState, LinkScore)
&lt;span class="kwrd"&gt;Dim&lt;/span&gt; lvi &lt;span class="kwrd"&gt;As&lt;/span&gt; ListViewItem = scoresListView.Items.Add(ls.Url)

lvi.SubItems.AddRange(&lt;span class="kwrd"&gt;New&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;() {ls.Good.ToString, ls.Bad.ToString})

overallProgressBar.Style = ProgressBarStyle.Blocks
overallProgressBar.Value = e.ProgressPercentage&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Visual C#&lt;/b&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;LinkScore ls = e.UserState &lt;span class="kwrd"&gt;as&lt;/span&gt; LinkScore;

ListViewItem lvi = scoresListView.Items.Add(ls.Url);
lvi.SubItems.AddRange(
    &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] { ls.Good.ToString(), ls.Bad.ToString() });

overallProgressBar.Style = ProgressBarStyle.Blocks;
overallProgressBar.Value = e.ProgressPercentage;
&lt;/pre&gt;
&lt;p&gt;Clicking &lt;strong&gt;Cancel&lt;/strong&gt; calls the &lt;strong&gt;CancelAsync&lt;/strong&gt; method.&amp;nbsp; The worker thread periodically checks the &lt;strong&gt;CancellationRequested&lt;/strong&gt; flag to exit early if necessary.&amp;nbsp; While the initial link is being downloaded, a &lt;strong&gt;ProgressBar&lt;/strong&gt; control goes into marquee mode (think &lt;em&gt;Knight Rider&lt;/em&gt;!).&amp;nbsp; It changes to a standard progress bar as discovered links are analyzed.&amp;nbsp; Finally, the &lt;strong&gt;RunWorkerCompleted&lt;/strong&gt; event fires when everything is done (based on the &lt;strong&gt;DoWork&lt;/strong&gt; event handler completing).&amp;nbsp; This updates the progress percentage, enables the &lt;strong&gt;Cancel&lt;/strong&gt; button, and hides the progress bar.&lt;/p&gt;
&lt;h2&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;The application isn't all that useful, but it's fun!&amp;nbsp; It could easily be extended to perform different actions on discovered pages, or simply to search for different keywords.&amp;nbsp; Several enhancements that would be fairly easy would be:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add a checkbox to prevent linked pages from being counted.&amp;nbsp; This would speed things up. 
&lt;li&gt;Add an options page to edit naughty/nice keywords and tweak other settings. 
&lt;li&gt;Restrict the number of links to follow.&amp;nbsp; If the given URL has links to 200 other pages, it may never finish! 
&lt;li&gt;Better filtering of links.&amp;nbsp; As I mentioned, resources like RSS or CSS don't need to be downloaded.&amp;nbsp; Links on the same site may not be needed either.&amp;nbsp; Checking for the same base URL would be a pretty easy addition. 
&lt;li&gt;Create multiple worker threads to share the load of analyzing linked pages.&amp;nbsp; This is a good scenario for parallelizing.&lt;/li&gt;&lt;/ol&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope that you had fun with this application.&amp;nbsp; It was fun coming up with a naughty-or-nice formula!&amp;nbsp; I struggled a bit with the best balance.&amp;nbsp; It's not perfect, but it works pretty well.&amp;nbsp; If you have a better approach, by all means tweak it.&amp;nbsp; Best of all, have fun!&lt;/p&gt;
&lt;p&gt;Get started by downloading &lt;a href="http://msdn.microsoft.com/vstudio/express"&gt;Visual Studio Express&lt;/a&gt; and download the sample code today.&lt;/p&gt;
&lt;hr&gt;

&lt;p&gt;Arian Kulp is an independent software developer and writer working in the Midwest.&amp;nbsp; He has been coding since the fifth grade on various platforms, and also enjoys photography, nature, and spending time with his family.&amp;nbsp; Arian can be reached through his web site at &lt;a href="http://www.ariankulp.com"&gt;http://www.ariankulp.com&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1287528" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx">events</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/holiday/default.aspx">holiday</category></item><item><title>Holiday Gift Guide 2006</title><link>http://blogs.msdn.com/coding4fun/archive/2006/12/06/1228621.aspx</link><pubDate>Thu, 07 Dec 2006 08:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1228621</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/1228621.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=1228621</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=1228621</wfw:comment><description>&lt;P&gt;Tired of giving socks every year to your favorite engineer or technology elitist? Coding4Fun has come up with a holiday gift guide of items that are sure to make them glee with joy. We’ve cranked up the geek-factor and have tried to come up with the biggest list of programmable presents on the Web! &amp;nbsp;If you like the guide, &lt;A href="http://www.digg.com/submit?url=http://msdn.microsoft.com/coding4fun/archive/article.aspx?articleid=1228621&amp;amp;title=Holiday%20Gift%20Guide%202006" mce_href="http://www.digg.com/submit?url=http://msdn.microsoft.com/coding4fun/archive/article.aspx?articleid=1228621&amp;amp;title=Holiday%20Gift%20Guide%202006"&gt;Digg Us&lt;/A&gt;. 
&lt;P&gt;Do you know of a programmable present that wasn’t listed here? &lt;A href="mailto:code4fun@microsoft.com" mce_href="mailto:code4fun@microsoft.com"&gt;Email us&lt;/A&gt; and we’ll get it added to our list. 
&lt;P&gt;The holiday guide is broken down into 5 sections. Programmable Hardware and Gadgets, Programmable Robots, Programmable Games, Cool Software Tools, and Top 10 Presents for Developers 
&lt;P&gt;&lt;!--
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=4539&amp;amp;postid=1228621#hardware" mce_href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=4539&amp;amp;postid=1228621#hardware"&gt;Programmable Hardware and Gadgets &lt;/A&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=4539&amp;amp;postid=1228621#robots"&gt;Programmable Robotics &lt;/A&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=4539&amp;amp;postid=1228621#games"&gt;Programmable Games &lt;/A&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=4539&amp;amp;postid=1228621#tools"&gt;Cool Software Tools &lt;/A&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=4539&amp;amp;postid=1228621#topten"&gt;Top 10 Presents for Developers &lt;/A&gt;--&gt;
&lt;H3&gt;&lt;A class="" title=hardware name=hardware&gt;&lt;/A&gt;&lt;B&gt;Programmable Hardware and Gadgets&lt;/B&gt; &lt;/H3&gt;
&lt;P&gt;Enjoy tinkering?&amp;nbsp; Think that the orginary can be modified to do something different with a little effort?&amp;nbsp; This entire section of gifts are items one can program. The range from webcams to disco floor parts to cell phones. 
&lt;TABLE class="" cellSpacing=5 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=240 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/xbox360controller5.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/xbox360controller5.jpg"&gt; Wireless Xbox 360 Controller for Windows&lt;/B&gt; 
&lt;P&gt;The newly released wireless controller can be used to play both Xbox 360 and Windows PC games, and best of all, you can program with it too. In fact, certain applications, like Virtual Earth 3D already include support for the Xbox 360 controller so you’ll be able to use your controller to literally fly around the world! 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $37.99 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.amazon.com/Microsoft-VAMSFT-882224022408-Wireless-Controller/dp/B000B6MLUA/sr=8-2/qid=1165259673/ref=pd_bbs_sr_2/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames" mce_href="http://www.amazon.com/Microsoft-VAMSFT-882224022408-Wireless-Controller/dp/B000B6MLUA/sr=8-2/qid=1165259673/ref=pd_bbs_sr_2/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames"&gt;Wireless Xbox 360 Controller&lt;/A&gt; on Amazon.com 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: The XNA Framework includes full support for Xbox 360 controllers for Windows and the Web using the XInput class. To learn the basics of programming your XNA controller, check out Paul Stubbs excellent &lt;A href="http://blogs.msdn.com/pstubbs/articles/531008.aspx" mce_href="http://blogs.msdn.com/pstubbs/articles/531008.aspx"&gt;Xbox 360 controller article&lt;/A&gt; as well as the newly updated version ported to work with the &lt;A href="http://blogs.msdn.com/pstubbs/archive/2006/08/31/733031.aspx" mce_href="http://blogs.msdn.com/pstubbs/archive/2006/08/31/733031.aspx"&gt;XNA Framework&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=160 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/irman_front14.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/irman_front14.jpg"&gt; IrMan&lt;/B&gt;&lt;BR&gt;Infrared man (Irman) is a small device that allows you to control your PC with the remote from your TV, VCR, CD or Stereo. You can use it to programmatically control any applications on your PC!&lt;BR&gt;&lt;B&gt;Cost&lt;/B&gt;: $40&lt;BR&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.evation.com/irman/" mce_href="http://www.evation.com/irman/"&gt;IrMan Home Page&lt;/A&gt;&lt;BR&gt;&lt;B&gt;Code it&lt;/B&gt;: Duncan MacKenzie, the first Coding4Fun author, posted a &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncodefun/html/code4fun06272003.asp" mce_href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncodefun/html/code4fun06272003.asp"&gt;classic article&lt;/A&gt; on using an IrMan through a Pocket PC using Visual Studio .NET 2003. &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=240 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/wiiremote5.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/wiiremote5.jpg"&gt; Nintendo Wii Remote&lt;/B&gt; 
&lt;P&gt;Why the Wii Remote without the Nintendo Wii? Because some &lt;A href="http://www.hackaday.com/2006/12/01/hacking-wiimote-bluetooth/" mce_href="http://www.hackaday.com/2006/12/01/hacking-wiimote-bluetooth/"&gt;clever hackers figure &lt;/A&gt;out how to get information out of it. The Wii Remote is actually a Bluetooth device that has an XYZ accelerometer in it. With some computing, one is able to figure out the tilt of the controller. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $53.67 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.amazon.com/Nintendo-Wii-Remote-Controller/dp/B000IMWK2G/sr=8-1/qid=1165274081/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames" mce_href="http://www.amazon.com/Nintendo-Wii-Remote-Controller/dp/B000IMWK2G/sr=8-1/qid=1165274081/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames"&gt;Nintendo Wii Remote&lt;/A&gt; on Amazon.com&lt;BR&gt;&lt;B&gt;Code it&lt;/B&gt;: [Link coming soon]&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=200 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/PE830_rg16.jpg" width=200 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/PE830_rg16.jpg"&gt; Pedometer with PC Download&lt;/B&gt; &lt;/P&gt;
&lt;P&gt;Geek out, even when your exercising using this built-in pedometer 
&lt;P&gt;&lt;B&gt;Cost: &lt;/B&gt;$59.99 
&lt;P&gt;&lt;B&gt;Get it:&lt;/B&gt; &lt;A href="http://www2.oregonscientific.com/shop/product.asp?cid=3&amp;amp;scid=10&amp;amp;pid=686" mce_href="http://www2.oregonscientific.com/shop/product.asp?cid=3&amp;amp;scid=10&amp;amp;pid=686"&gt;Pedometer with PC Download&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it:&lt;/B&gt; With the included PC download software, users can easily export the data into a database and easily track their progress. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=66 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/CFA635_YYE_Front_Backlight_On_43015.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/CFA635_YYE_Front_Backlight_On_43015.jpg"&gt; CrystalFontz LCD Displays&lt;BR&gt;&lt;/B&gt;Using the new Serial Port classes in the .NET Framework 2.0, you can create some pretty cool applications to display dynamic information on a CrystalFontz LCD display.&lt;BR&gt;&lt;B&gt;Cost&lt;/B&gt;: $60-$80&lt;BR&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.crystalfontz.com/" mce_href="http://www.crystalfontz.com/"&gt;CrystalFontz Home Page&lt;/A&gt;&lt;BR&gt;&lt;B&gt;Code it&lt;/B&gt;: Scott Hanselman has a &lt;A href="http://msdn.microsoft.com/coding4fun/hardware/misc/article.aspx?articleid=914453" mce_href="http://msdn.microsoft.com/coding4fun/hardware/misc/article.aspx?articleid=914453"&gt;great article that shows how to display&lt;/A&gt; what's playing in Windows Media Player on an LCD display and Kit George has a cool &lt;A href="http://gotdotnet.com/team/clr/bcl/demos/demos/zipfiles/SpaceInvadersCS.zip" mce_href="http://gotdotnet.com/team/clr/bcl/demos/demos/zipfiles/SpaceInvadersCS.zip"&gt;Space Invaders Console game demo&lt;/A&gt; that he hooked up to an LCD display to control how you fly the spacecraft. &lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=185 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/phidget6.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/phidget6.jpg"&gt; Phidgets&lt;/B&gt; 
&lt;P&gt;&lt;A href="http://www.phidgets.com/" mce_href="http://www.phidgets.com/"&gt;Phidgets&lt;/A&gt; are a low cost, easy to use building block that connects to your PC through USB. Through a very robust API, developing applications is quick and easy. They have RFID, electrical relays, Servos, LED, multiple different types of sensors, and even a Pan &amp;amp; Tilt Web Cam kit. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $75 and up 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: Scott Hanselman created a &lt;A href="http://msdn.microsoft.com/coding4fun/article.aspx?articleid=914024" mce_href="http://msdn.microsoft.com/coding4fun/article.aspx?articleid=914024"&gt;weather collection program&lt;/A&gt; and Brian Peek created a &lt;A href="http://msdn.microsoft.com/coding4fun/article.aspx?articleid=905480" mce_href="http://msdn.microsoft.com/coding4fun/article.aspx?articleid=905480"&gt;motion-detecting Halloween prank from one&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=150 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/aic25016.jpg" width=139 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/aic25016.jpg"&gt; Airlink Network Camera AIC 250 &lt;/B&gt;
&lt;P&gt;Enjoy full motion video over a wireless connection with this easy-to-setup Web cam with built-in support for DSL or Cable model DHCP. 
&lt;P&gt;&lt;B&gt;Cost: &lt;/B&gt;$99&lt;B&gt;&lt;/B&gt; 
&lt;P&gt;&lt;B&gt;Get it:&lt;/B&gt; &lt;A href="http://shop1.outpost.com/product/4600208?site=sr:SEARCH:MAIN_RSLT_PG" mce_href="http://shop1.outpost.com/product/4600208?site=sr:SEARCH:MAIN_RSLT_PG"&gt;Airlink Network Camera at Frys.com&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it: &lt;/B&gt;Scott Hanselman’s got a great article that shows how to &lt;A href="http://msdn.microsoft.com/coding4fun/hardware/video/article.aspx?articleid=912407" mce_href="http://msdn.microsoft.com/coding4fun/hardware/video/article.aspx?articleid=912407"&gt;programmatically detect motion&lt;/A&gt; using the AIC 250 Network Camera.&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=240 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/streets7.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/streets7.jpg"&gt; GPS Receiver with Microsoft Streets &amp;amp; Trips 2007 &lt;/B&gt;&lt;/P&gt;
&lt;P&gt;Where am I? With Microsoft Streets and Trips, it provides a turn-by-turn speech support and .NET integration. This software and GPS combo can be used with your laptop, Tablet PC, Windows Mobile device to find your way when asking for directions won’t do. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;&lt;B&gt;:&lt;/B&gt; $129.99 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;&lt;B&gt;:&lt;/B&gt; &lt;A href="http://www.amazon.com/exec/obidos/ASIN/B000HDOJUC/ref=nosim/3147335-20" mce_href="http://www.amazon.com/exec/obidos/ASIN/B000HDOJUC/ref=nosim/3147335-20"&gt;Streets and Trips 2006&lt;/A&gt; on Amazon.com 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;&lt;B&gt;:&lt;/B&gt; Scott Hanselman again comes to the rescue with a great article on &lt;A href="http://msdn.microsoft.com/coding4fun/hardware/misc/article.aspx?articleid=914453" mce_href="http://msdn.microsoft.com/coding4fun/hardware/misc/article.aspx?articleid=914453"&gt;how read data off of the GPS receiver&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=175 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/controller115.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/controller115.jpg"&gt; MAKE Controller Kit&lt;/B&gt; &lt;/P&gt;
&lt;P&gt;Need a relay controller? How about a device that is Ethernet ready? USB too? Need digital Inputs also? Don’t worry, MAKE has you covered with their MAKE controller. It has all of the above functionality and more. More so, it has API for .Net, Java, Max &amp;amp; Pd, Flash, C / C++. You can even network multiple controllers together to create a more complex device. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $149 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.makingthings.com/cgi-local/SoftCart.100.exe/online-store/scstore/c-MAKE_Controller_Kit.html?L+scstore+kmdj3248ff31f231+1172938304" mce_href="http://www.makingthings.com/cgi-local/SoftCart.100.exe/online-store/scstore/c-MAKE_Controller_Kit.html?L+scstore+kmdj3248ff31f231+1172938304"&gt;Make Controller Kit&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: The Make Controller Kit features a &lt;A href="http://www.makingthings.com/makecontrollerkit/guides/dotnet.html" mce_href="http://www.makingthings.com/makecontrollerkit/guides/dotnet.html"&gt;.NET library for easy programmability&lt;/A&gt; that can be used with any managed code language including VB, C#, and C++. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=150 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/CD_collection15.jpg" width=150 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/CD_collection15.jpg"&gt; Z-Wave PC SDK Starter Kit&lt;/B&gt; 
&lt;P&gt;Intermatic’s HomeSettings Lighting Control Starter Kit is an easy way to help automate your home. Want your lights to turn on at 7 pm or &lt;A href="http://msdn.microsoft.com/coding4fun/hardware/home/article.aspx?articleid=1088252" mce_href="http://msdn.microsoft.com/coding4fun/hardware/home/article.aspx?articleid=1088252"&gt;control your home entertainment system’s lighting&lt;/A&gt;, the Z-Wave makes it rather easy. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $149 not including discount for registered Express users 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.controlthink.com/zwavesdk.htm" mce_href="http://www.controlthink.com/zwavesdk.htm"&gt;Z-Wave PC SDK Starter Kit&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: The Z-Wave PC Starter Kit ships with the SDK, .NET Framework API and full documentation to get started. You can get help using the SDK on the &lt;A href="http://forums.controlthink.com/5/ShowForum.aspx" mce_href="http://forums.controlthink.com/5/ShowForum.aspx"&gt;ControlThink Forums&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=192 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/mc_200617.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/mc_200617.jpg"&gt; Learning Edition Microcontroller Kit &lt;/B&gt;
&lt;P&gt;Whether you’re young or old, learning the ins and outs of microcontrollers can be tricky. You can now learn the basics of microcontrollers including programming sensors, motors, resistors, microphones, diodes, capacitors and more. 
&lt;P&gt;&lt;B&gt;Cost:&lt;/B&gt; $149.95 
&lt;P&gt;&lt;B&gt;Get it:&lt;/B&gt; &lt;A href="http://www.thamesandkosmos.com/products/mc/mc.html" mce_href="http://www.thamesandkosmos.com/products/mc/mc.html"&gt;Microcontroller Kit Home Page&lt;/A&gt; (source: Wired Gift Guide) 
&lt;P&gt;&lt;B&gt;Code it:&lt;/B&gt; The kit includes built-in programmability for controlling your hardware. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=162 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/ellipse4.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/ellipse4.jpg"&gt;Disco Dance Floor Parts &lt;/B&gt;&lt;/P&gt;
&lt;P&gt;If you want your home to be disco’ed out, you can get the PCB hardware boards from the people over at MIT who originally designed it. They also have boards pre-constructed if surface soldering isn’t your forte for an additional cost.&amp;nbsp; Not sure on what types of LEDs to buy or how to do the cabling?&amp;nbsp; They have that too now! 
&lt;P&gt;&lt;B&gt;Cost: &lt;/B&gt;$35 to $450 dollars per board 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.dropoutdesign.com/ddf-parts.html" mce_href="http://www.dropoutdesign.com/ddf-parts.html"&gt;Dropout Design&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: You can’t go wrong with Clint Rutkas’s Coding4Fun article for how to &lt;A href="http://msdn.microsoft.com/coding4fun/article.aspx?articleid=918683" mce_href="http://msdn.microsoft.com/coding4fun/article.aspx?articleid=918683"&gt;build out your own disco dance floor&lt;/A&gt;!&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=202 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/EC.DEI.SCH1W17.jpg" width=160 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/EC.DEI.SCH1W17.jpg"&gt; Sirius Conductor Satellite Radio Tuner&lt;/B&gt; 
&lt;P&gt;For &lt;A href="http://www.sirius.com/" mce_href="http://www.sirius.com/"&gt;Sirius&lt;/A&gt; Satellite radio fans, you can program macro-like behavior using the Z-Wave Sirius Radio Tuner. Because it’s Z-Wave, you’ll be able to easily program it or any other &lt;A href="http://www.z-wavealliance.org/content/modules/iaCM-ProReg-II/" mce_href="http://www.z-wavealliance.org/content/modules/iaCM-ProReg-II/"&gt;Z-Wave Products&lt;/A&gt; using the Intermatic .NET Framework 2.0 gear. 
&lt;P&gt;&lt;B&gt;Cost: &lt;/B&gt;$149.99 
&lt;P&gt;&lt;B&gt;Get it:&lt;/B&gt; &lt;A href="http://www.circuitcity.com/ssm/SIRIUS-Conductor-Satellite-Radio-Tuner-SCH1W/sem/rpsm/oid/164934/catOid/-14641/rpem/ccd/productDetail.do" mce_href="http://www.circuitcity.com/ssm/SIRIUS-Conductor-Satellite-Radio-Tuner-SCH1W/sem/rpsm/oid/164934/catOid/-14641/rpem/ccd/productDetail.do"&gt;Z-Wave Sirius Radio Tuner at Circuit City&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it:&lt;/B&gt; If you have the Z-Wave PC SDK with &lt;A href="http://www.controlthink.com/zwavesdk.htm" mce_href="http://www.controlthink.com/zwavesdk.htm"&gt;Intermatic Home Settings Lighting Control Starter Kit&lt;/A&gt;, it includes the ControlThink SDK which enables you to easily program Z-Wave gear. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P mce_keep="true"&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=193 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/phones4.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/phones4.jpg"&gt; Windows Mobile Smartphones&lt;/B&gt; &lt;/P&gt;
&lt;P&gt;The Samsung Blackjack, T-Mobile Dash, or the Motorola Q are great at making complex life easy. They run Windows Mobile 5.0 Smart Phone edition and are slim and small. With this Windows Mobile Version, you won’t be able to alter Office Documents, but you’ll be able to view them through Picsel Viewer. All these phones have a full QWERTY keyboard on them. 
&lt;P&gt;If you need more power, upgrade to a Cingular 8515, a Treo 700w, T-Mobile MDA, or the Samsung SCH-i730. These phones have larger screens that are touch sensitive and while physically bigger, they can do more. Unlike the phones above that run the Smart Phone edition these run the Pocket PC Edition. With these phones, you get Microsoft Office Mobile Suite so one can create and editing of Office documents. 
&lt;P&gt;&lt;B&gt;Price&lt;/B&gt;: $199 - $600 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.microsoft.com/windowsmobile/devices/default.mspx" mce_href="http://www.microsoft.com/windowsmobile/devices/default.mspx"&gt;Windows Mobile Smartphones&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: You can use Visual Studio 2005 Standard Edition, one is able to develop for these devices and create software with ease, like Bryan Dougherty’s &lt;A href="http://msdn.microsoft.com/coding4fun/gaming/arcade/article.aspx?articleid=1044050&amp;amp;title=Pac-Man+for+the+Smartphone" mce_href="http://msdn.microsoft.com/coding4fun/gaming/arcade/article.aspx?articleid=1044050&amp;amp;title=Pac-Man+for+the+Smartphone"&gt;Mobile Pac-man&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=188 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/SDK0052T16.jpg" width=250 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/SDK0052T16.jpg"&gt; StreetDeck Software&lt;/B&gt; 
&lt;P&gt;StreetDeck software is the ultimate must-have software for pimping out your car. StreetDeck includes, GPS Navigation, internet-enhanced navigation using Google Maps or Microsoft Live Local, Media Sync for your MP3 collection, games, and best of all, there’s an SDK so it’s fully customizable. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $199.99 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://store.mp3car.com/ProductDetails.asp?ProductCode=SDK%2D005" mce_href="http://store.mp3car.com/ProductDetails.asp?ProductCode=SDK%2D005"&gt;StreetDeck software on MP3Car.com&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: Streetdeck includes a &lt;A href="http://www.streetdeck.com/developers-SDK.php" mce_href="http://www.streetdeck.com/developers-SDK.php"&gt;SDK for programming using VB Script&lt;/A&gt;, similar to Office VBA, and you can also build a .NET add-in in Visual Basic, C#, or C++ by &lt;A href="http://www.mp3car.com/wiki/index.php/Building_a_.Net_Addin_for_StreetDeck" mce_href="http://www.mp3car.com/wiki/index.php/Building_a_.Net_Addin_for_StreetDeck"&gt;making it available through COM&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=198 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/estarling_new14.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/estarling_new14.jpg"&gt; eStarling Wi-Fi Email/RSS-Enabled LCD Frame&lt;/B&gt;&lt;BR&gt;This frame enables users to either run an email configuration or RSS feed configuration so you can choose to write an application that dynamically sends an email (say from a Webcam periodically), dynamically upload your pictures to Flickr, or create your own RSS feed with pictures.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Cost:&lt;/B&gt; $249.99&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Get it:&lt;/B&gt; &lt;A href="http://www.thinkgeek.com/electronics/cameras/7edc/" mce_href="http://www.thinkgeek.com/electronics/cameras/7edc/"&gt;eStarling page on ThinkGeek.com&lt;/A&gt;&lt;B&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Code it:&lt;/B&gt; You can use &lt;A href="http://www.codeplex.com/FlickrNet" mce_href="http://www.codeplex.com/FlickrNet"&gt;Sam Judson’s Flickr .NET API&lt;/A&gt; to easily programmatically send pictures to Flickr, or use the &lt;A href="http://photograham.me.uk/FlickrWebCam/" mce_href="http://photograham.me.uk/FlickrWebCam/"&gt;FlickrWebCam application&lt;/A&gt; to have mom get real-time pictures of you from your Webcam or use the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebmailsmtpmailclasstopic.asp" mce_href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebmailsmtpmailclasstopic.asp"&gt;SmtpMail Class&lt;/A&gt; to email a picture attachment in one line of code. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=162 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/300_115.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/300_115.jpg"&gt; Home Theater and Lighting Controller 300 featuring OmniLinkTM&lt;BR&gt;&lt;/B&gt;If you have your house setup for Z-Wave Home Automation, then you’ll want this programmable remote that enables you to easily control your lights, home theater and more. 
&lt;P&gt;&lt;B&gt;Cost: &lt;/B&gt;$599 
&lt;P&gt;&lt;B&gt;Get it:&lt;/B&gt; &lt;A href="http://www.monstercentral.com/Public/productPage_control.asp?pin=3368" mce_href="http://www.monstercentral.com/Public/productPage_control.asp?pin=3368"&gt;Home Theater and Lighting Controller 300&lt;/A&gt;&lt;B&gt;&lt;/B&gt; 
&lt;P&gt;&lt;B&gt;Code it: &lt;/B&gt;If you have the Z-Wave PC SDK with &lt;A href="http://www.controlthink.com/zwavesdk.htm" mce_href="http://www.controlthink.com/zwavesdk.htm"&gt;Intermatic Home Settings Lighting Control Starter Kit&lt;/A&gt;, it includes the ControlThink SDK which enables you to easily program Z-Wave gear. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=173 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/01425i1475220014.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/01425i1475220014.jpg"&gt; Windows&lt;/B&gt;&lt;B&gt; Media Center&lt;/B&gt;&lt;B&gt; &lt;/B&gt;
&lt;P&gt;Now is a great time to upgrade your old PC, like the &lt;A href="http://configure.us.dell.com/dellstore/config.aspx?oc=dxps410f1&amp;amp;cs=19&amp;amp;dgvcode=ss&amp;amp;c=US&amp;amp;l=EN" mce_href="http://configure.us.dell.com/dellstore/config.aspx?oc=dxps410f1&amp;amp;cs=19&amp;amp;dgvcode=ss&amp;amp;c=US&amp;amp;l=EN"&gt;Dell XPS 410&lt;/A&gt; a &lt;A href="http://www.pcmag.com/article2/0,1895,2017294,00.asp" mce_href="http://www.pcmag.com/article2/0,1895,2017294,00.asp"&gt;PC Magazine Editor’s Choice&lt;/A&gt; that ships with Windows Media Center 2005, but includes a &lt;B&gt;free&lt;/B&gt; upgrade to &lt;A href="http://www.microsoft.com/windowsvista/getready/editions/home_premium.mspx" mce_href="http://www.microsoft.com/windowsvista/getready/editions/home_premium.mspx"&gt;Windows Vista Home Premium&lt;/A&gt; which includes a &lt;A href="http://www.microsoft.com/windowsvista/experiences/magic.mspx" mce_href="http://www.microsoft.com/windowsvista/experiences/magic.mspx"&gt;revamped Media Center&lt;/A&gt; with built-in streaming to your Xbox 360. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $999 - $2,500 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://configure.us.dell.com/dellstore/config.aspx?oc=dxps410f1&amp;amp;cs=19&amp;amp;dgvcode=ss&amp;amp;c=US&amp;amp;l=EN" mce_href="http://configure.us.dell.com/dellstore/config.aspx?oc=dxps410f1&amp;amp;cs=19&amp;amp;dgvcode=ss&amp;amp;c=US&amp;amp;l=EN"&gt;Dell Online Store&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: Windows Vista Media Center has a much-improved API and &lt;A href="http://blog.mediacentersandbox.com/PermaLink,guid,817c2b05-2a9e-47ac-80c9-1c4db5b26c18.aspx" mce_href="http://blog.mediacentersandbox.com/PermaLink,guid,817c2b05-2a9e-47ac-80c9-1c4db5b26c18.aspx"&gt;three different ways to mod Media Center&lt;/A&gt; including HTML, XAML, and Media Center’s own markup language using the &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&amp;amp;displaylang=en"&gt;Windows SDK&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H3&gt;
&lt;P mce_keep="true"&gt;&lt;A class="" title=robots name=robots&gt;&lt;/A&gt;&lt;B&gt;Robotics&lt;/B&gt; &lt;/P&gt;&lt;/H3&gt;
&lt;P&gt;Mr. Roboto, please come to the front, your Roomba is waiting for you. This entire section lists robots and electronics that do everything from a vacuum cleaner to&amp;nbsp;creating your own cellphones to GPS. 
&lt;TABLE class="" cellSpacing=5 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=210 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/remoterobotweb15.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/remoterobotweb15.jpg"&gt; Microbric Viper Robot &lt;/B&gt;
&lt;P&gt;The Microbric Viper robot enables you to build complex electronic devices with little or no prior electronics knowledge and no soldering required. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $89.99 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.microbric.com/page.php?sId=17" mce_href="http://www.microbric.com/page.php?sId=17"&gt;Microbric Viper Robot&lt;/A&gt; and &lt;A href="http://iguanaworks.net/ir/serial/" mce_href="http://iguanaworks.net/ir/serial/"&gt;Serial IR Transmitter/Receiver&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: Scott Hanselman walks through programming a &lt;A href="http://msdn.microsoft.com/coding4fun/hardware/robotics/article.aspx?articleid=1192168" mce_href="http://msdn.microsoft.com/coding4fun/hardware/robotics/article.aspx?articleid=1192168"&gt;Microbric Viper Robot&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=200 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/GPSlogact_img15.jpg" width=200 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/GPSlogact_img15.jpg"&gt; Lassen iQ FAT16 Datalogger - Complete Kit&lt;/B&gt; 
&lt;P&gt;Ever think you constantly walk in circles? Think you could optimize your routes if you only could map where your went? Use this GPS&amp;nbsp;device to passively map your routes, all you need is an SD card added in. Then return to your computer, upload your data and see where you wandered. Great for mapping routes biking or hiking. 
&lt;P&gt;&lt;B&gt;Cost:&lt;/B&gt; $150.70 
&lt;P&gt;&lt;B&gt;Get It&lt;/B&gt;: &lt;A href="http://www.sparkfun.com/commerce/product_info.php?products_id=671" mce_href="http://www.sparkfun.com/commerce/product_info.php?products_id=671"&gt;Spark Fun&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code It&lt;/B&gt;: From their &lt;A href="http://www.sparkfun.com/datasheets/GPS/GPSLogger%20V1_0.pdf" mce_href="http://www.sparkfun.com/datasheets/GPS/GPSLogger%20V1_0.pdf"&gt;GPS Logger Datasheet&lt;/A&gt;, you can get it to work with &lt;A href="http://www.sparkfun.com/datasheets/GPS/Casey-Lunch.kml" mce_href="http://www.sparkfun.com/datasheets/GPS/Casey-Lunch.kml"&gt;Google Maps &lt;/A&gt;or create your own from the specification provided. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=200 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/2811816.gif" width=200 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/2811816.gif"&gt; Parallax Bluetooth Boe-Bot Kit for Microsoft Robotics Studio&lt;/B&gt; 
&lt;P&gt;Using &lt;A href="http://msdn.com/robotics/" mce_href="http://msdn.com/robotics/"&gt;Microsoft Robotics Studio&lt;/A&gt;, you can easily program the Boe-Bot Parallax kit over Bluetooth and best of all, the Robotics Studio team has negotiated a 15% discount on the BoeBot. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $198.77 after 15% discount 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.parallax.com/detail.asp?product_id=28118" mce_href="http://www.parallax.com/detail.asp?product_id=28118"&gt;Parallax Boe-Bot Kit&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: You can use Microsoft Robotics Studio which exposes services to control your &lt;A href="http://msdn.microsoft.com/robotics/learn/tutorials/setuphdwr/default.aspx#Parallax" mce_href="http://msdn.microsoft.com/robotics/learn/tutorials/setuphdwr/default.aspx#Parallax"&gt;Parallax Boe-Bot Kit using Bluetooth&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=200 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/img_toothbundle_small15.jpg" width=227 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/img_toothbundle_small15.jpg"&gt; iRobot Roomba &lt;/B&gt;
&lt;P&gt;It’s not just a vacuum cleaner it’s also your programmable minion! You can use the clean-the-house excuse as your justification for getting this friendly house cleaner. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $229 or $339 depending on model 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.roombadevtools.com/productcart/pc/viewPrd.asp?idcategory=9&amp;amp;idproduct=23" mce_href="http://www.roombadevtools.com/productcart/pc/viewPrd.asp?idcategory=9&amp;amp;idproduct=23"&gt;Roomba Red + RooTooth bundle&lt;/A&gt;, &lt;A href="http://www.roombadevtools.com/productcart/pc/viewPrd.asp?idcategory=9&amp;amp;idproduct=18" mce_href="http://www.roombadevtools.com/productcart/pc/viewPrd.asp?idcategory=9&amp;amp;idproduct=18"&gt;Roomba Discovery + RooTooth Bundle&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: You can use Microsoft Robotics Studio which includes built-in &lt;A href="http://msdn.microsoft.com/robotics/learn/tutorials/setuphdwr/default.aspx#iRobot" mce_href="http://msdn.microsoft.com/robotics/learn/tutorials/setuphdwr/default.aspx#iRobot"&gt;services for Roomba programming&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=240 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/B000E4FDAE.01.PT01._SS400_SCLZZZZZZZ_V37205325_15.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/B000E4FDAE.01.PT01._SS400_SCLZZZZZZZ_V37205325_15.jpg"&gt; LEGO Mindstorms NXT&lt;/B&gt; 
&lt;P&gt;Lego Mindstorms NXT is Lego’s newest release of their popular Mindstorms robotics and includes built-in three motor support and multiple sensor support including motion, touch, sound, and light. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $249.99 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.amazon.com/LEGO-4494799-Mindstorms-NXT/dp/B000E4FDAE/sr=8-1/qid=1165258587/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=toys-and-games" mce_href="http://www.amazon.com/LEGO-4494799-Mindstorms-NXT/dp/B000E4FDAE/sr=8-1/qid=1165258587/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=toys-and-games"&gt;Lego Mindstorms&lt;/A&gt; on Amazon.com 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: You can use Microsoft Robotics Studio which includes built-in services for &lt;A href="http://msdn.microsoft.com/robotics/learn/tutorials/setuphdwr/default.aspx#LegoNXT" mce_href="http://msdn.microsoft.com/robotics/learn/tutorials/setuphdwr/default.aspx#LegoNXT"&gt;Lego Mindstorms NXT programming&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=200 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/GM862USBKit115.jpg" width=200 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/GM862USBKit115.jpg"&gt; GM862-GPS Evaluation Cell phone Kit – USB&lt;/B&gt; 
&lt;P&gt;Looking to write your own cell phone software? Just pop in your SIM card and get to it. Spark Fun has an evaluation cell phone board with GPS that can interface with your computer through USB.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Cost:&lt;/B&gt; $274.65&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Get It&lt;/B&gt;: &lt;A href="http://www.sparkfun.com/commerce/product_info.php?products_id=280" mce_href="http://www.sparkfun.com/commerce/product_info.php?products_id=280"&gt;Spark Fun&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Code It:&lt;/B&gt; You can find the documentation for how to start interfacing with the board and Spark Fun provides a &lt;A href="http://www.sparkfun.com/commerce/product_info.php?products_id=281" mce_href="http://www.sparkfun.com/commerce/product_info.php?products_id=281"&gt;Visual Basic example&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=240 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/914_new_0115.jpg" width=138 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/914_new_0115.jpg"&gt; White Box Robotics PC-BOTs&lt;/B&gt; 
&lt;P&gt;&lt;A href="http://www.whiteboxrobotics.com/" mce_href="http://www.whiteboxrobotics.com/"&gt;Whitebox Robotics&lt;/A&gt; has created the closest thing to having R2D2 at home with their newly released PC-BOTs. While it’s the priciest of all robotics kits, it’s hardware is no joke as it includes 1GB of RAM, an 80GB hard drive, Windows XP Home, DVD Drive, and a wireless network card. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $3,995 for the Developer kit, $4,995 to include the ever-so cool panels. 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://store.pcpowerzone.com/914pcspedro.html" mce_href="http://store.pcpowerzone.com/914pcspedro.html"&gt;914 PC-BOT&lt;/A&gt;, &lt;A href="http://store.pcpowerzone.com/whhoro9pcro.html" mce_href="http://store.pcpowerzone.com/whhoro9pcro.html"&gt;9-Series PC-BOT&lt;/A&gt; both from PCPowerzone 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: You can use Microsoft Robotics Studio to program Whitebox Robotics devices (&lt;A href="http://msdn.microsoft.com/robotics/media/MSRS_WhiteBox_300K.wvx" mce_href="http://msdn.microsoft.com/robotics/media/MSRS_WhiteBox_300K.wvx"&gt;video&lt;/A&gt;). &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/GM862USBKit115.jpg" align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/GM862USBKit115.jpg"&gt; Tira – Infrared Remote Control Receiver/Transmitter&lt;/B&gt; 
&lt;P&gt;&lt;A href="http://blogs.msdn.com/ericgu/"&gt;Eric Gunnerson&lt;/A&gt; pointed us to Tira, or Transmitting InfraRed Adapter, which is a device that enables you to send and receive infrared signals to any IR device, say to control home automation, or to change your TV channel. Best of all, it’s fully programmable so you can control when to send IR signals or what happens when it receives IR signals.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Cost:&lt;/STRONG&gt; $49.00&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Get it:&lt;/STRONG&gt; Tira 2.1 on &lt;A href="http://www.home-electro.com/buy_it.php"&gt;Home Electronics&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Code it:&lt;/STRONG&gt; Tira’s Developer Page includes a &lt;A href="http://www.home-electro.com/download/tira_api_win_latest.zip"&gt;downloadable SDK&lt;/A&gt; which includes a DLL that you can call from any .NET language or directly from C++, once you install the &lt;A href="http://www.home-electro.com/tira_support.php#Downloads"&gt;Tira drivers&lt;/A&gt;.&lt;BR&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H3&gt;&lt;A class="" title=games name=games&gt;&lt;/A&gt;&lt;B&gt;Programmable Games&lt;/B&gt; &lt;/H3&gt;
&lt;P&gt;Think the final boss is too hard?&amp;nbsp; "Modify" the game to give yourself that extra edge.&amp;nbsp; As any Coding4Fun reader can tell you, games are more fun when you can mod them, and we’ve chosen our favorite moddable games that you can take and extend to your heart’s content.&amp;nbsp; 
&lt;TABLE class="" cellSpacing=5 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px; WIDTH: 300px; HEIGHT: 225px" height=225 src="http://blogs.msdn.com/blogfiles/coding4fun/gamedev/rocketcmd/rocketcmd_0.jpg" width=300 align=right mce_src="http://blogs.msdn.com/blogfiles/coding4fun/gamedev/rocketcmd/rocketcmd_0.jpg"&gt;Rocket Commander&lt;/B&gt; 
&lt;P&gt;&lt;A href="http://abi.exdream.com/" mce_href="http://abi.exdream.com/"&gt;Benjamin Nitschke&lt;/A&gt;’s Rocket Commander is both fun and educational as Ben put together 10 step-by-step videos that show how to build a fully moddable an immersive 3D game using Managed DirectX and C#. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: Free 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://download.microsoft.com/download/4/1/e/41e8f2c1-1bf7-419f-b31b-06122d090a49/RocketCommanderv1.1.msi" mce_href="http://download.microsoft.com/download/4/1/e/41e8f2c1-1bf7-419f-b31b-06122d090a49/RocketCommanderv1.1.msi"&gt;Rocket Commander Game&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: &lt;A href="http://msdn.microsoft.com/coding4fun/gaming/arcade/article.aspx?articleid=997852" mce_href="http://msdn.microsoft.com/coding4fun/gaming/arcade/article.aspx?articleid=997852"&gt;Watch all 10 videos and download the source code&lt;/A&gt; to start building your own RocketCommander mod. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=180 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/clip_image00238.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/clip_image00238.jpg"&gt;&lt;/B&gt;Mech Commander 2&lt;/B&gt; 
&lt;P&gt;If you're interested in how real commercial games are built, look no further than Mech Commander 2, a real-time strategy game with full source code available released by Microsoft Game Studios. If you're a C++ developer you can learn how to build your own mods to Mech Commander in these three free webcasts 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: Free 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6d790cde-c3e5-46be-b3a5-729581269a9c&amp;amp;DisplayLang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6d790cde-c3e5-46be-b3a5-729581269a9c&amp;amp;DisplayLang=en"&gt;Download the full source code&lt;/A&gt; (1GB) 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: Mike Klucher from the XNA team gave a 3-part on-demand Webcast series on how to mod Mech Commander 2that you should use as your starting point: &lt;A href="http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?EventID=1032296433" mce_href="http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?EventID=1032296433"&gt;Part 1&lt;/A&gt;, &lt;A href="http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&amp;amp;EventID=1032296436" mce_href="http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&amp;amp;EventID=1032296436"&gt;Part 2&lt;/A&gt;, and &lt;A href="http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&amp;amp;EventID=1032296439" mce_href="http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&amp;amp;EventID=1032296439"&gt;Part 3&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=200 src="http://ec2.images-amazon.com/images/P/B000067FDW.01._AA280_SCLZZZZZZZ_.jpg" width=200 align=right mce_src="http://ec2.images-amazon.com/images/P/B000067FDW.01._AA280_SCLZZZZZZZ_.jpg"&gt;World of Warcraft&lt;/B&gt; 
&lt;P&gt;If you haven’t started playing World of Warcraft, you simply don’t know what you’re missing! With the &lt;A href="http://www.amazon.com/World-Warcraft-Expansion-Burning-Crusade/dp/B000BWZY7Q/sr=8-1/qid=1165263496/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames" mce_href="http://www.amazon.com/World-Warcraft-Expansion-Burning-Crusade/dp/B000BWZY7Q/sr=8-1/qid=1165263496/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames"&gt;Burning Crusade Expansion Pack&lt;/A&gt; coming out on January 16&lt;SUP&gt;th&lt;/SUP&gt;, now is a great time to join this ever-evolving world! 
&lt;P&gt;&lt;B&gt;Cost: &lt;/B&gt;$19.99&lt;B&gt;&lt;/B&gt; 
&lt;P&gt;&lt;B&gt;Get it: &lt;/B&gt;&lt;A href="http://www.amazon.com/Blizzard-Entertainment-World-of-Warcraft/dp/B000067FDW/sr=8-2/qid=1165261682/ref=pd_bbs_sr_2/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames" mce_href="http://www.amazon.com/Blizzard-Entertainment-World-of-Warcraft/dp/B000067FDW/sr=8-2/qid=1165261682/ref=pd_bbs_sr_2/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames"&gt;World of Warcraft&lt;/A&gt; on Amazon.com or pre-order the &lt;A href="http://www.amazon.com/World-Warcraft-Expansion-Burning-Crusade/dp/B000BWZY7Q/sr=8-1/qid=1165263496/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames" mce_href="http://www.amazon.com/World-Warcraft-Expansion-Burning-Crusade/dp/B000BWZY7Q/sr=8-1/qid=1165263496/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames"&gt;Burning Crusade&lt;/A&gt;&lt;B&gt;&lt;/B&gt; 
&lt;P&gt;&lt;B&gt;Code it: &lt;/B&gt;World of Warcraft scripting and add-ins are coded in LUA, which you can add &lt;A href="http://luaforge.net/projects/lualangpack/" mce_href="http://luaforge.net/projects/lualangpack/"&gt;Visual Studio 2005 support&lt;/A&gt; (Standard and above), or check out &lt;A href="http://www.davidnikdel.com/projects/wow-360/" mce_href="http://www.davidnikdel.com/projects/wow-360/"&gt;David Nikdel’s WoW-360&lt;/A&gt; Project, or &lt;A href="http://wowprofilers.com/Downloads/details/id=13.html" mce_href="http://wowprofilers.com/Downloads/details/id=13.html"&gt;UniUploader&lt;/A&gt; (&lt;A href="http://wowprofilers.com/uploads/downloads/images/2_uu_250_settings_simple_thumb.jpg" mce_href="http://wowprofilers.com/uploads/downloads/images/2_uu_250_settings_simple_thumb.jpg"&gt;screenshot&lt;/A&gt;) which enables you to dynamically upload much more detailed players stats to a WowRoster portal. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=200 src="http://ec2.images-amazon.com/images/P/B000FIQAME.01._AA280_SCLZZZZZZZ_V60792105_.jpg" width=200 align=left mce_src="http://ec2.images-amazon.com/images/P/B000FIQAME.01._AA280_SCLZZZZZZZ_V60792105_.jpg"&gt;Neverwinter Nights 2 Limited Edition DVD&lt;/B&gt; 
&lt;P&gt;Neverwinter Nights 2 is a popular Dungeon and Dragons game that enables users to create their own worlds and adventures and includes a large community of users building games and dungeons for you to explore 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: ~$34.99 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.amazon.com/Atari-26503-Neverwinter-Nights-DVD-ROM/dp/B000E0XX9Q/sr=1-1/qid=1165418883/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames" mce_href="http://www.amazon.com/Atari-26503-Neverwinter-Nights-DVD-ROM/dp/B000E0XX9Q/sr=1-1/qid=1165418883/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames"&gt;Neverwinter Nights 2&lt;/A&gt; on Amazon.com 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: The Neverwinter Nights game builder is written in C# using the .NET Framework and you can write Game Builder plug-ins &lt;A href="http://www.nwn2.pwp.blueyonder.co.uk/ToolsetTuts/plugins/createplugins.html" mce_href="http://www.nwn2.pwp.blueyonder.co.uk/ToolsetTuts/plugins/createplugins.html"&gt;using any Visual Studio 2005 language&lt;/A&gt; including VB, C#, or C++. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=200 src="http://ec1.images-amazon.com/images/P/B000BC38K6.01._AA280_SCLZZZZZZZ_.jpg" width=200 align=right mce_src="http://ec1.images-amazon.com/images/P/B000BC38K6.01._AA280_SCLZZZZZZZ_.jpg"&gt;Civilization IV&lt;/B&gt; 
&lt;P&gt;Sid Meier's Civilization IV is an unlike the typical Age of Empires battle strategy game in that players can use everything from diplomacy to technology to advance their civilization. 
&lt;P&gt;&lt;STRONG&gt;Cost:&lt;/STRONG&gt; $39.99 or $19.99 for the expansion 
&lt;P&gt;&lt;STRONG&gt;Get it:&lt;/STRONG&gt; &lt;A href="http://www.amazon.com/2K-Games-710425217128-Meiers-Civilization/dp/B000BC38K6/sr=1-1/qid=1165263585/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames" mce_href="http://www.amazon.com/2K-Games-710425217128-Meiers-Civilization/dp/B000BC38K6/sr=1-1/qid=1165263585/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames"&gt;Civilization IV&lt;/A&gt; on Amazon.com or &lt;A href="http://www.amazon.com/Sid-Meiers-Civilization-IV-Expansion/dp/B000FHGA4S/sr=1-2/qid=1165263705/ref=pd_bbs_sr_2/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames" mce_href="http://www.amazon.com/Sid-Meiers-Civilization-IV-Expansion/dp/B000FHGA4S/sr=1-2/qid=1165263705/ref=pd_bbs_sr_2/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames"&gt;Warlords Expansion Pack&lt;/A&gt; 
&lt;P&gt;&lt;STRONG&gt;Code it:&lt;/STRONG&gt; Civilization IV includes a &lt;A href="http://civilization4.net/files/modding/PythonAPI_original/&amp;amp;&amp;amp;DI=293&amp;amp;IG=6c43348add274a70b71a72bf022ec5c6&amp;amp;POS=1&amp;amp;CM=WPU&amp;amp;CE=1&amp;amp;CS=AWP&amp;amp;SR=1" mce_href="http://civilization4.net/files/modding/PythonAPI_original/&amp;amp;&amp;amp;DI=293&amp;amp;IG=6c43348add274a70b71a72bf022ec5c6&amp;amp;POS=1&amp;amp;CM=WPU&amp;amp;CE=1&amp;amp;CS=AWP&amp;amp;SR=1"&gt;Python and C++ SDK&lt;/A&gt; and, while we haven’t tried it, you may also be able to call the DLL from VB and C#. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=78 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/header17.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/header17.jpg"&gt; Half Life 2 Holiday 2006 Collection&lt;/B&gt; 
&lt;P&gt;The Half Life 2 Holiday 2006 Collection includes Counter-Strike: Source, Half-Life 2, Half-Life 2: Deathmatch, Half-Life 2: Episode One, Half-Life Deathmatch: Source, Half-Life: Source. The good news is that you can now officially use &lt;A href="http://msdn.microsoft.com/vstudio/express/visualc/" mce_href="http://msdn.microsoft.com/vstudio/express/visualc/"&gt;Visual C++ 2005 Express Edition&lt;/A&gt; for your Half Life 2 mods. 
&lt;P&gt;&lt;STRONG&gt;Cost:&lt;/STRONG&gt; $49.95 
&lt;P&gt;&lt;STRONG&gt;Get it:&lt;/STRONG&gt; &lt;A href="http://steampowered.com/v/index.php?area=package&amp;amp;SubId=201&amp;amp;" mce_href="http://steampowered.com/v/index.php?area=package&amp;amp;SubId=201&amp;amp;"&gt;Holiday 2006 Collection&lt;/A&gt; 
&lt;P&gt;&lt;STRONG&gt;Code it:&lt;/STRONG&gt; &lt;A href="http://developer.valvesoftware.com/wiki/SDK_Docs" mce_href="http://developer.valvesoftware.com/wiki/SDK_Docs"&gt;Valve’s online wiki SDK&lt;/A&gt; docs include everything you need to get started including steps to get &lt;A href="http://developer.valvesoftware.com/wiki/Compiling_under_VS2005" mce_href="http://developer.valvesoftware.com/wiki/Compiling_under_VS2005"&gt;Visual Studio 2005 working&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=200 src="http://ec1.images-amazon.com/images/P/B000GCJ6MK.01._AA280_SCLZZZZZZZ_V41077232_.jpg" width=200 align=right mce_src="http://ec1.images-amazon.com/images/P/B000GCJ6MK.01._AA280_SCLZZZZZZZ_V41077232_.jpg"&gt;Flight Simulator X Deluxe DVD&lt;/B&gt; 
&lt;P&gt;While Flight Simulator X’s hardware requirements are quite big, the graphics on Windows Vista using DirectX 10 are nothing short of breathtaking. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $49.99 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.amazon.com/Microsoft-Flight-Simulator-Deluxe-DVD/dp/B000GCJ6MK/sr=1-1/qid=1165264203/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames" mce_href="http://www.amazon.com/Microsoft-Flight-Simulator-Deluxe-DVD/dp/B000GCJ6MK/sr=1-1/qid=1165264203/ref=pd_bbs_sr_1/104-7127103-7243165?ie=UTF8&amp;amp;s=videogames"&gt;Flight Simulator X&lt;/A&gt; on Amazon.com 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: The Deluxe edition of Flight Simulator X includes a new &lt;A href="http://fsinsider.com/Community/Developers-Corner/About-the-SDK.htm" mce_href="http://fsinsider.com/Community/Developers-Corner/About-the-SDK.htm"&gt;SDK called SimConnect&lt;/A&gt; that you can use to manipulate and control the Flight Simulator world using VB, C#, or C++. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H3&gt;&lt;A class="" title=tools name=tools&gt;&lt;/A&gt;&lt;B&gt;Software Tools&lt;/B&gt; &lt;/H3&gt;
&lt;P&gt;Tools to help make video games, robots and webpages oh my! Every good craftsmen needs their tools and we’re no exception.&amp;nbsp; Below is a list of tools and tool add-on's that will make anyone's life that much easier. 
&lt;TABLE class="" cellSpacing=5 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;Microsoft Robotic Studio&lt;/B&gt; 
&lt;P&gt;If you have LEGO Mindstorm RCX or NXT, you actually can control them through Microsoft Robotic Studio. It can control far more than just LEGO too, it is able to control &lt;A href="http://msdn.microsoft.com/robotics/learn/tutorials/setuphdwr/default.aspx" mce_href="http://msdn.microsoft.com/robotics/learn/tutorials/setuphdwr/default.aspx"&gt;far more&lt;/A&gt; and comes full of examples. Instead of having to deal with low level coding to deal with everything on your robots, one can write a wrapper then have the Robotic Studio do all the heavy lifting! 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: Free 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://msdn.microsoft.com/robotics/" mce_href="http://msdn.microsoft.com/robotics/"&gt;Microsoft Robotics Studio&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;Microsoft Visual Studio Express Editions&lt;/B&gt;&amp;nbsp;&lt;B&gt;&lt;/B&gt; 
&lt;P&gt;You can get everything someone needs to code in 6 different flavors. Web Development, SQL Server, Visual Basic, C#, C++, and J# Editions are available for download from Microsoft. They are the perfect gift for the hobbyist, novice or student developer that is looking for lightweight, easy to learn and use tools. Each edition is able to run side by side on your computer with other installations so you can collect them all! 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: Free 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://msdn.com/express" mce_href="http://msdn.com/express"&gt;Visual Studio Express Editions&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=67 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/XNA_Hero_Banner15.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/XNA_Hero_Banner15.jpg"&gt; Microsoft XNA Game Studio Express&lt;/B&gt; 
&lt;P&gt;Think you are cut out to build video games? Using Microsoft Game Studio Express you can try out building video games that can be played. If you have an Xbox 360, you can actually transfer the game you created to it too! You can show off to your friends the games you created (Don’t forget to add in a god mode for yourself). 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: Free for Windows/$99 year for Xbox porting and content subscription 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://msdn.microsoft.com/directx/XNA/default.aspx" mce_href="http://msdn.microsoft.com/directx/XNA/default.aspx"&gt;XNA Game Studio Express&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=177 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/pdn30_camaro_thumb14.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/pdn30_camaro_thumb14.jpg"&gt; Paint.NET&lt;/B&gt; 
&lt;P&gt;Paint.NET is a free image and photo manipulation software that is open source too! Paint.NET is written in .NET 2.0 and mostly is c# and has a small amount of C++. It supports layers, unlimited history, a simple and intuitive interface, and is loaded with special effects. While it isn’t an Adobe Photoshop replacement, it is simple and powerful enough for someone on a budget. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: Free 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.getpaint.net/" mce_href="http://www.getpaint.net/"&gt;GetPaint.NET&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: Paint.NET has a managed API that you can write plug-ins for using any managed language as shown in this &lt;A href="http://www.codeproject.com/csharp/PdnNoiseEffect.asp" mce_href="http://www.codeproject.com/csharp/PdnNoiseEffect.asp"&gt;Code Project tutorial&lt;/A&gt; by Dennis Dietrich. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=160 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/Reflector16.png" width=160 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/Reflector16.png"&gt; Reflector for .NET&lt;/B&gt; 
&lt;P&gt;Do you have a program that is written in .NET and you can’t figure out how it they preformed a certain task? You thought you fixed that bug but it is still happening after you deployed it. Use Reflector it to see how they pulled it off and verify deployments! Reflector is capable of showing the source code of DLL’s in .NET 1.1 and 2.0 in both Visual Basic and Visual C#. What is displayed isn’t a 1 to 1 code representation, instead what the ILM runs, however one can figure out how certain tasks are accomplished and should be able to gauge what is happening. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: Free 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.aisto.com/roeder/dotnet/" mce_href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector for .NET&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=240 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/thumb_ts2_0116.gif" width=187 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/thumb_ts2_0116.gif"&gt; TeamSpeak&lt;/B&gt; 
&lt;P&gt;If you’re a gamer, you’ve likely used TeamSpeak or Ventrilo to have live chat while playing online games. For us, the choice between TS and Vent came down to who has the API’s, and it was clear that TeamSpeak is the way to go given its built for extensibility 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: Free 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.goteamspeak.com/" mce_href="http://www.goteamspeak.com/"&gt;TeamSpeak&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: You can find a couple of .NET TS samples including &lt;A href="http://www.peterbarrette.com/" mce_href="http://www.peterbarrette.com/"&gt;Peter Barette’s&lt;/A&gt; &lt;A href="http://forum.goteamspeak.com/showthread.php?t=23789" mce_href="http://forum.goteamspeak.com/showthread.php?t=23789"&gt;C# Chat Text application&lt;/A&gt; or Oliver Flint’s &lt;A href="http://forum.goteamspeak.com/showthread.php?t=33995" mce_href="http://forum.goteamspeak.com/showthread.php?t=33995"&gt;TSDisplay.NET&lt;/A&gt; (&lt;A href="http://www.oliverflint.co.uk/tsdisplay.net/default.aspx?hostname=voice.teamspeak.org&amp;amp;serverport=10050&amp;amp;queryport=51234" mce_href="http://www.oliverflint.co.uk/tsdisplay.net/default.aspx?hostname=voice.teamspeak.org&amp;amp;serverport=10050&amp;amp;queryport=51234"&gt;live demo&lt;/A&gt;) using ASP.NET &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=240 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/display_settings15.png" width=215 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/display_settings15.png"&gt; UltraMon&lt;/B&gt; 
&lt;P&gt;If your coder has multiple monitors, you may think about getting them UltraMon. UltraMon extends out the Windows Taskbar across all the monitors along with the ability to create shortcut keystrokes to send windows to different monitors. In addition, it allows for each monitor to have a different display profile. Plus it has scripting support! 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $39.95 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.realtimesoft.com/ultramon/" mce_href="http://www.realtimesoft.com/ultramon/"&gt;UltraMon&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code It&lt;/B&gt;: Ultramon has a &lt;A href="http://www.realtimesoft.com/ultramon/developers.asp" mce_href="http://www.realtimesoft.com/ultramon/developers.asp"&gt;SDK &lt;/A&gt;along with &lt;A href="http://www.realtimesoft.com/ultramon/tour/scripting.asp" mce_href="http://www.realtimesoft.com/ultramon/tour/scripting.asp"&gt;scripting support&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=240 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/B000BT8TRQ.01._AA280_SCLZZZZZZZ_16.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/B000BT8TRQ.01._AA280_SCLZZZZZZZ_16.jpg"&gt; Microsoft Visual Studio 2005&lt;/B&gt; 
&lt;P&gt;If developing for mobile applications or want to use 3&lt;SUP&gt;rd&lt;/SUP&gt; party Visual Studio add-ins, you’ll need to upgrade to Visual Studio Standard or Professional Edition. Visual Studio Express Editions projects will seamlessly work with the full versions of Visual Studio. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $179 - $679 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.amazon.com/Microsoft-Visual-Studio-Standard-2005/dp/B000BT8TRQ/sr=8-1/qid=1165270874/ref=pd_bbs_1/104-7127103-7243165?ie=UTF8&amp;amp;s=software" mce_href="http://www.amazon.com/Microsoft-Visual-Studio-Standard-2005/dp/B000BT8TRQ/sr=8-1/qid=1165270874/ref=pd_bbs_1/104-7127103-7243165?ie=UTF8&amp;amp;s=software"&gt;Standard Edition&lt;/A&gt; (&lt;A href="http://www.amazon.com/Microsoft-Visual-Studio-Standard-Upgrade/dp/B000BT8TS0/sr=8-2/qid=1165270874/ref=pd_bbs_2/104-7127103-7243165?ie=UTF8&amp;amp;s=software" mce_href="http://www.amazon.com/Microsoft-Visual-Studio-Standard-Upgrade/dp/B000BT8TS0/sr=8-2/qid=1165270874/ref=pd_bbs_2/104-7127103-7243165?ie=UTF8&amp;amp;s=software"&gt;upgrade price&lt;/A&gt;), &lt;A href="http://www.amazon.com/Microsoft-Visual-Studio-Professional-2005/dp/B000BTA4LU/sr=1-1/qid=1165270933/ref=pd_bbs_1/104-7127103-7243165?ie=UTF8&amp;amp;s=software" mce_href="http://www.amazon.com/Microsoft-Visual-Studio-Professional-2005/dp/B000BTA4LU/sr=1-1/qid=1165270933/ref=pd_bbs_1/104-7127103-7243165?ie=UTF8&amp;amp;s=software"&gt;Professional Edition&lt;/A&gt; (&lt;A href="http://www.amazon.com/Microsoft-Visual-Studio-Professional-Upgrade/dp/B000BT8TRG/sr=1-2/qid=1165270933/ref=pd_bbs_2/104-7127103-7243165?ie=UTF8&amp;amp;s=software" mce_href="http://www.amazon.com/Microsoft-Visual-Studio-Professional-Upgrade/dp/B000BT8TRG/sr=1-2/qid=1165270933/ref=pd_bbs_2/104-7127103-7243165?ie=UTF8&amp;amp;s=software"&gt;upgrade price&lt;/A&gt;) 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=7e0fdd66-698a-4e6a-b373-bd0642847ab7&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=7e0fdd66-698a-4e6a-b373-bd0642847ab7&amp;amp;displaylang=en"&gt;Visual Studio 2005 includes a free SDK&lt;/A&gt; that you can use to create your own add-ins or even your own programming language. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=54 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/statusIndicator16.png" width=298 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/statusIndicator16.png"&gt; JetBrains ReSharper &lt;/B&gt;
&lt;P&gt;ReSharper is an add-in to Visual Studio 2003 and 2005. ReSharper provides an intelligent coding assistance, on-the-fly error highlighting (no more recompiling), additional searching and navigation features, unit testing, and realy time analysis of code warnings / errors … the list goes on and on. JetBrains ReSharper is free to try out for 30 days, $200 for a full copy. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $200 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.jetbrains.com/resharper/" mce_href="http://www.jetbrains.com/resharper/"&gt;JetBrains ReSharper&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: ReSharper has an &lt;A href="http://www.jetbrains.com/resharper/features/openAPI.html" mce_href="http://www.jetbrains.com/resharper/features/openAPI.html"&gt;open API&lt;/A&gt; which you can use to modify how your code is refactored. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=87 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/logo16.gif" width=200 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/logo16.gif"&gt; WebSuperGoo ABCpdf&lt;/B&gt; 
&lt;P&gt;PDFs are everywhere and progressively more applications are needing them. AbcPDF allows a developer to easily manipulate or create dynamic PDFs. It is fully multithreaded and is loaded with stock full of examples to figure out everything. Past just normal PDF generation, it also can do HTML to PDF generation. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $328, &lt;A href="http://www.websupergoo.com/linktous.htm" mce_href="http://www.websupergoo.com/linktous.htm"&gt;Possibly free if you link to them&lt;/A&gt;. 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.websupergoo.com/abcpdf-1.htm" mce_href="http://www.websupergoo.com/abcpdf-1.htm"&gt;WebSuperGoo&lt;/A&gt; 
&lt;P&gt;&lt;B&gt;Code it&lt;/B&gt;: Here is their &lt;A href="http://www.websupergoo.com/helppdf5net/default.html" mce_href="http://www.websupergoo.com/helppdf5net/default.html"&gt;API for ABCpdf&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H3&gt;&lt;A class="" title=topten name=topten&gt;&lt;/A&gt;&lt;B&gt;Top 10 Cool Presents for Developers&lt;/B&gt; &lt;/H3&gt;
&lt;P&gt;What are your top 5 favorite ... wait, this isn't a movie.&amp;nbsp;&amp;nbsp;&amp;nbsp;Here are what Coding4Fun would deem Top 10 cool presents for Coders.&amp;nbsp; Some range from a magazine subscription to DNA.&amp;nbsp; Each one is 
&lt;TABLE class="" cellSpacing=5 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=168 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/optimus_mini14.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/optimus_mini14.jpg"&gt; Optimus mini three keyboard&lt;/B&gt; 
&lt;P&gt;Wondering how much CPU or RAM your system is taking up? How about what the weather is? The Optimus mini three keyboard allows you to view what is going on in the world with animation. 
&lt;P&gt;&lt;STRONG&gt;Cost:&lt;/STRONG&gt; $159.99 &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Get It:&lt;/STRONG&gt; &lt;A href="http://www.thinkgeek.com/computing/input/88ee/" mce_href="http://www.thinkgeek.com/computing/input/88ee/"&gt;Optimus mini three keyboard &lt;/A&gt;on ThinkGeek &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Code It:&lt;/STRONG&gt; The Optimus Mini has a &lt;A href="http://optimus.artlebedev.com/download/OptimusMiniC%23Example.zip" mce_href="http://optimus.artlebedev.com/download/OptimusMiniC%23Example.zip"&gt;c# library &lt;/A&gt;to use along with other languages which can be &lt;A href="http://www.artlebedev.com/everything/optimus-mini/developers/" mce_href="http://www.artlebedev.com/everything/optimus-mini/developers/"&gt;found here&lt;/A&gt;. &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=97 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/safari7.jpg" width=192 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/safari7.jpg"&gt; O'Reilly Safari Books Online Subscription&lt;/B&gt; 
&lt;P&gt;Wonder why FireFox and Internet Explorer's JavaScript Dom acts different for the same property?&amp;nbsp; Me too.&amp;nbsp; That is why I have a ton of O'Reilly books at my desk.&amp;nbsp; With their online solution, one has the entire library to their disposal.&amp;nbsp; No need to go through pages upon pages of search results! 
&lt;P&gt;&lt;STRONG&gt;Cost:&lt;/STRONG&gt; $39.99 per month&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Get It:&lt;/STRONG&gt; &lt;A href="http://safari.oreilly.com/" mce_href="http://safari.oreilly.com/"&gt;Safari Books Online&lt;/A&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=60 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/make25.gif" width=155 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/make25.gif"&gt; MAKE Magazine&lt;/B&gt; &lt;/P&gt;
&lt;P&gt;MAKE magazine is a magazine that actually encourages you to break your warranties. Wonder how to do modify your camera to do strobe photography, they’ll explain how to create a rig to create. How about a toy gun alarm clock? A jet made out of a jar? A 5-in-1 network cable? These are just a few of many things they show people how to make in their quarterly magazine. In addition to their magazine, they have a great blog over at &lt;A href="http://makezine.com/blog/" mce_href="http://makezine.com/blog/"&gt;http://makezine.com/blog/&lt;/A&gt;. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: Register your copy of Visual Studio Express and get 5 issues for the price of 4. 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://makezine.com/magazine/" mce_href="http://makezine.com/magazine/"&gt;Make Magazine&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=200 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/515767B_p18.jpg" width=200 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/515767B_p18.jpg"&gt; Color Call&lt;/B&gt; 
&lt;P&gt;You’re in the middle of a meeting and you’re up on the whiteboard. The phone rings, should you answer? Find out easily with the Color-Call Caller ID System which enables you to setup which phone numbers should correspond to up to four different colors.&amp;nbsp; 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $29.99 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.brookstone.com/store/product.asp?pid=515767&amp;amp;wid=100&amp;amp;cid=59&amp;amp;sid=630&amp;amp;search_type=subcategory&amp;amp;prodtemp=t1" mce_href="http://www.brookstone.com/store/product.asp?pid=515767&amp;amp;wid=100&amp;amp;cid=59&amp;amp;sid=630&amp;amp;search_type=subcategory&amp;amp;prodtemp=t1"&gt;Color-Call Caller ID&lt;/A&gt; from Brookstone &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px; WIDTH: 276px; HEIGHT: 104px" src="http://blogs.msdn.com/blogfiles/danielfe/WindowsLiveWriter/SaraFordshowsofftheScrollingLEDBeltBuckl_746F/buckle1%5B4%5D.jpg" align=right mce_src="http://blogs.msdn.com/blogfiles/danielfe/WindowsLiveWriter/SaraFordshowsofftheScrollingLEDBeltBuckl_746F/buckle1%5B4%5D.jpg"&gt; Scrolling LED Belt Buckle&lt;/B&gt; 
&lt;P&gt;Nothing says geek chic like a scrolling LED Belt Buckle.&amp;nbsp; It can hold up to six messages at a time with each message containing 256 characters. You can see pictures of our very own &lt;A class="" href="http://blogs.msdn.com/saraford" mce_href="http://blogs.msdn.com/saraford"&gt;Sara Ford&lt;/A&gt; wearing the &lt;A class="" href="http://blogs.msdn.com/danielfe/archive/2006/12/13/sara-ford-shows-off-the-scrolling-led-belt-buckle.aspx" mce_href="http://blogs.msdn.com/danielfe/archive/2006/12/13/sara-ford-shows-off-the-scrolling-led-belt-buckle.aspx"&gt;Scrolling LED Belt Buckle&lt;/A&gt;. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $29.99 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.scrollingbuckle.com/" mce_href="http://www.scrollingbuckle.com/"&gt;Scrolling Belt Buckle&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=132 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/usb_hub_DX_0317.jpg" width=150 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/usb_hub_DX_0317.jpg"&gt; Self Destruction Button USB Hub&lt;/B&gt;&lt;BR&gt;You can’t go wrong accessorizing your office with this custom USB Hub that would be perfect for Dr. Evil.&amp;nbsp; Just remember, do not press the red button no matter how much you want to. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $64.66 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.geekstuff4u.com/product_info.php?manufacturers_id=&amp;amp;products_id=404" mce_href="http://www.geekstuff4u.com/product_info.php?manufacturers_id=&amp;amp;products_id=404"&gt;Self Destruction USB Hub&lt;/A&gt; from GeekStuff4u.com &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=150 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/podcastkit_USBweb113.jpg" width=118 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/podcastkit_USBweb113.jpg"&gt;Alesis USB Podcasting Kit&lt;/B&gt; 
&lt;P&gt;For your inspiring Podcaster, the Alesis kit takes the guesswork out of podcasting. It comes with an 8-Channel USB Mixer, dynamic microphone, stand, and headphones. It also comes with 30 days of free hosting for your podcasts. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $250 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;B&gt;&lt;A href="http://www.alesis.com/product.php?id=99" mce_href="http://www.alesis.com/product.php?id=99"&gt;Alesis USB Podcasting Kit&lt;/A&gt;&lt;/B&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px" height=119 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/fs2004_40015.jpg" width=240 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/fs2004_40015.jpg"&gt; Matrox DualHead2Go / TripleHead2Go&lt;/B&gt; 
&lt;P&gt;Afraid which new video card is right for you or are you on a laptop? The Matrox allows a coder to have up to three monitors with the TripleHead2Go (two with the DualHead2Go) with only one video input. Multiple monitor support is build into Windows. While having that many monitors may seem a tad excessive, they do help boost productivity and help the keep workspace less messy. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $169-$299 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.matrox.com/graphics/en/gxm/products/" mce_href="http://www.matrox.com/graphics/en/gxm/products/"&gt;Matrox Products&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=156 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/pic_bedroom_orange14.jpg" width=240 align=right mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/pic_bedroom_orange14.jpg"&gt; DNA Portrait&lt;/B&gt; &lt;/P&gt;
&lt;P&gt;The ultimate in personalized artwork, this portrait is created by using your actual DNA and comes in fun color choices like Firesky, Ice, Citylights, and Citron 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $390 for 18” x 24”, $490 for 24” x 36” and $790 for 36” x 54” 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.dna11.com/" mce_href="http://www.dna11.com/"&gt;DNA11&lt;/A&gt; &lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 5px 0px 0px" height=200 src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/320468816.jpg" width=200 align=left mce_src="http://www.coding4fun.net/images/HolidayGiftGuide2006_12078/320468816.jpg"&gt; 22”+ wide screen monitors&lt;/B&gt; &lt;/P&gt;
&lt;P&gt;What is better than having dual monitors? Dual 22” widescreen monitors. Bigger monitors aid in the ability to read more and have been shown to have &lt;A href="http://www.nytimes.com/2005/10/16/magazine/16guru.html?ei=5090&amp;amp;en=c8985a80d74cefc1&amp;amp;ex=1287115200&amp;amp;adxnnl=1&amp;amp;partner=rssuserland&amp;amp;emc=rss&amp;amp;pagewanted=all&amp;amp;adxnnlx=1129521853-ar/Jp1qnf0XCl9MGUEiLGA" mce_href="http://www.nytimes.com/2005/10/16/magazine/16guru.html?ei=5090&amp;amp;en=c8985a80d74cefc1&amp;amp;ex=1287115200&amp;amp;adxnnl=1&amp;amp;partner=rssuserland&amp;amp;emc=rss&amp;amp;pagewanted=all&amp;amp;adxnnlx=1129521853-ar/Jp1qnf0XCl9MGUEiLGA"&gt;boost productivity 10 to 44%&lt;/A&gt;. Please verify the graphic card / device they have can support a monitor of this size. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $400-$500 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://accessories.us.dell.com/sna/productlisting.aspx?c=us&amp;amp;category_id=6198&amp;amp;cs=19&amp;amp;l=en&amp;amp;s=dhs" mce_href="http://accessories.us.dell.com/sna/productlisting.aspx?c=us&amp;amp;category_id=6198&amp;amp;cs=19&amp;amp;l=en&amp;amp;s=dhs"&gt;Dell&lt;/A&gt; or NewEgg lists of &lt;A href="http://www.newegg.com/Product/ProductList.asp?Category=19&amp;amp;N=2010190020+1301919996+1109917865&amp;amp;Submit=ENE&amp;amp;SubCategory=20" mce_href="http://www.newegg.com/Product/ProductList.asp?Category=19&amp;amp;N=2010190020+1301919996+1109917865&amp;amp;Submit=ENE&amp;amp;SubCategory=20"&gt;22”-23”&lt;/A&gt;+ or &lt;A href="http://www.newegg.com/Product/ProductList.asp?Category=19&amp;amp;N=2010190020+1301919996+1109909240&amp;amp;Submit=ENE&amp;amp;SubCategory=20" mce_href="http://www.newegg.com/Product/ProductList.asp?Category=19&amp;amp;N=2010190020+1301919996+1109909240&amp;amp;Submit=ENE&amp;amp;SubCategory=20"&gt;23”+ &lt;/A&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;P&gt;&lt;B&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" src="http://ec2.images-amazon.com/images/P/1878739026.01._AA240_SCLZZZZZZZ_V57043853_.jpg" align=right mce_src="http://ec2.images-amazon.com/images/P/1878739026.01._AA240_SCLZZZZZZZ_V57043853_.jpg"&gt; C++ Programming Books&lt;/B&gt; &lt;/P&gt;
&lt;P&gt;Every programmer needs C++ books. Some need a C++ GUI Programming Guide while others need a primer book.&amp;nbsp; The gift of reference books is always a good bet. 
&lt;P&gt;&lt;B&gt;Cost&lt;/B&gt;: $30 to $50 
&lt;P&gt;&lt;B&gt;Get it&lt;/B&gt;: &lt;A href="http://www.amazon.com/C%2B%2B-Primer-Plus-5th-Sams/dp/0672326973/sr=1-1/qid=1165987086/ref=pd_bbs_sr_1/102-0481056-4888969?ie=UTF8&amp;amp;s=books" mce_href="http://www.amazon.com/C%2B%2B-Primer-Plus-5th-Sams/dp/0672326973/sr=1-1/qid=1165987086/ref=pd_bbs_sr_1/102-0481056-4888969?ie=UTF8&amp;amp;s=books"&gt;Amazon&lt;/A&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H3&gt;&lt;B&gt;Happy Holidays From Coding4Fun!&lt;/B&gt;&lt;/H3&gt;
&lt;P&gt;Now only if I can get someone to get me all these gadgets, software, and toys, I mean highly educational, non-fun&amp;nbsp;devices.&amp;nbsp; Thanks for reading and if you think we've missed any awesome holiday gift, please &lt;A href="mailto:code4fun@microsoft.com" mce_href="mailto:code4fun@microsoft.com"&gt;Email us&lt;/A&gt; and we’ll get it added to our list.&amp;nbsp; If you like the guide, &lt;A href="http://www.digg.com/submit?url=http://msdn.microsoft.com/coding4fun/archive/article.aspx?articleid=1228621&amp;amp;title=Holiday%20Gift%20Guide%202006" mce_href="http://www.digg.com/submit?url=http://msdn.microsoft.com/coding4fun/archive/article.aspx?articleid=1228621&amp;amp;title=Holiday%20Gift%20Guide%202006"&gt;Digg Us&lt;/A&gt;. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1228621" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx">events</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/holiday/default.aspx">holiday</category></item><item><title>Kid's Programming Language: Santa's Gifts</title><link>http://blogs.msdn.com/coding4fun/archive/2006/12/01/1183279.aspx</link><pubDate>Fri, 01 Dec 2006 12:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1183279</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/1183279.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=1183279</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=1183279</wfw:comment><description>&lt;SPAN id=c4fmetadata&gt;
&lt;TABLE class="" cellSpacing=0 cellPadding=1 width="100%" border=0&gt;
&lt;TBODY&gt;
&lt;TR class=entry_overview&gt;
&lt;TD class="" width=50&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;SPAN class=entry_description&gt;This article is in a series in which we are recreating classic video games in KPL code—in this article, Santa's Gifts&lt;/SPAN&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" colSpan=2&gt;
&lt;DIV class=entry_author&gt;Larry Serflaten&lt;/DIV&gt;
&lt;DIV class=entry_company&gt;&lt;A mce_href="" mce_thref=""&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;BR&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Difficulty: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;Easy&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Time Required:&lt;/B&gt; &lt;SPAN class=entry_details_input&gt;1-3 hours&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Cost: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;Free&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Software: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;&lt;A href="http://www.kidsprogramminglanguage.com/" mce_href="http://www.kidsprogramminglanguage.com/"&gt;Kid's Programming Language&lt;/A&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Hardware: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Download: &lt;/B&gt;&lt;A href="http://download.microsoft.com/download/d/4/5/d4556729-81f9-4578-936a-111721b27e49/SantasGifts_KPL.msi" mce_href="http://download.microsoft.com/download/d/4/5/d4556729-81f9-4578-936a-111721b27e49/SantasGifts_KPL.msi"&gt;Download&lt;/A&gt; 
&lt;UL&gt;&lt;/UL&gt;&lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One way to get started programming games is to pick a popular game that is fun to play, that has all of the rules already made up, and develop a program that just transfers that game to the computer. Doing that much will help beginning programmers raise their programming skills as they code and tweak their own rendition of the fun game. A Christmastime example of that method accompanies this article, programmed using a relatively new programming language designed to help beginners gain programming skills. Kids' Programming Language (KPL) is a simplified but modern programming language and development environment that introduces beginners to the basic programming concepts. Just as many famous sports players start out playing sports while they're young, KPL is a tool kids can use to program computers while they are still young. With KPL being a free download, it is well within their budget! &lt;/P&gt;
&lt;P&gt;The referenced KPL game is called Santa's Gifts, but it is very similar in nature to the popular Tetris genre of falling objects that need to be properly positioned for optimum points. The rules and game play is simple to learn, but strategically placing the falling objects will give the advanced players higher scores. Using the arrow keys to move the objects from side to side allows the player to position them where they want. Pressing the Down arrow key lets the object drop. When three or more objects of the same type are positioned together, they form a group that is removed from the drop zone, adding some number of points to the player's score. The strategic part of the game is to try to build groups of four or five items, or to try to cause chain reactions where the removal of one group causes another group to be formed and removed. Both of those methods yield more points than just creating groups of three. There is a time aspect to the play as well. The player can't take all day to decide where to position the next item. The time to decide is decreased as the levels progress, which will cause the player to have to recognize certain patterns that score better, decide on a strategy to complete those patterns, and go for it in a relatively short period of time. &lt;/P&gt;
&lt;H4&gt;&lt;B&gt;Do some functional testing&lt;/B&gt;&lt;/H4&gt;
&lt;P&gt;If at all possible, create the game on a piece of paper first, or use pieces of paper to represent objects in the game, and set it all out on a table top to run through the game a few times. Get input and feedback from other game players, and check it over to see if the rules are easy to learn, and if there is opportunity for advanced players to gain an advantage at beating the game. You'll want to iron out the problems and any other conflicts on paper as much as possible before they become problems while writing the game code. It is much easier to change a rule on paper than retrofit a new rule into the computer program. For the simpler games, some may do all of that planning and checking in their head, as I know I did on more than a few occasions, but it cannot be stressed enough to do the planning first, to avoid scrapping or re-writing whole sections of code. &lt;/P&gt;
&lt;P&gt;As I mentioned before about the sports heroes playing the sport while they were young, it takes many years to develop the skills needed to play professionally. They certainly didn't do everything right while they were learning. Expect a little of that in yourself. Those professional players didn't quit, and they kept going until they made it to the top. That sort of perseverance is what you'll need to get past the few failures that may happen. If you can't get the programming to work one way, try another route. Don't be discouraged about starting a project over, or trying to do it in a new way, especially as you begin to develop your skills. Mentors, or others familiar with the tools you are using, are a good source of information and can help you find the right path, instead of the trial and error mode of learning. &lt;/P&gt;
&lt;H4&gt;&lt;B&gt;In summary:&lt;/B&gt; &lt;/H4&gt;
&lt;P&gt;Begin a new game by writing the storyline. Describe where the player is coming from, and where he has to get to. Include the objects or obstacles he will meet along the way, and then move on to creating the rules of engagement. Pretend your table top is your computer screen and cut out pieces of paper to represent the objects the player will see on the screen. Play the game several times, taking notes of any conflicts or other ideas that will be included in the game. Refine the movements and game play such that a child can learn it fairly quickly and figure out how to add something the advanced players can use to gain an upper hand. Begin coding the program by adding just a shell that shows how the screen will look, and provide the means to start the game, and whatever needs to happen to end the game. Then start adding routines to get the game up and running. For example, if there is going to be five levels to the game where each level shows a different screen, then start with a loop in your main procedure that iterates 1 to 5, that will call the routines to draw the different screens as they are needed. Just get the basic shell in place as the starting point. Then add the objects that make up the game, such as adding the player to the screen, and allowing him to move in each of the levels. Then add the objects to the different screens, or whatever the player will be interacting with, and so on. Piece by piece, build the game by providing the skeleton and then adding the meat. You can do that on the whole game level, and on a finer level for different routines. Be mindful of saving your work at different milestones, and then working with a copy from there. You should save your work periodically, at various milestones, so that if the day happens where your file gets corrupted, or you code yourself into a corner, you can go back and make another copy of the last milestone and get back into it, instead of having to start all over from scratch. &lt;/P&gt;
&lt;H4&gt;&lt;B&gt;About the game listing...&lt;/B&gt;&lt;/H4&gt;
&lt;P&gt;For those who are going to be looking at Santa's Gifts source code, I want to point out a couple techniques that might be useful in your own games. The first is in translating a one-dimensional array into something that represents the two-dimensional screen; specifically, checking for objects that are in the immediate area of the player. The second is the method I used to create the fading points that are shown when groups are removed from the play area. For people who do not yet have a copy of KPL, you can learn more about it from &lt;A href="http://www.kidsprogramminglanguage.com/" mce_href="http://www.kidsprogramminglanguage.com"&gt;www.kidsprogramminglanguage.com&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;KPL only supports arrays of a single dimension, so representing two-dimensional space takes a bit of doing. In particular, X and Y coordinates have to be translated into an Index value that points to an element in the array. In general terms, transposing between the two can be shown by the following code: &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=rem&gt;// XMax is the maximum extent of the 2D space in the horizontal direction &lt;/SPAN&gt;
X = Index Mod XMax
Y =  Index / XMax
Index = X + (Y * XMax)
&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;That works when the arrays begin with the first element at index 0. Currently KPL begins its arrays at an index of 1, (but that may change!), so the above code becomes: &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;X = (Index - 1) Mod XMax&lt;BR&gt;Y = (Index - 1) / XMax&lt;BR&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;P&gt;Because the KPL single dimension array uses the Index value to reference its elements, it is more often easier to work with the 2D grid cells by manipulating the Index value, instead of the X and Y values. When the game code has to check for any objects in a grid cell adjacent to the player, it can test the next cell to the right by adding 1 to the player's Index value, and the cell to the left by subtracting 1 from the player's Index value. Similarly, to check the next cell above or below the player, XMax can be subtracted or added (respectively) to the player's Index value. Of course boundary checks are needed to avoid looking above the top edge or below the bottom edge, which are easily handled by testing the adjusted Index value to be between zero and the upper bound of the KPL array. But boundary checks on the right or left edge are more difficult to handle when using the Index value. &lt;/P&gt;
&lt;P&gt;To represent a checkerboard, for example, the KPL array would hold elements indexed from 1 to 64 which represent the 8 X 8 grid. A value at Index 1 is the same value for the grid coordinate (0, 0) or (1, 1) depending on which value you prefer to begin numbering with. Assuming the upper left cell is at (1, 1) then the next cell to the right of the upper left cell is at (2, 1) with an index of 2, (3, 1) is Index 3, (4, 1) is Index 4, and so on to the upper right cell which is at (8, 1) corresponding to the KPL array Index value of 8. The cell below the upper left corner cell is at (1, 2) which equates to an index value of 9. And so it goes with the Index value incrementing by one as the grid cells are traversed left to right and top to bottom. &lt;/P&gt;
&lt;P&gt;The trouble arises when the player is at the right or left edge, because adding one when the player is at the right edge, or subtracting one when the player is at the left edge will actually be referencing a cell from a different row. If the player is at cell (8, 1) or Index 8, then the code must not add 1 for the adjacent test because the player is at the edge; there is no cell at (9, 1). &lt;/P&gt;
&lt;P&gt;One way to avoid overstepping the boundary is to convert the Index value back into its X and Y coordinates so you can test X in comparison with XMax. But there may be many places where such a check is made, which would require many such conversions. Even if centrally located in a function somewhere, the code must be called, which takes some amount of time, repeatedly, over and over, every time such a test is needed. &lt;/P&gt;
&lt;P&gt;The method I used instead of repeated boundary conversions effectively adds a blank cell to the right edge of the 2D space. The KPL array was lengthened to account for there being a cell there, but it was never used for player movements. What it did was avoid the need for special case tests for the right or left edges. Upper and lower boundaries were still in place, but adding that extra cell meant I could simplify the code used to test the adjacent cells. I could safely increment the Index and check for objects for tests to the right, and I could safely decrement the Index value and check for objects to the left because there was that extra cell at the end of each row. Tests to the left when the player was at the left edge found a blank cell (obviously no object there), and tests to the right when the player was at the right edge also found a blank cell. With a little tradeoff in memory usage, I simplified my code considerably. Check out the &lt;B&gt;CheckAdjacent&lt;/B&gt; routine in the game source code. It turned out to be nice uniform code that tests for upper or lower boundaries ahead of comparing the objects for similarity. That is the code used to find all the members of the same type for inclusion into a grouping. If a similar gift is found in an adjacent cell, then adjacent cells to that one have to checked for further similar gifts. If checking there finds one in an adjacent cell, then that new one has to have its adjacent cells checked as so on, to find all the gifts of the same type that are next to each other. You'll note the repetitive nature of those tests made for a good place to use a recursive call (where some routine calls itself to complete its task), but recursion is entirely another topic, worthy of its own detailed discussion. &lt;/P&gt;
&lt;P&gt;The second technique I wanted to mention allowed me to print text on the screen and have it fade away. It was just one of those what-if discoveries I made while looking for a simple way to show the points for the currently removed group, without it remaining on the screen too long. I had used the Status area, but I didn't like how the points shown there seemed to be more like debugging information and not really a part of the game. What I did was take part of the screen image and make it partially transparent using my favorite paint program. I placed that translucent image in a sprite and used KPL's &lt;B&gt;StampSprite&lt;/B&gt; method to transfer the image to the screen. I found that I could print text to that area, and periodically stamp that translucent sprite over the text which would gradually erase the text. I also used that method to provide the BRIGHTNESS constant you'll find near the top of the listing. It controls the brightness of the background image. I didn't want the background image to be so bright as to distract from the animated gift images. I wanted a kind of lower-contrast image to avoid that distraction. When I found the translucent sprite could be stamped in place several times to build up to being opaque, I decided that would be how I could lower the contrast of the background, by making the background sprite translucent. It has to be translucent over some color or shade, and that is what the BRIGHTNESS value controls: it decides the brightness of the gray color used behind the translucent background image. &lt;/P&gt;
&lt;P&gt;One final note on playability. On faster computers you may find that the program runs way too fast to play. That is the way I have grown accustomed to designing programs. Design them so they can play faster than the human can because the computer can easily be slowed down to let the human catch up, but it is usually more difficult (or nearly impossible) to try to speed up a program when it runs too slow. Also near the top of the listing is a TIMEDELAY constant you can adjust to slow down the game more to your liking and abilities. &lt;/P&gt;
&lt;P&gt;I hope you enjoy playing Santa's Gifts, and that you'll take up writing and sharing programs of your own design! If you need beta testers for your KPL program, or have questions or comments, do visit the KPL forums available from links in the help menu of the KPL environment. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1183279" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx">events</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/holiday/default.aspx">holiday</category></item><item><title>Kid’s Programming Language: Christmas Tree Shooter</title><link>http://blogs.msdn.com/coding4fun/archive/2006/11/23/1127053.aspx</link><pubDate>Thu, 23 Nov 2006 08:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1127053</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/1127053.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=1127053</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=1127053</wfw:comment><description>&lt;SPAN id=c4fmetadata&gt;
&lt;TABLE class="" cellSpacing=0 cellPadding=1 width="100%" border=0&gt;
&lt;TBODY&gt;
&lt;TR class=entry_overview&gt;
&lt;TD class="" width=50&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;SPAN class=entry_description&gt;This article lights on a language called Kids Programming Language (KPL). This is a very easy language and especially made for people which are not the memeber of programers team. It mainly deals with games.&lt;/SPAN&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" colSpan=2&gt;
&lt;DIV class=entry_author&gt;Walt Morrison and Jon Schwartz&lt;/DIV&gt;
&lt;DIV class=entry_company&gt;&lt;A mce_thref=""&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;BR&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Difficulty: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;Intermediate&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Time Required:&lt;/B&gt; &lt;SPAN class=entry_details_input&gt;1-3 hours&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Cost: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;Free&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Software: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;Phrogram&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Hardware: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Download: &lt;/B&gt;&lt;A href="http://download.microsoft.com/download/d/4/5/d4556729-81f9-4578-936a-111721b27e49/ChristmasTreeShooter_KPL.msi"&gt;Download&lt;/A&gt; &lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/SPAN&gt;
&lt;P&gt;Ho Ho Ho! Merry Christmas! Happy Holidays! Ho Ho Ho! Naughty or nice? We don't really want to know! Ho Ho Ho!&lt;/P&gt;
&lt;P&gt;Have you seen the previous articles here at Coding4Fun about KPL, the &lt;A href="http://www.kidsprogramminglanguage.com/" mce_href="http://www.kidsprogramminglanguage.com/"&gt;Kid's Programming Language&lt;/A&gt;? The &lt;A href="http://msdn.microsoft.com/coding4fun/coolapplications/KPL/default.aspx" mce_href="http://msdn.microsoft.com/coding4fun/coolapplications/KPL/default.aspx"&gt;overview&lt;/A&gt; and the article on &lt;A href="http://msdn.microsoft.com/coding4fun/gamedevelopment/KPL1/default.aspx" mce_href="http://msdn.microsoft.com/coding4fun/gamedevelopment/KPL1/default.aspx"&gt;KPL Pong&lt;/A&gt;. KPL is not just for kids; it's for anyone who wants to code fun stuff fast. Proving the point, we're working on a couple of Holiday-themed KPL games and articles—like this one, ChristmasTreeShooter.kpl! We have a fun and easy suggestion for how you and family or friends can modify the game yourself, too. &lt;/P&gt;
&lt;P&gt;&lt;IMG alt="" src="file:///coding4fun/images/gamedev/KPL-Xmas1/KPL-Xmas1_1.gif" border=0 mce_src="file:///coding4fun/images/gamedev/KPL-Xmas1/KPL-Xmas1_1.gif"&gt;&lt;/P&gt;
&lt;P&gt;For some unknown reason, your Christmas tree is bobbing and weaving unpredictably before your eyes. It just won't hold still! And you have the rest of these ornaments that you &lt;I&gt;have&lt;/I&gt; to hang on the tree, or you can &lt;I&gt;forget&lt;/I&gt; about opening that green box. You suspect it's got an &lt;A href="http://www.xbox.com/" mce_href="http://www.xbox.com/"&gt;Xbox 360&lt;/A&gt; in it, and going with that theory, you're &lt;I&gt;not&lt;/I&gt; shaking it like the others. Just in case. Anyway, you do your best with the ornaments, and Santa rates your performance at the end. Not a guy you want to disappoint, coming down to that Christmas Eve wire...&lt;/P&gt;
&lt;P&gt;This KPL game was implemented in 161 KPL instructions, and will be simple code for an experienced or hobbyist programmer to follow. It uses sprites for graphics and uses custom sound clips, which we're going to show you how to replace with your own voice-overs. What are friends or family going to say when it's &lt;B&gt;you&lt;/B&gt; who rates their performance? Are you going to be deadpan and droll? Acerbic and insulting? Will you do a Santa voice, a Mrs. Claus voice or an Elf voice? However you record it, you know it'll be fun!&lt;/P&gt;
&lt;P&gt;Chances are, if you're here at Coding4Fun, you're more than just a beginning programmer—but I bet you can think of some friends or family who might like to be a beginning programmer? Well, we made KPL for them—and you helping them learn with KPL should make it fun and easy for both of you. This game ought to catch their interest, but if they're a novice perhaps you can help them through the &lt;A href="http://www.ms-inc.net/Download.aspx?File=BeginningProgrammingWithKPL" mce_href="http://www.ms-inc.net/Download.aspx?File=BeginningProgrammingWithKPL"&gt;Beginning Programming with KPL Tutorial&lt;/A&gt; before you work with them on this or other KPL game code.&lt;/P&gt;
&lt;H2&gt;Just the interesting stuff, please&lt;/H2&gt;
&lt;P&gt;This article will assume some basic programming skill, and rather than explaining every line of code in the KPL program, will focus on key techniques or algorithms which will be useful as you develop your own KPL games: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Finding free images online&lt;BR&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Using Sprites in KPL&lt;BR&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Recording and using custom sounds&lt;BR&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Using Arrays&lt;BR&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Handling keyboard input&lt;BR&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Sprite interaction&lt;BR&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Allowing user customization of game behavior&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Before we begin, the article will make the most sense if you have installed KPL, and downloaded and unzipped the Christmas Tree Shooter program underneath your KPL install folder. The ideal way to start, of course, is to load ChristmasTreeShooter.kpl in the KPL IDE, click "Run the program," and play it a few times before examining the code. :)&lt;/P&gt;
&lt;P&gt;KPL and this program are both available as freeware downloads from: &lt;A href="http://www.kidsprogramminglanguage.com/download.htm" mce_href="http://www.kidsprogramminglanguage.com/download.htm"&gt;http://www.kidsprogramminglanguage.com/download.htm&lt;/A&gt;. KPL does have a dependency on the .NET Framework 1.1, and the KPL install will "auto-magically" download and install the Framework if it is not already installed on your machine. &lt;/P&gt;
&lt;H2&gt;Finding Free Images Online&lt;/H2&gt;
&lt;P&gt;There are many many places online that offer free images that you can reuse in your own KPL programs. An &lt;A href="http://search.msn.com/results.aspx?q=christmas+tree+clipart&amp;amp;FORM=QBHP" mce_href="http://search.msn.com/results.aspx?q=christmas+tree+clipart&amp;amp;FORM=QBHP"&gt;MSN Search for "Christmas Tree Clipart"&lt;/A&gt; returned 589,677 search results when I ran it. Here's the page where we found our Xmas tree:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.geocities.com/~bug_hut/Christmas/trees.html" mce_href="http://www.geocities.com/%7Ebug_hut/Christmas/trees.html"&gt;http://www.geocities.com/~bug_hut/Christmas/trees.html&lt;/A&gt;&lt;U&gt; &lt;/U&gt;&lt;/P&gt;
&lt;P&gt;That particular page is of interest because it's been viewed over 200,000 times—who'd have thought?!? And because it is the only web page I can think of using a background WAV file that I actually &lt;I&gt;liked&lt;/I&gt; hearing!&lt;/P&gt;
&lt;P&gt;KPL supports images in all standard file formats, including GIF, JPG, PNG, TIF and BMP. KPL does support animated GIFs, but those are not used in our Christmas Tree Shooter. If you're using Internet Explorer, saving an image you find on the Web for reuse is easy: right-click the image, and select "Save Picture As...". KPL will automatically find an image by file name if the image is in the Media\Images folder under the KPL installation folder; if you expect to use an image from more than one KPL program, this is the right place to put it. If an image is specific to the program you are working on, you can leave the image in the same folder as the .kpl program itself. KPL will find it in the local folder, looking there first before checking the Images folder.&lt;/P&gt;
&lt;P&gt;Of course, the caveat about finding images online is making sure the site allows you to reuse the image. Image reuse happens all the time on the Web, but of course, if you find an image with a copyright or other usage limitation stated on the page, you will want to comply. There are many many freely usable images out there, so it's safest and simplest to keep looking until you find one with no strings attached.&lt;/P&gt;
&lt;H2&gt;Using Sprites in KPL&lt;/H2&gt;
&lt;P&gt;Here's a single method we coded that wraps the basic KPL sprite commands into one:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;FONT color=#0000ff&gt;Method&lt;/FONT&gt; LoadSizePlaceSprite(name &lt;FONT color=#0000ff&gt;As String&lt;/FONT&gt;, file &lt;FONT color=#0000ff&gt;As String&lt;/FONT&gt;, &lt;BR&gt;                           scale &lt;FONT color=#0000ff&gt;As Decimal&lt;/FONT&gt;, x &lt;FONT color=#0000ff&gt;As Int&lt;/FONT&gt;, y &lt;FONT color=#0000ff&gt;As Int&lt;/FONT&gt;)&lt;BR&gt;    LoadSprite( name, file ) &lt;BR&gt;    ScaleSprite( name, scale )&lt;BR&gt;    MoveSpriteToPoint( name, x, y )&lt;BR&gt;    ShowSprite( name )    &lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;End Method&lt;/FONT&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This allows a single call to load, place and display a sprite:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;LoadSizePlaceSprite(&lt;FONT color=#000080&gt;"TREE"&lt;/FONT&gt;, &lt;FONT color=#000080&gt;"Christmas Tree3.png"&lt;/FONT&gt;, 1.50, &lt;BR&gt;                     TreeX, TreeY )&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The &lt;B&gt;name&lt;/B&gt; parameter gives the sprite a name which you will use to refer to it when you manipulate the sprite.&lt;/P&gt;
&lt;P&gt;The &lt;B&gt;file&lt;/B&gt; parameter is the filename to the image file which will be used to represent the sprite on-screen. No path is required to the filename, but the file must be in the local folder with the .kpl program, or in KPL's Media\Images folder.&lt;/P&gt;
&lt;P&gt;The &lt;B&gt;scale&lt;/B&gt; parameter is a size multiplier for displaying the sprite. 1.0 is no size change, 0.5 is half size, etcâ€¦&lt;/P&gt;
&lt;P&gt;The &lt;B&gt;x&lt;/B&gt; and &lt;B&gt;y&lt;/B&gt; parameters specify the screen location where the sprite will be displayed, in pixels, with the default being that the upper left corner of the window is location (0, 0).&lt;/P&gt;
&lt;P&gt;KPL defaults all sprites to the same ZIndex of 0—all sprites are drawn or rendered on the same layer, so the last one drawn always appears "on top." &lt;CODE&gt;SetSpriteZIndex(name, ZIndex)&lt;/CODE&gt; can be used to specify the ZIndex to control this. Sprites with a higher ZIndex will always be drawn on top of sprites with a lower ZIndex.&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;SetSpriteZIndex(&lt;FONT color=#000080&gt;"Ball"&lt;/FONT&gt; + BallCount, 10)&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Other Sprite-manipulating methods used in ChristmasTreeShooter.kpl are:&lt;/P&gt;
&lt;P&gt;&lt;B&gt;HideSprite()&lt;/B&gt; takes the name of the sprite which is to be hidden when it is no longer needed:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;HideSprite(&lt;FONT color=#000080&gt;"CrossH"&lt;/FONT&gt;)&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;B&gt;GetSpriteHeight() &lt;/B&gt;and&lt;B&gt; GetSpriteWidth()&lt;/B&gt; return a height or width in pixels of the sprite:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;GetSpriteHeight( &lt;FONT color=#000080&gt;"CrossH"&lt;/FONT&gt; )&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;B&gt;SpritesIntersect()&lt;/B&gt; takes the name of two sprites, and returns true only if they intersect or overlap on the screen:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; SpritesIntersect(&lt;FONT color=#000080&gt;"TREE"&lt;/FONT&gt;, &lt;FONT color=#000080&gt;"Ball"&lt;/FONT&gt; + OrnamentCount) &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;That's all the Sprite code used in ChristmasTreeShooter.kpl. We have designed KPL to be as simple and as highly leveraged as possible, and this is particularly visible in KPL support for Sprites.&lt;/P&gt;
&lt;H2&gt;Recording and using custom sounds&lt;/H2&gt;
&lt;P&gt;This KPL program uses custom sounds for Santa's rating of your performance at the end of the game. As with images, sound files can be placed in the same folder as the program if they are used only for the program. If you'd like to share the sounds across more than one program, they can be placed into the Media\Sounds folder underneath KPL's install folder.&lt;/P&gt;
&lt;P&gt;The sounds used for the game were recorded using the Sound Recorder, which is available as part of all versions of Windows. You can launch it from Start Menu &amp;gt; All Programs &amp;gt; Accessories &amp;gt; Entertainment &amp;gt; Sound Recorder, or by running sndrec32.exe from the Start &amp;gt; Run... dialog. If you've been a geek long enough, that file name will remind you of the good (?!?) old days. Not only of 32-bit Windows, but of 8-character MSDOS file names. Amazing thing is, that really wasn't very long ago. :)&lt;/P&gt;
&lt;P&gt;The File menu and the tape-deck style button bar are all of the Sound Recorder that you'll need to use. KPL currently supports .WAV file formats. We're adding support for more sound formats—as well as the ability to play multiple, layered sounds—to KPL v 2, which is targeted for a January 2006 release. Any other program which allows recording or editing supported sound files can be used instead of the Sound Recorder, or course.&lt;/P&gt;
&lt;P&gt;So, here's a fun, easy customization: use Sound Recorder to record and save your own version of the following sound files in place of ours! Here are our sounds and their scripts:&lt;/P&gt;
&lt;P&gt;&lt;B&gt;HoHoILikeIt.wav&lt;/B&gt;: "Ho Ho Ho! I like it!"&lt;/P&gt;
&lt;P&gt;&lt;B&gt;HoHoTryAgain.wav&lt;/B&gt;: "Ho Ho Ho! Try again!"&lt;/P&gt;
&lt;P&gt;You can, of course, say anything you like, and/or give your recordings a different name. If you do use a different name, you'll need to change the following lines of KPL code to match:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; HitCount = 5 &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt;&lt;BR&gt;    PlaySound( &lt;FONT color=#000080&gt;"HoHoILikeIt.wav"&lt;/FONT&gt; )&lt;BR&gt;Else&lt;BR&gt;    PlaySound( &lt;FONT color=#000080&gt;"HoHoTryAgain.wav"&lt;/FONT&gt; )&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;CODE&gt;&lt;FONT color=#0000ff&gt;End If&lt;/FONT&gt;&lt;/CODE&gt;&lt;/P&gt;
&lt;H2&gt;Using Arrays in KPL&lt;/H2&gt;
&lt;P&gt;KPL does support the use of arrays, as well as user-defined structures. KPL v 2 will add support for user-defined classes—an ideal way to encapsulate logic such as the handling of our Christmas tree ornaments. Until then, we kept this simple by using arrays to handle the five of them:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;FONT color=#0000ff&gt;Define&lt;/FONT&gt; BallX &lt;FONT color=#0000ff&gt;As Int&lt;/FONT&gt;[5]&lt;BR&gt;&lt;FONT color=#0000ff&gt;Define&lt;/FONT&gt; BallY &lt;FONT color=#0000ff&gt;As Int&lt;/FONT&gt;[5]&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;CODE&gt;&lt;FONT color=#0000ff&gt;Define&lt;/FONT&gt; BallOffset &lt;FONT color=#0000ff&gt;As Int&lt;/FONT&gt;[5]&lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;And here is an example from the program showing the use of these arrays:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;    BallOffset[OrnamentCount] = BallX[OrnamentCount] - TreeX &lt;/CODE&gt;&lt;/PRE&gt;
&lt;H2&gt;Handling keyboard input&lt;/H2&gt;
&lt;P&gt;A simple model for coding a game in KPL is a large loop which, at a controlled interval, processes user input and game events. Here is our Method &lt;B&gt;Main(),&lt;/B&gt; which shows how this loop is the basis of the processing for the program:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;Method Main()&lt;BR&gt;    SetupGame()&lt;BR&gt;        &lt;BR&gt;    &lt;FONT color=#008000&gt;// Show Instructions&lt;/FONT&gt;    &lt;BR&gt;    Alert(&lt;FONT color=#000080&gt;"Use the Arrow keys to move the shooter and tap the &lt;BR&gt;           Space Bar to place an ornament. Placing an ornament &lt;BR&gt;           on another will break both!", "How to play!"&lt;/FONT&gt;) &lt;BR&gt;&lt;BR&gt;    &lt;FONT color=#0000ff&gt;Define&lt;/FONT&gt; CurrentTime &lt;FONT color=#0000ff&gt;As Decimal&lt;/FONT&gt; &lt;BR&gt;    &lt;FONT color=#0000ff&gt;Define&lt;/FONT&gt; TimeLastChecked &lt;FONT color=#0000ff&gt;As Decimal&lt;/FONT&gt;&lt;BR&gt;    &lt;BR&gt;    &lt;FONT color=#008000&gt;// Start the wait time for the Space Bar to prevent the Key &lt;BR&gt;    // Bounce effect&lt;/FONT&gt;     &lt;BR&gt;    LastOrnamentFireTime = TickCount()&lt;BR&gt;&lt;BR&gt;    &lt;FONT color=#0000ff&gt;While&lt;/FONT&gt; GameOver = &lt;FONT color=#0000ff&gt;False&lt;/FONT&gt;&lt;BR&gt;    &lt;BR&gt;        CurrentTime = TickCount()    &lt;BR&gt;        &lt;BR&gt;        &lt;FONT color=#008000&gt;// If 60 milliseconds have not passes since the last &lt;BR&gt;        // time we checked, we don't do anything yet.&lt;/FONT&gt;&lt;BR&gt;        &lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; CurrentTime - TimeLastChecked &amp;gt; 60 &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt; &lt;BR&gt;            &lt;FONT color=#008000&gt;// Every 60 milliseconds (that's 17 times a &lt;BR&gt;            // second!) we fall into this block.&lt;BR&gt;            // First we process Key events to move the&lt;BR&gt;            // targeting circle&lt;/FONT&gt;        &lt;BR&gt;            ProcessKeyEvents()&lt;BR&gt;            &lt;FONT color=#008000&gt;// Then we MoveTheTree.&lt;/FONT&gt;&lt;BR&gt;            MoveTheTree()&lt;BR&gt;            &lt;FONT color=#008000&gt;// We reset the timer each time, so we wait &lt;BR&gt;            // another 60 milliseconds before moving again.&lt;/FONT&gt;&lt;BR&gt;            TimeLastChecked = CurrentTime&lt;BR&gt;        &lt;FONT color=#0000ff&gt;End If&lt;/FONT&gt;&lt;BR&gt;        &lt;BR&gt;    &lt;FONT color=#0000ff&gt;End While&lt;/FONT&gt;&lt;BR&gt;    &lt;BR&gt;    GameOverShowTree()&lt;BR&gt;  &lt;BR&gt;End Method&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The actual processing of key events is done in the &lt;B&gt;ProcessKeyEvents()&lt;/B&gt; method, using the &lt;B&gt;IsKeyDown()&lt;/B&gt; function:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;    &lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; IsKeyDown( &lt;FONT color=#000080&gt;"Up"&lt;/FONT&gt; ) &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt;&lt;BR&gt;        &lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; CrossHY &amp;gt; 10 &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt;&lt;BR&gt;            CrossHY = CrossHY - CrossHairSpeed&lt;BR&gt;        &lt;FONT color=#0000ff&gt;End If&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;End If&lt;/FONT&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The key processing code checks for all keys that are relevant to targeting movement, and will handle any and all keys that are down. It also uses logic as shown above so that keys which would cause the targeting circle to move off the viewable screen are ignored.&lt;/P&gt;
&lt;P&gt;One issue caused by processing keys in a loop this way results from the fact that the computer loop can be so much faster than our own fingers on the keyboard, which can result in processing the KeyDown more than once on a single tap of the Space Bar. When the single Space Bar keystroke is as important to the game as it is here, we must add a little extra code which makes sure we don't process that Space Bar keystroke more than once. The following code, at the bottom of the &lt;B&gt;ProcessKeyEvents()&lt;/B&gt; method, does this using the global variable &lt;CODE&gt;LastOrnamentFireTime&lt;/CODE&gt;:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;// Process the wait time for the Space Key to reduce the Key &lt;BR&gt;&lt;FONT color=#008000&gt;// Bounce Effect.  If it's been less than 200 milliseconds...&lt;/FONT&gt;&lt;BR&gt;currentTime = TickCount()&lt;BR&gt;&lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; (currentTime - LastOrnamentFireTime) &amp;lt; PlayerOrnamentFireDelay &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt;&lt;BR&gt;    Return &lt;FONT color=#008000&gt;// Exit the method without processing&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;End If&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; IsKeyDown( "Space" ) &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt;&lt;BR&gt;    LastOrnamentFireTime = currentTime&lt;BR&gt;    ShootOrnament()&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;End If&lt;/FONT&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H2&gt;Sprite interaction&lt;/H2&gt;
&lt;P&gt;What you are attempting to do with this game, of course, if place each of the five ornaments onto the bobbing and weaving Christmas tree, without breaking them. Since the tree and the ornaments are all implemented as sprites in this KPL program, this is as easy as checking to see whether the sprites "intersect" when you hit the spacebar to place an ornament. The code for this is in method&lt;B&gt; ShootOrnament()&lt;/B&gt;:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; SpritesIntersect("TREE", "Ball" + OrnamentCount) &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt;&lt;BR&gt;    PlaySound( HitSound )    &lt;BR&gt;    &lt;FONT color=#008000&gt;// if we hit the tree count it and show it&lt;/FONT&gt;&lt;BR&gt;    HitCount = HitCount + 1&lt;BR&gt;    &lt;FONT color=#008000&gt;// calculate the ornament offset&lt;/FONT&gt;&lt;BR&gt;    BallOffset[OrnamentCount] = BallX[OrnamentCount] - TreeX &lt;BR&gt;Else&lt;BR&gt;    &lt;FONT color=#008000&gt;// if we miss the tree all together don't count or show ornament&lt;/FONT&gt;&lt;BR&gt;    PlaySound( BreakSound )    &lt;BR&gt;    HideSprite("Ball" + OrnamentCount)    &lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;End If&lt;/FONT&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Note that if we actually got the ornament on the tree, we figure out its Offset so we can later move it along with the tree. And if we miss the tree altogether, the bulb breaks and is not shown.&lt;/P&gt;
&lt;P&gt;These ornaments are those fragile little glass balls—proof that guys have no business decorating Christmas trees, right?!? If we actually shoot one glass ball on top of another, well, they both break, Santa is less than pleased, and we might never get to open that green box! Here are the nested &lt;B&gt;For...Next&lt;/B&gt; loops that check for this:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;FONT color=#0000ff&gt;For&lt;/FONT&gt; Ornaments = 1 &lt;FONT color=#0000ff&gt;To&lt;/FONT&gt; OrnamentCount&lt;BR&gt;    &lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; Ornaments &amp;lt; OrnamentCount &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt;&lt;BR&gt;        &lt;FONT color=#0000ff&gt;For&lt;/FONT&gt; OtherOrnaments = (Ornaments + 1) &lt;FONT color=#0000ff&gt;To&lt;/FONT&gt; OrnamentCount&lt;BR&gt;            &lt;FONT color=#008000&gt;// Process balls hitting balls, don't count them and&lt;/FONT&gt; &lt;BR&gt;            &lt;FONT color=#008000&gt;// don't show them&lt;/FONT&gt;&lt;BR&gt;            &lt;FONT color=#0000ff&gt;If&lt;/FONT&gt; SpritesIntersect(&lt;FONT color=#000080&gt;"Ball"&lt;/FONT&gt; + Ornaments, &lt;FONT color=#000080&gt;"Ball"&lt;/FONT&gt; + &lt;BR&gt;                                 OtherOrnaments) &lt;FONT color=#0000ff&gt;Then&lt;/FONT&gt;&lt;BR&gt;                PlaySound( OrnamentHit )&lt;BR&gt;                HideSprite(&lt;FONT color=#000080&gt;"Ball"&lt;/FONT&gt; + Ornaments)&lt;BR&gt;                HideSprite(&lt;FONT color=#000080&gt;"Ball"&lt;/FONT&gt; + OtherOrnaments)&lt;BR&gt;                HitCount = HitCount - 2&lt;BR&gt;            &lt;FONT color=#0000ff&gt;End If&lt;/FONT&gt;&lt;BR&gt;        &lt;FONT color=#0000ff&gt;Next&lt;/FONT&gt;&lt;BR&gt;    &lt;FONT color=#0000ff&gt;End If&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;Next&lt;/FONT&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Besides nested loops always being fun exercises of logic, this is interesting because it shows how easy it can be to use an automatic type conversion to build a string from a number. Our sprites are named Ball1 to Ball5, and when we need to process them in a loop this way, we can simply construct the name by concatenating "Ball" + Ornaments, where the latter is the integer loop index.&lt;/P&gt;
&lt;H2&gt;Allowing user customization of game behavior&lt;/H2&gt;
&lt;P&gt;Besides being educational, open-source KPL games have the advantage of allowing a user to change or customize the game behavior. The entire game and all its code is there for the user's modification, but it's also worth putting a little thought and effort into allowing easy customization of the behavior of your game. Our Christmas Tree Shooter does this with three global variables, defined, commented and changeable up at the top of the program file:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;FONT color=#008000&gt;// Set these next 3 variables to affect game play&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;Define&lt;/FONT&gt; CrossHairSpeed &lt;FONT color=#0000ff&gt;As Int&lt;/FONT&gt; = 20&lt;BR&gt;&lt;FONT color=#0000ff&gt;Define&lt;/FONT&gt; TreeSpeed &lt;FONT color=#0000ff&gt;As Int&lt;/FONT&gt; = 20&lt;BR&gt;&lt;FONT color=#008000&gt;// how many times the tree will move before game is over&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;Define MoveCount As Int = 2 &lt;FONT color=#008000&gt;// = once to the right, once to the left&lt;/FONT&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Good naming and comments make this pretty easy for users to find and change. The two speed variables can be tweaked to make the game easier or harder, depending on the user's reflexes. And the move count can be increased to lengthen the game and allow the user more time.&lt;/P&gt;
&lt;P&gt;Building in game settings based on global variables like this just takes a little thought, and can allow a fun extra level of control for people playing your game.&lt;/P&gt;
&lt;H2&gt;What's next?&lt;/H2&gt;
&lt;P&gt;Two or three other Holiday-themed KPL games should also be up on the Coding4Fun site. Have fun with them, and Happy Holidays—no matter which particular Holiday you're celebrating at this time of year!&lt;/P&gt;
&lt;P&gt;KPL Asteroids is also next in the series of retro games implemented with KPL—watch for that in the next couple of weeks!&lt;/P&gt;
&lt;P&gt;There are now dozens of open source KPL games, and dozens more educational programs—either included in the base KPL install, or new and separately downloadable. Check them all out at &lt;A href="http://www.kidsprogramminglanguage.com/download.htm" mce_href="http://www.kidsprogramminglanguage.com/download.htm"&gt;http://www.kidsprogramminglanguage.com/download.htm&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Moral of the story? Coding4Fun isn't just a name—it's the point!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1127053" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx">events</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/holiday/default.aspx">holiday</category></item><item><title>Persistent Error Messages</title><link>http://blogs.msdn.com/coding4fun/archive/2006/11/01/918706.aspx</link><pubDate>Wed, 01 Nov 2006 08:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:918706</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/918706.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=918706</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=918706</wfw:comment><description>&lt;SPAN id=c4fmetadata&gt;
&lt;TABLE class="" cellSpacing=0 cellPadding=1 width="100%" border=0&gt;
&lt;TBODY&gt;
&lt;TR class=entry_overview&gt;
&lt;TD class="" width=50&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;SPAN class=entry_description&gt;A prank that makes the hapless user see a familiar error message box that he/she can't close, and that spawns more and more error messages each time he/she try to close it.&lt;/SPAN&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" colSpan=2&gt;
&lt;DIV class=entry_author&gt;Jacqueline Russell&lt;/DIV&gt;
&lt;DIV class=entry_company&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;BR&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Difficulty: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;Easy&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Time Required:&lt;/B&gt; &lt;SPAN class=entry_details_input&gt;3-6 hours&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Cost: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;Free&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Software: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;&lt;A href="http://msdn.com/express/" mce_href="http://msdn.com/express/"&gt;Visual Basic or Visual C# Express Editions&lt;/A&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Hardware: &lt;/B&gt;&lt;SPAN class=entry_details_input&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class=entry_details&gt;&lt;B&gt;Download: &lt;/B&gt;&lt;A href="http://download.microsoft.com/download/4/1/e/41e8f2c1-1bf7-419f-b31b-06122d090a49/PersistentErrorMessagePrank.msi"&gt;Download&lt;/A&gt; 
&lt;UL&gt;&lt;/UL&gt;&lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here's a quick and easy prank that's sure to get a few laughs. I pulled this together in a matter of a few hours between meetings at work. It's very simple, so you should be able to quickly understand and customize it. Basically, on startup, the hapless user will see a familiar error message box that they can't close, and that spawns more and more error messages each time they try to close it. I tried this on my husband and it wasn't until the third error message box that he caught on! &lt;/P&gt;
&lt;H4&gt;To deploy&lt;/H4&gt;
&lt;P&gt;Simply copy the executable file (or a shortcut to it) to the Startup folder (C:\Documents and Settings\All Users\Start Menu\Programs\Startup) on the victim's machine and watch the fun begin when they start up their machine in the morning! &lt;/P&gt;
&lt;H4&gt;Ideas for Customization&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Customize the text messages to your specific work situation or victim. &lt;/LI&gt;
&lt;LI&gt;Add more forms. &lt;/LI&gt;
&lt;LI&gt;If you're mean, don't allow the user to close the app at all and constantly rotate between forms. &lt;/LI&gt;
&lt;LI&gt;For a more subtle approach, create a Windows service so that error messages pop up at random time intervals during the day and then disappear automagically (as soon as your victim gets Help Desk on the phone)! &lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=918706" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx">events</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/april+fools+day/default.aspx">april fools day</category></item><item><title>Reusable Body Parts</title><link>http://blogs.msdn.com/coding4fun/archive/2006/10/30/905562.aspx</link><pubDate>Tue, 31 Oct 2006 08:39:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:905562</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/905562.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=905562</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=905562</wfw:comment><description>&lt;p&gt;Clint Rutkas&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;What screams Halloween more than fake body parts? Fake body parts that twitch and are covered with blood. The second thing that screams Halloween is causing some mischief.&lt;/p&gt; &lt;p&gt;&lt;a href="http://coding4fun.net/images/ReusableBodyParts_13B8A/hand1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://coding4fun.net/images/ReusableBodyParts_13B8A/hand.jpg" width="240" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Black cats of Hardware&lt;/h3&gt; &lt;p&gt;I got to say, I love &lt;a href="http://www.phidgets.com/"&gt;Phidgets&lt;/a&gt;. They are relatively inexpensive USB items that power motors and have a great API with tons of examples. My only issue I have is I follow what my teachers and mother told me far too much to the letter. I attempted to reuse and modify what I had instead of buying what I need to get the job done. After buying three separate items, I finally got the correct item for this task. I got a PhidgetMotorControl LV.  &lt;p&gt;&lt;a href="http://coding4fun.net/images/ReusableBodyParts_13B8A/phidget1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://coding4fun.net/images/ReusableBodyParts_13B8A/phidget.jpg" width="240" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;The failed purchase and why.&lt;/h3&gt; &lt;p&gt;Attempt 1: The PhidgetTextLCD 8/8/8  &lt;p&gt;Why did this Phidget fail to work for this application? It couldn’t provide enough power to the motor. The hand moved far more like something caught in a black hole than anything remotely scary.  &lt;p&gt;Attempt 2: The Phidget Servo 4-Motor  &lt;p&gt;My attempt to piggy back on top of a Servo control failed pretty badly. I forgot an important thing with servos which is they are always on. I got this initially for a different project and figured I could modify it to fit my need.  &lt;h3&gt;Mod the hand with internal water cooling!&lt;/h3&gt; &lt;p&gt;Wait, no, I didn’t do that, but it would be cooler if I did. Getting the hand to work with the Phidget was rather easy. I soldered some extension wires into the battery pack and then hooked it into the Phidget.  &lt;h3&gt;Black cats of Hardware&lt;/h3&gt; &lt;p&gt;This is a relatively easy program. Due to Phidget’s awesome and easy to use API, I had the program up and working in a matter of minutes. I spent more time messing around with the layout and finding a cool background than I did typing.  &lt;p&gt;&amp;nbsp;&lt;a href="http://coding4fun.net/images/ReusableBodyParts_13B8A/entireSetup2.jpg" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="317" src="http://coding4fun.net/images/ReusableBodyParts_13B8A/entireSetup_thumb.jpg" width="423" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;h3&gt;The entire application, in a c# power cord.&lt;/h3&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; Form1 : Form
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; Form1()
        {
            InitializeComponent();
        }

        MotorControl motor;
        
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; btnMoveStart = &lt;span class="str"&gt;"Force Start Movement"&lt;/span&gt;;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; btnMoveEnd = &lt;span class="str"&gt;"Force Stop Movement"&lt;/span&gt;;

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Form1_Load(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
        {
            motor = &lt;span class="kwrd"&gt;new&lt;/span&gt; MotorControl();
            Servo_Detach(&lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
            
            motor.Attach += &lt;span class="kwrd"&gt;new&lt;/span&gt; AttachEventHandler(Servo_Attach);
            motor.Detach += &lt;span class="kwrd"&gt;new&lt;/span&gt; DetachEventHandler(Servo_Detach);
            
            btnMove.Text = btnMoveStart;
            
            motor.open();
        }

        &lt;span class="kwrd"&gt;void&lt;/span&gt; Servo_Detach(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, DetachEventArgs e)
        {
            btnMove.Enabled = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            txtStatus.Text = &lt;span class="str"&gt;"NOT CONNECTED"&lt;/span&gt;;
            txtStatus.ForeColor = Color.Red;
        }
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Servo_Attach(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, AttachEventArgs e)
        {
            btnMove.Enabled = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            txtStatus.Text = &lt;span class="str"&gt;"CONNECTED"&lt;/span&gt;;
            txtStatus.ForeColor = Color.Green;
        }

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnMove_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (btnMove.Text == btnMoveStart)
            {
                btnMove.Text = btnMoveEnd;
                motor.motors[1].Velocity = 75;
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                btnMove.Text = btnMoveStart;
                motor.motors[1].Velocity = 0;
            }
        }

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Form1_FormClosing(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, FormClosingEventArgs e)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (motor.Attached)
                motor.close();
        }
    }
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Now in a Visual Basic chord&lt;/h3&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt; Form1
    &lt;span class="kwrd"&gt;Inherits&lt;/span&gt; Form

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; motor &lt;span class="kwrd"&gt;As&lt;/span&gt; MotorControl

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Const&lt;/span&gt; btnMoveStart &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;"Force Start Movement"&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Const&lt;/span&gt; btnMoveEnd &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;"Force Stop Movement"&lt;/span&gt;

    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt;()
        &lt;span class="kwrd"&gt;MyBase&lt;/span&gt;.&lt;span class="kwrd"&gt;New&lt;/span&gt;()
        InitializeComponent()
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Form1_Load(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;MyBase&lt;/span&gt;.Load
        motor = &lt;span class="kwrd"&gt;New&lt;/span&gt; MotorControl
        &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Servo_Detach(&lt;span class="kwrd"&gt;Nothing&lt;/span&gt;, &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;)
        &lt;span class="kwrd"&gt;AddHandler&lt;/span&gt; motor.Attach, &lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Servo_Attach
        &lt;span class="kwrd"&gt;AddHandler&lt;/span&gt; motor.Detach, &lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Servo_Detach
        btnMove.Text = btnMoveStart
        motor.open()
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Servo_Detach(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; DetachEventArgs)
        btnMove.Enabled = &lt;span class="kwrd"&gt;False&lt;/span&gt;
        txtStatus.Text = &lt;span class="str"&gt;"NOT CONNECTED"&lt;/span&gt;
        txtStatus.ForeColor = Color.Red
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Servo_Attach(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; AttachEventArgs)
        btnMove.Enabled = &lt;span class="kwrd"&gt;True&lt;/span&gt;
        txtStatus.Text = &lt;span class="str"&gt;"CONNECTED"&lt;/span&gt;
        txtStatus.ForeColor = Color.Green
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; btnMove_Click(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; btnMove.Click
        &lt;span class="kwrd"&gt;If&lt;/span&gt; (btnMove.Text = btnMoveStart) &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            btnMove.Text = btnMoveEnd
            motor.motors(1).Velocity = 75
        &lt;span class="kwrd"&gt;Else&lt;/span&gt;
            btnMove.Text = btnMoveStart
            motor.motors(1).Velocity = 0
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Form1_FormClosing(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; FormClosingEventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;MyBase&lt;/span&gt;.FormClosing
        &lt;span class="kwrd"&gt;If&lt;/span&gt; motor.Attached &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            motor.close()
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Class&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;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://coding4fun.net/images/ReusableBodyParts_13B8A/interface1.gif" atomicselection="true"&gt;&lt;img height="205" src="http://coding4fun.net/images/ReusableBodyParts_13B8A/interface.gif" width="240"&gt;&lt;/a&gt; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3&gt;Let the hunt begin for prank monkeys&lt;/h3&gt;
&lt;p&gt;Here is one of my favorite victims, Chris King, to prank. 
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.coding4fun.net/media/cking.wmv"&gt;Prank Video with motion hand&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Hacking hardware is easy if you buy the right toys. What can be done to make this better and cooler? I could add in an IR sensor with the 8/8/8 and use that to detect if people are near the hand. 
&lt;p&gt;&amp;nbsp; 
&lt;p&gt;Author bio: Clint is an application developer for &lt;a href="http://springcm.com/"&gt;SpringCM&lt;/a&gt;, an on-demand, web-based document and content management system. As a developer, Clint is part of an innovative team committed to supporting affordable, scalable and reliable enterprise content management. His two primary development languages are C# and JavaScript. Prior to the Halloween Dead Hand project, he worked on his &lt;a href="http://msdn.microsoft.com/coding4fun/coolapplications/disco/default.aspx"&gt;Disco Dance Floor&lt;/a&gt;. In his off time, he whips up other random weird projects and does twenty something activities with his friends. Clint’s blog is &lt;a href="http://betterthaneveryone.com/"&gt;betterthaneveryone.com&lt;/a&gt; and can be emailed at &lt;a href="mailto:clint@rutkas.com"&gt;clint@rutkas.com&lt;/a&gt;. 
&lt;p&gt;&amp;nbsp; 
&lt;p&gt;&amp;nbsp; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;span style='display:none'&gt;&lt;![CDATA[
&lt;summary&gt;
&lt;title&gt;Reusable Body Parts&lt;/title&gt;
&lt;description&gt;&lt;![CDATA[ What screams Halloween more than fake body parts?  Fake body parts that twitch and are covered with blood.  The second thing that screams Halloween is causing some mischief.  ]]&gt;&lt;/description&gt;
&lt;author&gt;
&lt;name&gt;Clint Rutkas&lt;/name&gt;
&lt;company&gt;http://betterthaneveryone.com/&lt;/company&gt;
&lt;url&gt;Clint's Blog&lt;/url&gt;
&lt;/author&gt;
&lt;downloads&gt;
&lt;code&gt;http://channel9.msdn.com/ShowPost.aspx?PostID=251380&lt;/code&gt;
&lt;/downloads&gt;
&lt;difficulty&gt;Intermediate&lt;/difficulty&gt;
&lt;requirements&gt;
&lt;cost&gt;$100-$200&lt;/cost&gt;
&lt;time&gt;3-6 hours&lt;/time&gt;
&lt;software&gt;&lt;![CDATA[ &lt;a href="http://msdn.com/express/"&gt;Visual Basic or Visual C# Express Editions&lt;/a&gt;]]&gt;&lt;/software&gt;
&lt;hardware&gt;&lt;![CDATA[PhidgetMotorControl LV, animatronic hand]]&gt;&lt;/hardware&gt;
&lt;/requirements&gt;
&lt;/summary&gt;
]]&gt;&lt;/span&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=905562" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx">events</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/halloween/default.aspx">halloween</category></item><item><title>Scary Halloween Application</title><link>http://blogs.msdn.com/coding4fun/archive/2006/10/30/905508.aspx</link><pubDate>Tue, 31 Oct 2006 08:06:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:905508</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/905508.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=905508</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=905508</wfw:comment><description>&lt;p mce_keep="true"&gt;&lt;/p&gt;&lt;span id="c4fmetadata"&gt; &lt;table cellspacing="0" cellpadding="1" width="100%" border="0"&gt; &lt;tbody&gt; &lt;tr class="entry_overview"&gt; &lt;td width="50"&gt;&lt;img height="50" src="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/article_thumb.png" width="50"&gt;&lt;/td&gt; &lt;td&gt;&lt;span class="entry_description"&gt;Build an application that will drip animated blood down your victim's computer screen for a scary Halloween treat!&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td colspan="2"&gt; &lt;div class="entry_author"&gt;Brian Peek&lt;/div&gt; &lt;div class="entry_company"&gt;&lt;a href="http://www.aspsoft.com/" target="_blank"&gt;ASPSOFT, Inc.&lt;/a&gt;&lt;/div&gt;&lt;br&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Difficulty: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Easy&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Time Required:&lt;/b&gt; &lt;span class="entry_details_input"&gt;Less than 1 hour&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Cost: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Free&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Software: &lt;/b&gt;&lt;span class="entry_details_input"&gt;&lt;a href="http://msdn.com/express/" target="_blank"&gt;Visual Basic or Visual C# Express Editions&lt;/a&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;strong&gt;Hardware: &lt;/strong&gt;None&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Download: &lt;/b&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=251376" target="_blank"&gt;Download&lt;/a&gt; &lt;/div&gt; &lt;div class="entry_details"&gt;&amp;nbsp;&lt;/div&gt; &lt;h3&gt;Introduction&lt;/h3&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt; &lt;p&gt;If you’re anything like me, and I hope for your friends’ and family’s sake you’re not, you believe that annoying others is amazingly entertaining. If that’s the case, then this article is for you.  &lt;p&gt;We are going to build an application that you will copy to a friend’s PC that will, at a specified date and time, cause the computer to appear to start dripping blood down the screen and, after a few seconds, switch to a full-screen image of something terrifying while playing a screaming sound effect. This should sufficiently scare your victim for Halloween (hear the &lt;a class="" href="http://www.coding4fun.net/media/scream.wav" mce_href="http://www.coding4fun.net/media/scream.wav"&gt;built-in scary sound&lt;/a&gt;).  &lt;p&gt;&lt;a href="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/bloody_desktop2.png" mce_href="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/bloody_desktop2.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="261" src="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/bloody_desktop_thumb.png" width="348" border="0" mce_src="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/bloody_desktop_thumb.png"&gt;&lt;/a&gt;  &lt;h3&gt;&lt;b&gt;The Form&lt;/b&gt; &lt;/h3&gt; &lt;p&gt;We will be creating a full-screen, always-on-top, transparent form that will overlay the entire screen. This will be our display surface for the dripping blood.  &lt;p&gt;The form can be created as described by modifying the following properties:  &lt;p&gt;&lt;b&gt;BackColor&lt;/b&gt; – Fuchsia  &lt;p&gt;&lt;b&gt;FormBorderStyle&lt;/b&gt; – None  &lt;p&gt;&lt;b&gt;DoubleBuffered&lt;/b&gt; – True  &lt;p&gt;&lt;b&gt;Text&lt;/b&gt; - &amp;lt;empty string&amp;gt;  &lt;p&gt;&lt;b&gt;WindowState&lt;/b&gt; – Maximized  &lt;p&gt;&lt;b&gt;ShowInTaskbar&lt;/b&gt; – False  &lt;p&gt;&lt;b&gt;TransparencyKey&lt;/b&gt; – Fuchsia  &lt;p&gt;&lt;b&gt;TopMost&lt;/b&gt; - True  &lt;p&gt;This will create our full-screen, transparent form with no visible name, no icon in the task bar, no border that will remain on top of all other windows. With this in place, we can draw whatever we want to on to the form and it will be displayed over whatever happens to be on the screen. A nice bonus to this is that even though the form is maximized, because it is transparent, mouse and keyboard events will pass through to the visible active forms below. The user’s PC should act as though nothing is happening!  &lt;h3&gt;&lt;b&gt;The Blood&lt;/b&gt;  &lt;h3&gt;&lt;/h3&gt;I created a class named &lt;b&gt;BloodDrop&lt;/b&gt; to represent the on-screen blood droplets flowing down the screen. When a droplet is instantiated, it loads its frames of animation from a series of images saved as resources in the application. Each image is located in a directory named &lt;b&gt;images&lt;/b&gt; in the project, and its &lt;b&gt;Build Action&lt;/b&gt; property is set to &lt;b&gt;Embedded Resource&lt;/b&gt;. &lt;/h3&gt; &lt;p&gt;&lt;a href="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/embedded1.png" mce_href="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/embedded1.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" src="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/embedded.png" width="220" border="0" mce_src="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/embedded.png"&gt;&lt;/a&gt;  &lt;p&gt;With the images set as resources, we can load the images in the &lt;b&gt;BloodDrop&lt;/b&gt; constructor as follows:  &lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt;()
    &lt;span class="rem"&gt;' load each animation frame from the app's resources and add it to our frame list&lt;/span&gt;
    &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; file &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; &lt;span class="kwrd"&gt;In&lt;/span&gt; _files
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; img &lt;span class="kwrd"&gt;As&lt;/span&gt; Image = Image.FromStream(&lt;span class="kwrd"&gt;Assembly&lt;/span&gt;.GetExecutingAssembly().GetManifestResourceStream(&lt;span class="str"&gt;"HalloweenVB."&lt;/span&gt; + file))
        _frames.Add(img)
    &lt;span class="kwrd"&gt;Next&lt;/span&gt;

    &lt;span class="rem"&gt;' set our first frame&lt;/span&gt;
    _image = _frames(0)
&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;
&lt;p&gt;&lt;strong&gt;Visual C#&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; BloodDrop()
{
    &lt;span class="rem"&gt;// load each animation frame from the app's resources and add it to our frame list&lt;/span&gt;
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; file &lt;span class="kwrd"&gt;in&lt;/span&gt; _files)
    {
        Image img = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(&lt;span class="str"&gt;"Halloween.images."&lt;/span&gt; + file));
        _frames.Add(img);
    }

    &lt;span class="rem"&gt;// set our first frame&lt;/span&gt;
    _image = _frames[0];
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;The &lt;b&gt;FromStream&lt;/b&gt; method of the &lt;b&gt;Image&lt;/b&gt; object allows loading of an image file from an application’s embedded resource list. To get access to the stream for a specific resource, the name of the resource needs to be known, which is the fully qualified name of the file. In the case of the C# project, the resources are named &lt;b&gt;Halloween.images.&amp;lt;filename&amp;gt;&lt;/b&gt;. The VB project’s resources are named &lt;b&gt;HalloweenVB.&amp;lt;filename&amp;gt;&lt;/b&gt;. Though the images are stored in a directory named &lt;b&gt;images&lt;/b&gt; in both projects, only the C# version includes the directory name as part of the fully qualified name. 
&lt;p&gt;In either case, each file is loaded and stored in a &lt;b&gt;List&lt;/b&gt; of &lt;b&gt;Image&lt;/b&gt; objects. 
&lt;h3&gt;&lt;b&gt;Drawing&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;In creating this application, I decided to stay entirely within the framework so deployment would be as simple as copying a single executable to your victim’s machine. Therefore, I decided to use standard GDI+ calls for drawing, instead of Managed DirectX or some other method. 
&lt;p&gt;At first, I experimented with making each blood droplet a &lt;b&gt;PictureBox&lt;/b&gt; control and moving the control down the screen, but that was not quick enough for smooth animation. I next tried using a timer and drawing to the screen directly inside the &lt;b&gt;Tick&lt;/b&gt; event, however this too was too jerky. Finally, I set the &lt;b&gt;Tick&lt;/b&gt; event to simply invalidate the screen, causing the &lt;b&gt;OnPaint&lt;/b&gt; event to fire. I found that performing screen updates inside this method with the &lt;b&gt;DoubleBuffered&lt;/b&gt; property set to &lt;b&gt;True&lt;/b&gt; allowed for the smoothest animation. 
&lt;p&gt;When the blood is set to be drawn, a timer is started that ticks every 100 milliseconds. This timer simply calls the &lt;b&gt;Invalidate&lt;/b&gt; method of the current form object. When invalidated, the form calls its &lt;b&gt;OnPaint&lt;/b&gt; handler, which we override. 
&lt;p&gt;Inside the &lt;b&gt;OnPaint&lt;/b&gt; handler, we create a new &lt;b&gt;BloodDrop&lt;/b&gt; object and assign a random horizontal position and vertical velocity to it. This provides for an interesting display as the blood drips down. The newly created &lt;b&gt;BloodDrop&lt;/b&gt; is then added to a &lt;b&gt;List&lt;/b&gt; of &lt;b&gt;BloodDrop&lt;/b&gt; types. Finally, the full list of blood drops is enumerated, animated, and drawn. 
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;' create a new blood drop&lt;/span&gt;
&lt;span class="kwrd"&gt;Dim&lt;/span&gt; drop &lt;span class="kwrd"&gt;As&lt;/span&gt; BloodDrop = &lt;span class="kwrd"&gt;New&lt;/span&gt; BloodDrop()

&lt;span class="rem"&gt;' set it to a random location on the screen&lt;/span&gt;
drop.Location = &lt;span class="kwrd"&gt;New&lt;/span&gt; Point(_random.&lt;span class="kwrd"&gt;Next&lt;/span&gt;(SystemInformation.PrimaryMonitorSize.Width), 0)

&lt;span class="rem"&gt;' set it's velocity to a random number&lt;/span&gt;
drop.Velocity = _random.&lt;span class="kwrd"&gt;Next&lt;/span&gt;(40) + 20

&lt;span class="rem"&gt;' add it to our drawing list&lt;/span&gt;
_dropList.Add(drop)

&lt;span class="rem"&gt;' enumerate the drawing list&lt;/span&gt;
&lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; bd &lt;span class="kwrd"&gt;As&lt;/span&gt; BloodDrop &lt;span class="kwrd"&gt;In&lt;/span&gt; _dropList
    &lt;span class="rem"&gt;' animate and then draw the drop            &lt;/span&gt;
    bd.Animate()
    bd.Draw(g)
Next&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;
&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;Visual C#&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// create a new blood drop&lt;/span&gt;
BloodDrop drop = &lt;span class="kwrd"&gt;new&lt;/span&gt; BloodDrop();

&lt;span class="rem"&gt;// set it to a random location on the screen&lt;/span&gt;
drop.Location = &lt;span class="kwrd"&gt;new&lt;/span&gt; Point(_random.Next(SystemInformation.PrimaryMonitorSize.Width), 0);

&lt;span class="rem"&gt;// set it's velocity to a random number&lt;/span&gt;
drop.Velocity = _random.Next(40) + 20;

&lt;span class="rem"&gt;// add it to our drawing list&lt;/span&gt;
_dropList.Add(drop);

&lt;span class="rem"&gt;// enumerate the drawing list&lt;/span&gt;
&lt;span class="kwrd"&gt;foreach&lt;/span&gt;(BloodDrop bd &lt;span class="kwrd"&gt;in&lt;/span&gt; _dropList)
{    
    &lt;span class="rem"&gt;// animate and then draw the drop            &lt;/span&gt;
    bd.Animate();
    bd.Draw(g);
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;At application startup, an instance of the &lt;b&gt;Random &lt;/b&gt;class is created and stored in our &lt;b&gt;_random&lt;/b&gt; member variable. The &lt;b&gt;Next&lt;/b&gt; method requires a parameter for the maximum value of the random number to be returned. In the case of setting the drop’s location, I use the maximum screen width, determined by using the &lt;b&gt;SystemInformation&lt;/b&gt; object. In the case of velocity, a maximum value of 40 pixels is requested, and an additional 20 pixels is added on in case a very low number is randomly selected. 
&lt;p&gt;Drawing the actual drop is pretty simple. The &lt;b&gt;Draw&lt;/b&gt; method of our &lt;b&gt;BloodDrop&lt;/b&gt; class looks like the following: 
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;' draw the drop&lt;/span&gt;
&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Draw(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; g &lt;span class="kwrd"&gt;As&lt;/span&gt; Graphics)
    &lt;span class="rem"&gt;' if we're in "drop" mode, draw the stream behind it&lt;/span&gt;
    &lt;span class="kwrd"&gt;If&lt;/span&gt; _index &amp;gt;= 4 &lt;span class="kwrd"&gt;Then&lt;/span&gt;
        g.DrawImage(_frames(4), &lt;span class="kwrd"&gt;Me&lt;/span&gt;._location.X + 24, 0, _frames(4).Width, &lt;span class="kwrd"&gt;Me&lt;/span&gt;._location.Y + 10)
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

    &lt;span class="rem"&gt;' if we're beyond the bottom of the screen, don't bother drawing the drop&lt;/span&gt;
    &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;._location.Y &amp;lt; SystemInformation.PrimaryMonitorSize.Height &lt;span class="kwrd"&gt;Then&lt;/span&gt;
        g.DrawImage(_image, &lt;span class="kwrd"&gt;Me&lt;/span&gt;._location.X, &lt;span class="kwrd"&gt;Me&lt;/span&gt;._location.Y, _image.Width, _image.Height)
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;Visual C#&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// draw the drop&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Draw(Graphics g)
{
    &lt;span class="rem"&gt;// if we're in "drop" mode, draw the stream behind it&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt;(_index &amp;gt;= 4)
        g.DrawImage(_frames[4], &lt;span class="kwrd"&gt;this&lt;/span&gt;._location.X + 24, 0, _frames[4].Width, &lt;span class="kwrd"&gt;this&lt;/span&gt;._location.Y + 10);

    &lt;span class="rem"&gt;// if we're beyond the bottom of the screen, don't bother drawing the drop&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt;._location.Y &amp;lt; SystemInformation.PrimaryMonitorSize.Height)
        g.DrawImage(_image, &lt;span class="kwrd"&gt;this&lt;/span&gt;._location.X, &lt;span class="kwrd"&gt;this&lt;/span&gt;._location.Y, _image.Width, _image.Height);
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;In each case, we use the &lt;b&gt;Graphics&lt;/b&gt; object provided to us and use the &lt;b&gt;DrawImage&lt;/b&gt; method to draw the correct frame number to the correct position. In order to save some CPU cycles, we first determine whether the drop has passed the lower edge of the screen and, if it is, it is not drawn. The size of the screen can be determined by using the &lt;b&gt;SystemInformation&lt;/b&gt; object and using the &lt;b&gt;PrimaryMonitorSize&lt;/b&gt; method. 
&lt;p&gt;The second part of this method draws the blood trail that follows behind the droplet as it falls. This is done by stretching an image that is 1 pixel tall down the screen to the top of the blood drop graphic. 
&lt;p&gt;In my first attempts at drawing the blood in this manner, I found that the &lt;b&gt;DrawImage&lt;/b&gt; method, when scaling an image as it is doing here, will anti-alias and blend the image to make it appear less blocky. Unfortunately, this caused a great deal of distortion, making the trail look awful. After some experimenting, I found that setting the following properties of the &lt;b&gt;Graphics&lt;/b&gt; object before drawing would allow the image to be stretched without modification. 
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Protected&lt;/span&gt; &lt;span class="kwrd"&gt;Overrides&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; OnPaint(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.Windows.Forms.PaintEventArgs)
    ...
    &lt;span class="rem"&gt;' grab the Graphics object for me app and set some properties for correct drawing&lt;/span&gt;
    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; g &lt;span class="kwrd"&gt;As&lt;/span&gt; Graphics = e.Graphics
    g.PixelOffsetMode = PixelOffsetMode.Half
    g.InterpolationMode = InterpolationMode.NearestNeighbor
    g.CompositingQuality = CompositingQuality.HighSpeed
    ...
&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp; 
&lt;p&gt;&lt;strong&gt;Visual C#&lt;/strong&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="rem"&gt;// grab the Graphics object for this app and set some properties for correct drawing&lt;/span&gt;
    Graphics g = e.Graphics;
    g.PixelOffsetMode = PixelOffsetMode.Half;
    g.InterpolationMode = InterpolationMode.NearestNeighbor;
    g.CompositingQuality = CompositingQuality.HighSpeed;
    ...
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;h3&gt;&lt;b&gt;The Finale&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;After the blood has dripped down the screen for several seconds (10 in the default case), the animation timer is disabled, the screen is cleared and a scary image is quickly displayed along with a loud screaming sound, which should hopefully scare the person at the keyboard. A running count of the time elapsed is stored in a member variable and is incremented by the timer’s &lt;b&gt;Interval&lt;/b&gt; value each time our &lt;b&gt;OnPaint&lt;/b&gt; method is called. 
&lt;p&gt;This is accomplished by creating a &lt;b&gt;PictureBox&lt;/b&gt; on the fly and loading an image into the box. This box is then added to the &lt;b&gt;Controls&lt;/b&gt; collection of the form and displayed. Additionally, two events are handled that will dismiss the application when a user clicks the mouse or presses a key on the keyboard. 
&lt;p&gt;The sound is then loaded from a resource and played using the &lt;b&gt;SoundPlay&lt;/b&gt; object. This looks like the following: 
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;' disable the animation timer &lt;/span&gt;
tmrAnim.Enabled = &lt;span class="kwrd"&gt;False&lt;/span&gt;

&lt;span class="rem"&gt;' create a Picturebox&lt;/span&gt;
&lt;span class="kwrd"&gt;Dim&lt;/span&gt; pb &lt;span class="kwrd"&gt;As&lt;/span&gt; PictureBox = &lt;span class="kwrd"&gt;New&lt;/span&gt; PictureBox()

&lt;span class="rem"&gt;' pull in the scary image from our resources&lt;/span&gt;
pb.Image = Image.FromStream(&lt;span class="kwrd"&gt;Assembly&lt;/span&gt;.GetExecutingAssembly().GetManifestResourceStream(&lt;span class="str"&gt;"HalloweenVB.scary.jpg"&lt;/span&gt;))

&lt;span class="rem"&gt;' set it to fill the screen&lt;/span&gt;
pb.SizeMode = PictureBoxSizeMode.Zoom
pb.Width = SystemInformation.PrimaryMonitorSize.Width
pb.Height = SystemInformation.PrimaryMonitorSize.Height
pb.BackColor = Color.Black

&lt;span class="rem"&gt;' if it gets clicked, or someone presses a key, we want to end the app&lt;/span&gt;
&lt;span class="kwrd"&gt;AddHandler&lt;/span&gt; pb.Click, &lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; pb_Click
&lt;span class="kwrd"&gt;AddHandler&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.KeyDown, &lt;span class="kwrd"&gt;AddressOf&lt;/span&gt; MainForm_KeyDown

&lt;span class="rem"&gt;' add the Picturebox to the controls list&lt;/span&gt;
&lt;span class="kwrd"&gt;Me&lt;/span&gt;.Controls.Add(pb)

&lt;span class="rem"&gt;' play a scary sound&lt;/span&gt;
&lt;span class="kwrd"&gt;Dim&lt;/span&gt; sp &lt;span class="kwrd"&gt;As&lt;/span&gt; SoundPlayer = &lt;span class="kwrd"&gt;New&lt;/span&gt; SoundPlayer(&lt;span class="kwrd"&gt;Assembly&lt;/span&gt;.GetExecutingAssembly().GetManifestResourceStream(&lt;span class="str"&gt;"HalloweenVB.scream.wav"&lt;/span&gt;))
sp.Play()&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Visual C#&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// disable the animation timer&lt;/span&gt;
tmrAnim.Enabled = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

&lt;span class="rem"&gt;// create a Picturebox&lt;/span&gt;
PictureBox pb = &lt;span class="kwrd"&gt;new&lt;/span&gt; PictureBox();

&lt;span class="rem"&gt;// pull in the scary image from our resources&lt;/span&gt;
pb.Image = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(&lt;span class="str"&gt;"Halloween.images.scary.jpg"&lt;/span&gt;));

&lt;span class="rem"&gt;// set it to fill the screen&lt;/span&gt;
pb.SizeMode = PictureBoxSizeMode.Zoom;
pb.Width = SystemInformation.PrimaryMonitorSize.Width;
pb.Height = SystemInformation.PrimaryMonitorSize.Height;
pb.BackColor = Color.Black;

&lt;span class="rem"&gt;// if it gets clicked, or someone presses a key, we want to end the app&lt;/span&gt;
pb.Click += &lt;span class="kwrd"&gt;new&lt;/span&gt; EventHandler(pb_Click);
&lt;span class="kwrd"&gt;this&lt;/span&gt;.KeyDown += &lt;span class="kwrd"&gt;new&lt;/span&gt; KeyEventHandler(MainForm_KeyDown);

&lt;span class="rem"&gt;// add the Picturebox to the controls list&lt;/span&gt;
&lt;span class="kwrd"&gt;this&lt;/span&gt;.Controls.Add(pb);

&lt;span class="rem"&gt;// play a scary sound&lt;/span&gt;
SoundPlayer sp = &lt;span class="kwrd"&gt;new&lt;/span&gt; SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream(&lt;span class="str"&gt;"Halloween.scream.wav"&lt;/span&gt;));
sp.Play();
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;As you can see, the sound and image resources are loaded in an identical manner as the frames of animation shown earlier. 
&lt;h3&gt;&lt;b&gt;The Scheduler&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;The final piece of the puzzle was to allow a user to select the date and time that the animation would start on the victim’s PC. I created a simple configuration dialog box that is displayed the first time the application is run. The dialog allows the person setting up the application to choose the date and time the animation should be fired. This is saved using the &lt;b&gt;Settings&lt;/b&gt; object of the project. This way, the user can put the application in the startup group, or create a registry key to load it on startup, so if the PC is rebooted before the desired time is reached, the application will restart and wait for the time to occur. 
&lt;p&gt;Settings can be added by right-clicking the project in the &lt;b&gt;Solution Explorer&lt;/b&gt; and choosing &lt;b&gt;Properties&lt;/b&gt;. Select the &lt;b&gt;Settings&lt;/b&gt; tab and a new value can be entered. The one for this application looks like the following: 
&lt;p&gt;&lt;a href="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/Settings2.png" mce_href="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/Settings2.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="100" src="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/Settings_thumb.png" width="240" border="0" mce_src="http://coding4fun.net/images/ScaryHalloweenApplication_136D3/Settings_thumb.png"&gt;&lt;/a&gt; 
&lt;p&gt;Now, on application startup, the application’s &lt;b&gt;Settings&lt;/b&gt; can be checked to determine if the configuration dialog needs to be shown, or just wait for the time specified. 
&lt;p&gt;When the application is started, a scheduler timer is created which ticks every minute. The &lt;b&gt;Tick &lt;/b&gt;method for this timer looks at the current time, and if it is greater than or equal to the specified time, it will disable the scheduler timer, maximize the hidden window, and start the animation timer, which will automatically start drawing our blood droplets. 
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; tmrScheduler_Tick(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; System.&lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; tmrScheduler.Tick
    &lt;span class="kwrd"&gt;If&lt;/span&gt; DateTime.Now &amp;gt;= My.Settings.Time &lt;span class="kwrd"&gt;Then&lt;/span&gt;
        &lt;span class="rem"&gt;' re-maximize the window&lt;/span&gt;
        &lt;span class="kwrd"&gt;Me&lt;/span&gt;.WindowState = FormWindowState.Maximized

        &lt;span class="rem"&gt;' disable me timer&lt;/span&gt;
        tmrScheduler.Enabled = &lt;span class="kwrd"&gt;False&lt;/span&gt;

        &lt;span class="rem"&gt;' enable the animation timer&lt;/span&gt;
        tmrAnim.Enabled = &lt;span class="kwrd"&gt;True&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;Visual C#&lt;/strong&gt; &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// called once per minute to check whether it's time to run the show&lt;/span&gt;
&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; tmrScheduler_Tick(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
{
    &lt;span class="rem"&gt;// if the current time is greater than the time set by the user&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt;(DateTime.Now &amp;gt;= Properties.Settings.Default.Time)
    {
        &lt;span class="rem"&gt;// re-maximize the window&lt;/span&gt;
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.WindowState = FormWindowState.Maximized;

        &lt;span class="rem"&gt;// disable this timer&lt;/span&gt;
        tmrScheduler.Enabled = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

        &lt;span class="rem"&gt;// enable the animation timer&lt;/span&gt;
        tmrAnim.Enabled = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.csharpcode pre {
	font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff
}
.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 {
	margin: 0em; width: 100%; background-color: #f4f4f4
}
.csharpcode .lnum {
	color: #606060
}
&lt;/style&gt;

&lt;h3&gt;&lt;b&gt;Deployment&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;As mentioned earlier, one of the main goals of this project was to have an extremely easily deployable application. In order to achieve this, all code was kept inside the framework with no dependencies on things like Managed DirectX. Additionally, all resources used by the application (images and sounds) were setup as embedded resources so they do not need to be deployed separately. 
&lt;p&gt;When you are ready to scare your friend, simply copy the Halloween.exe file to his or her PC. )You may want to enlist someone as the “lookout” so you don’t get caught while doing so!) Create a shortcut to it in the Startup program group, or set it up to run via the registry using the following key for the logged in user: 
&lt;ul&gt;
&lt;li&gt;HKCU\Software\Microsoft\Windows\CurrentVersion\Run&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Simply create a new string key with any Name, and a Data value of the path to the executable. 
&lt;p&gt;Next, start the application once on their PC to setup the date and time for the show to begin. Once that is done, the application will remain running in the background. If the PC is restarted, and the application is setup to run at startup as described above, it will start silently and remain running, waiting for the date and time specified. 
&lt;h3&gt;&lt;b&gt;Summary&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;And there we have it. A very simple application requiring very little code that will elicit quite a reaction from your victim. The code can be very easily modified to include different images, a different sound effect, or even different animation effects. There is plenty of time between now and April Fool’s Day to modify the project for even more fun. 
&lt;h3&gt;&lt;b&gt;Thanks&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;A special thanks to &lt;a href="http://www.joeybphotography.com/" target="_blank"&gt;Joey Buczek&lt;/a&gt; for drawing up the blood drop animation, &lt;a href="http://www.markzaugg.com/" target="_blank"&gt;Mark Zaugg&lt;/a&gt;&amp;nbsp;for testing on a few machines outside my house, and Michelle Leavitt for making my writing a bit more palatable for the masses.&lt;/p&gt;
&lt;h3&gt;Bio&lt;/h3&gt;
&lt;p&gt;Though Brian is a recognized .NET expert with over 6 years experience developing .NET solutions, and over 9 years of professional experience architecting and developing solutions using Microsoft technologies and platforms, he has been "coding for fun" for as long as he can remember.&amp;nbsp; Outside the world of .NET and&amp;nbsp;business applications, Brian enjoys developing&amp;nbsp;both hardware and software projects in the areas of gaming, robotics, and&amp;nbsp;whatever else strikes his fancy for the next ten minutes.&amp;nbsp;He rarely passes up an opportunity to dive into a C/C++&amp;nbsp;or assembly language project.&amp;nbsp; You can reach Brian via his blog at &lt;a href="http://www.brianpeek.com/" target="_blank"&gt;http://www.brianpeek.com/&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=905508" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx">events</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/halloween/default.aspx">halloween</category></item><item><title>Motion-Detecting, Blood Squirting Halloween Skull</title><link>http://blogs.msdn.com/coding4fun/archive/2006/10/30/905480.aspx</link><pubDate>Tue, 31 Oct 2006 07:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:905480</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/905480.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=905480</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=905480</wfw:comment><description>&lt;span id="c4fmetadata"&gt; &lt;table cellspacing="0" cellpadding="1" width="100%" border="0"&gt; &lt;tbody&gt; &lt;tr class="entry_overview"&gt; &lt;td width="50"&gt;&lt;img height="50" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/article_thumb.jpg" width="50"&gt;&lt;/td&gt; &lt;td&gt;&lt;span class="entry_description"&gt;Create a scary surprise for your Halloween trick-or-treaters! With some off-the-shelf components and a bit of code, you can have some fun with your visitors...&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td colspan="2"&gt; &lt;div class="entry_author"&gt;&amp;nbsp;&lt;/div&gt; &lt;div class="entry_author"&gt;Brian Peek&lt;/div&gt; &lt;div class="entry_company"&gt;&lt;a href="http://www.aspsoft.com/"&gt;ASPSOFT, Inc.&lt;/a&gt;&lt;/div&gt;&lt;br&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Difficulty: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Intermediate&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Time Required:&lt;/b&gt; &lt;span class="entry_details_input"&gt;1-3 hours&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Cost: &lt;/b&gt;&lt;span class="entry_details_input"&gt;$100-$200&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Software: &lt;/b&gt;&lt;span class="entry_details_input"&gt;&lt;a href="http://msdn.microsoft.com/express/" target="_blank"&gt;Visual C# Express&lt;/a&gt;, &lt;a href="http://www.phidgets.com/modules.php?op=modload&amp;amp;name=Downloads&amp;amp;file=index&amp;amp;req=viewdownload&amp;amp;cid=3" target="_blank"&gt;Phidgets SDK&lt;/a&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Hardware: &lt;/b&gt;&lt;span class="entry_details_input"&gt;&lt;a href="http://www.airlink101.com/products/aic250w.html"&gt;AirLink101 AIC -250W wireless IP camera&lt;/a&gt;, &lt;a href="http://www.phidgetsusa.com/cat/viewproduct.asp?category=1000&amp;amp;subcategory=1100&amp;amp;SKU=1014" mce_href="http://www.phidgetsusa.com/cat/viewproduct.asp?category=1000&amp;amp;subcategory=1100&amp;amp;SKU=1014"&gt;Phidgets 0/0/4 Interface Kit&lt;/a&gt;, Westinghouse 3-Outlet Heavy Duty Remote, Beckett M60AUL Small Fountain Pump, rubber tubing, plastic skull, solder and soldering iron, external speakers&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Download: &lt;/b&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=251371"&gt;Download&lt;/a&gt; &lt;/div&gt; &lt;div class="entry_details"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt; &lt;p mce_keep="true"&gt;I wanted to build a small device that would terrify small children as they approached my door for Halloween. I suppose this makes me a bad person, but it’s still a lot of fun. &lt;/p&gt; &lt;p&gt;The concept here is pretty simple. We will be using motion detection from a web cam or network-enabled/IP camera to trigger a small fountain pump fitted into a bucket of water to spray anyone that approaches your front door. And, to make it a bit more creepy, we will fit the spray mechanism into a plastic skull.  &lt;p&gt;&lt;b&gt;WARNING: The pump being used will be connected to an A/C wall socket. While the pump is certainly designed to be used with water, please be aware of the fact that you will have water and electricity in close proximity to each other.&lt;/b&gt;  &lt;h3&gt;&lt;b&gt;What You Will Need&lt;/b&gt; &lt;/h3&gt; &lt;ul&gt; &lt;li&gt;A web or network-enabled camera.&amp;nbsp; I am using the &lt;a href="http://www.airlink101.com/products/aic250w.html" mce_href="http://www.airlink101.com/products/aic250w.html"&gt;AirLink101 AIC-250W wireless IP camera&lt;/a&gt;.  &lt;li&gt;A &lt;a href="http://www.phidgetsusa.com/cat/viewproduct.asp?category=1000&amp;amp;subcategory=1100&amp;amp;SKU=1014" mce_href="http://www.phidgetsusa.com/cat/viewproduct.asp?category=1000&amp;amp;subcategory=1100&amp;amp;SKU=1014"&gt;Phidget Interface Kit&lt;/a&gt; 0/0/4 – a USB-controlled board with 4 relays.  &lt;li&gt;A remote-controlled A/C power outlet. I chose the Westinghouse 3-Outlet Heavy Duty Remote, Item #T28074, normally used for Christmas lights.&lt;br&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/outlet1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/outlet1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/outlet.jpg" width="180" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/outlet.jpg"&gt;&lt;/a&gt; &lt;br&gt; &lt;li&gt;A fountain water pump. The one I used in this article is the Beckett M60AUL Small Fountain Pump. Almost any fountain pump will work, however be aware of how far the water will need to be pumped and choose a pump to meet your needs.&lt;br&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/pump1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/pump1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/pump.jpg" width="180" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/pump.jpg"&gt;&lt;/a&gt; &lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/pump21.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/pump21.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/pump2.jpg" width="240" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/pump2.jpg"&gt;&lt;/a&gt; &lt;br&gt; &lt;li&gt;Rubber tubing of the appropriate size to fit the pump, preferably black if you can find it.&lt;br&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/hose1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/hose1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/hose.jpg" width="240" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/hose.jpg"&gt;&lt;/a&gt; &lt;br&gt; &lt;li&gt;A Plastic Skull.&lt;br&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/skull1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/skull1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/skull.jpg" width="180" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/skull.jpg"&gt;&lt;/a&gt; &lt;br&gt; &lt;li&gt;Red food coloring.  &lt;li&gt;A soldering iron, solder and some spare wire.  &lt;li&gt;A set of external speakers with an audio extension cable.  &lt;li&gt;Optional: A strobe light.  &lt;li&gt;Microsoft Visual C# 2005 Express Edition.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;b&gt;&lt;/b&gt; &lt;h3&gt;&lt;b&gt;The Hardware&lt;/b&gt; &lt;/h3&gt; &lt;p&gt;Let’s start by setting up the hardware. We will be using the remote controlled A/C outlet to toggle power to the pump at will. The remote control for the unit I purchased has a separate on and off switch, so we will wire one relay from the Phidget board to the on switch, and one relay to the off switch.  &lt;p&gt;Open the remote control unit. Inside, you should see something similar to the image below:  &lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/opened_remote1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/opened_remote1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/opened_remote.jpg" width="240" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/opened_remote.jpg"&gt;&lt;/a&gt;  &lt;p&gt;Flip the unit over to access the side with the button contacts. My unit had two metal spring-type contacts taped to the board. Once removed, I was able to access the contacts directly. You should see contact pads similar to the following:  &lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/contacts1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/contacts1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/contacts.jpg" width="240" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/contacts.jpg"&gt;&lt;/a&gt;  &lt;p&gt;The pads each contain a common ground contact and an active contact. When the two are bridged, which happens when the button is pressed, the circuit closes and the remote sends the appropriate signal to the receiving unit. We will replicate the button action by tying a relay to each pad so that when the relay closes at our command, the circuit will close, sending the signal to the outlet unit.  &lt;p&gt;Cut 4 equal lengths of wire and strip a bit of insulation off of each end. Carefully solder one end of each wire to each contact pad on the remote control as shown:  &lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/soldered1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/soldered1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/soldered.jpg" width="180" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/soldered.jpg"&gt;&lt;/a&gt;&amp;nbsp;  &lt;p&gt;Additionally, use some electrical tape or rubber bands to affix the battery in place on the remote, if required.  &lt;p&gt;Next, put the opposite end of each wire into the appropriate screw terminal on the Phidget relay board. You will notice on the Phidget board that there are 3 terminals per relay, labeled NO, XC, and NC, where “X” is a number from 0 to 3. These stand for “Normally Open”, “Relay X Common”, and “Normally Closed”. Since we want each circuit to be normally open, we will put one wire of each button to the NO terminal, and one to the XC terminal of each relay. For the on button, insert one wire into the NO terminal of relay 0, and one wire into the 0C screw terminal. Do the same with the wires from the off button, but wire them into relay 1. You should wind up with something looking like the picture below:  &lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/connected1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/connected1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/connected.jpg" width="240" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/connected.jpg"&gt;&lt;/a&gt;&amp;nbsp;  &lt;p&gt;With this in place, we now have a computer-controlled remote control for the outlet. When the fountain pump (or anything else) is plugged into the outlet, it will toggle on and off as we open and close each relay.  &lt;p&gt;Next, we will modify our plastic skull. If you have access to a real skull, feel free to use that instead. I decided to puncture a small hole in the bottom and drill a hole in the nose of the skull. I then fed the tubing through the nose hole and out of the bottom of the skull. You may also wish to run the tubing out of the eyes by either splitting the tubing near the eyes, or using two separate pumps plugged into the remote outlet.  &lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/skull_bottom1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/skull_bottom1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/skull_bottom.jpg" width="240" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/skull_bottom.jpg"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/inserting_hose1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/inserting_hose1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/inserting_hose.jpg" width="180" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/inserting_hose.jpg"&gt;&lt;/a&gt;  &lt;p&gt;Cut holes in the appropriate areas and push the rubber tubing through, leaving just a tiny bit hanging out of the exit hole.  &lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/nose_hose1.jpg" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/nose_hose1.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/nose_hose.jpg" width="180" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/nose_hose.jpg"&gt;&lt;/a&gt;  &lt;p&gt;Leave a generous amount of tubing coming out of the bottom of the skull. You will cut this later to the desired length once the prop is setup outside. When the gadget is later setup outside, you will fill a bucket with warm (or COLD!) water and add some food coloring, and the fountain pump. The pump I used submerges entirely in water, but yours may use an intake tube instead. Then, plug the pump into the remote controlled outlet, and plug the outlet into a standard A/C wall socket.  &lt;p&gt;When the on signal is sent to the remote controlled outlet, the pump will turn on, and water will squirt from the rubber hose inside the skull!  &lt;p&gt;Our skull is set to spray water out of its nose. Let’s set all of this aside for now and move onto the software side of things.  &lt;h3&gt;&lt;b&gt;The Camera&lt;/b&gt; &lt;/h3&gt; &lt;p&gt;For motion detection, I chose to use the AIC-250W wireless IP camera. This allows me to freely mount the camera wherever I wish and not worry about cords. Of course, it will require that you have a wireless access point somewhere nearby to connect the camera and the laptop together. You also could use an ad-hoc network with the camera, but I have not tested this. With the software we will be using, you also should be able to use a standard USB web camera. Regardless of the method chosen, please configure the camera appropriately so that the video output can be seen. In the case of the AIC-250W, it is as simple as running the included utility and setting it up to use your wireless network.  &lt;h3&gt;&lt;b&gt;The Software&lt;/b&gt; &lt;/h3&gt; &lt;p&gt;We will need several pieces installed before we can begin coding. First, ensure that you have Microsoft Visual C# 2005 Express Edition installed.  &lt;p&gt;Following &lt;a href="http://msdn.microsoft.com/coding4fun/someassemblyrequired/babies/default.aspx" target="_blank"&gt;Scott Hanselman’s lead&lt;/a&gt;, I too will be using the excellent &lt;a href="http://www.codeproject.com/cs/media/Motion_Detection.asp" target="_blank"&gt;motion detection project&lt;/a&gt; from Andrew Kirillov.  &lt;p&gt;Download the source code for this project, as we will be modifying what is there to meet our requirements.  &lt;p&gt;You also will need to download and install the latest &lt;a href="http://www.phidget.com/modules.php?op=modload&amp;amp;name=Downloads&amp;amp;file=index&amp;amp;req=viewdownload&amp;amp;cid=3" mce_href="http://www.Phidget.com/modules.php?op=modload&amp;amp;name=Downloads&amp;amp;file=index&amp;amp;req=viewdownload&amp;amp;cid=3"&gt;Phidget's library&lt;/a&gt;.  &lt;p&gt;With those pieces installed and ready, we can begin modifying the software motion detection code.  &lt;p&gt;I am not going to give you a tutorial of Andrew’s source code as that is done at the original site linked above. I suggest reading through that article and exploring the source code a bit to learn what’s going on behind the scenes. The code is somewhat complex in areas, however the project itself, along with the original article, are a fantastic learning experience.  &lt;p&gt;Open the &lt;b&gt;motion_src.sln&lt;/b&gt; file in Visual C# 2005 Express. When the solution is opened, the IDE will prompt you to upgrade the solution to the latest version. Accept the defaults and make your way through the wizard. When complete, you should see your solution with three projects loaded into the IDE.  &lt;p&gt;The first thing we will add to the application is a handler to actually deal with firing the pump when the motion detection alarm is fired, which means we will need to communicate with the PhidgetInterfaceKit. Ensure the Phidget library listed above is installed. Then, right-click on the &lt;b&gt;References &lt;/b&gt;folder in the &lt;b&gt;motion&lt;/b&gt; project and select &lt;b&gt;Add Reference…&lt;/b&gt; . Scroll down and select &lt;b&gt;Phidget21.NET&lt;/b&gt; with runtime version &lt;b&gt;2.0.50727&lt;/b&gt;.  &lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/phidget1.png" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/phidget1.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="197" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/phidget.png" width="240" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/phidget.png"&gt;&lt;/a&gt;  &lt;p&gt;The pump is controlled in a separate thread, so we need to add the &lt;b&gt;System.Threading &lt;/b&gt;library to our code along with the Phidget library. Finally, to play a loud sound through some external speakers, we need to use the &lt;b&gt;System.Media &lt;/b&gt;library. All of this can be done by adding the following &lt;b&gt;using &lt;/b&gt;statements to the top of our &lt;b&gt;MainForm.cs &lt;/b&gt;code: &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Threading;
&lt;span class="kwrd"&gt;using&lt;/span&gt; Phidgets;
&lt;span class="kwrd"&gt;using&lt;/span&gt; Phidgets.Events;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Media;&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;When motion is detected, we want to call a method that will turn the pump on for a bit and then turn it back off. After the pump has been activated, we also want it to wait for the user to click a button or press a button on the keyboard to setup the “trap” again. Otherwise, we run the potential of having the pump fire over and over again while handing out candy or before the “trick-or-treater” leaves. Alternatively, we can have the trap turn off for a specified period of time and then re-enable itself. We will discuss both methods. 
&lt;p&gt;First, add a &lt;b&gt;bool&lt;/b&gt; variable named &lt;b&gt;pumpOn&lt;/b&gt; to the &lt;b&gt;MainForm&lt;/b&gt; class. This will maintain whether we are inside of our event handler, firing the pump. 
&lt;p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; pumpOn = &lt;span class="kwrd"&gt;false&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;p&gt;Next, we need to create an instance of the &lt;b&gt;InterfaceKit&lt;/b&gt; object to communicate with the Phidget board. Under the statement added above, add the following: 
&lt;p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; InterfaceKit ifKit = &lt;span class="kwrd"&gt;new&lt;/span&gt; InterfaceKit(); &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;Now that we have created an instance of the &lt;b&gt;InterfaceKit&lt;/b&gt; object, we need to open communication with the device. In the &lt;b&gt;MainForm&lt;/b&gt; constructor, after the call to &lt;b&gt;InitializeComponent&lt;/b&gt;, add the following line: &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// open the Phidget device&lt;/span&gt;
ifKit.open();&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;Next, look for a method named &lt;b&gt;camera_Alarm &lt;/b&gt;in &lt;b&gt;MainForm.cs&lt;/b&gt;. This is the event that is fired when motion is detected on the camera. Modify the &lt;b&gt;camera_Alarm&lt;/b&gt; method to look like the following: 
&lt;p mce_keep="true"&gt;&amp;nbsp;&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;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; camera_Alarm( &lt;span class="kwrd"&gt;object&lt;/span&gt; sender, System.EventArgs e )
{
    &lt;span class="rem"&gt;// save movie for 5 seconds after motion stops&lt;/span&gt;   
    intervalsToSave = (&lt;span class="kwrd"&gt;int&lt;/span&gt;) ( 5 * ( 1000 / timer.Interval ) );

    &lt;span class="kwrd"&gt;if&lt;/span&gt;(!pumpOn)
    {
        Thread thread = &lt;span class="kwrd"&gt;new&lt;/span&gt; Thread(&lt;span class="kwrd"&gt;new&lt;/span&gt; ThreadStart(ActivatePump));
        thread.Start();
    }
}&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 will, as long as the pump is not activated, spawn a new thread using the &lt;b&gt;ActivatePump&lt;/b&gt; method. Add the following &lt;b&gt;ActivatePump &lt;/b&gt;method to the &lt;b&gt;MainForm &lt;/b&gt;class: &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ActivatePump()
{
    pumpOn = &lt;span class="kwrd"&gt;true&lt;/span&gt;;

    &lt;span class="rem"&gt;// play the terrifying sound&lt;/span&gt;
    SoundPlayer sp = &lt;span class="kwrd"&gt;new&lt;/span&gt; SoundPlayer(&lt;span class="str"&gt;"scream.wav"&lt;/span&gt;));
    sp.Play();

    &lt;span class="rem"&gt;// press on switch, make sure off switch is not pressed&lt;/span&gt;
    ifKit.outputs[0] = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
    ifKit.outputs[1] = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

    &lt;span class="rem"&gt;// leave the pump on for 2 seconds&lt;/span&gt;
    Thread.Sleep(2000);

    &lt;span class="rem"&gt;// press off switch, make sure on switch is not pressed&lt;/span&gt;
    ifKit.outputs[0] = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
    ifKit.outputs[1] = &lt;span class="kwrd"&gt;true&lt;/span&gt;;

    &lt;span class="rem"&gt;// hold it for half a second&lt;/span&gt;
    Thread.Sleep(500);

    &lt;span class="rem"&gt;// ensure no button is pressed&lt;/span&gt;
    ifKit.outputs[0] = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
    ifKit.outputs[1] = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

    &lt;span class="kwrd"&gt;try&lt;/span&gt;
    {
        &lt;span class="rem"&gt;// kill the current thread&lt;/span&gt;
        Thread.CurrentThread.Abort();
    }
    &lt;span class="kwrd"&gt;catch&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;p&gt;This method will set our &lt;b&gt;pumpOn&lt;/b&gt; variable to true and then create a new &lt;b&gt;SoundPlayer &lt;/b&gt;object, loading the file &lt;b&gt;scream.wav &lt;/b&gt;as an embedded resource. The scream.wav file should be from the same directory as the source code. The sound will then be played asynchronously using the &lt;b&gt;Play&lt;/b&gt; method. Note that the scream.wav file located in the project solution is setup to be copied to the output directory on compilation. This can be done by selecting the file in the Solution Explorer and then choosing &lt;b&gt;Copy always&lt;/b&gt; in the &lt;b&gt;Copy to Output Directory&lt;/b&gt; option of the &lt;b&gt;Properties&lt;/b&gt; window. 
&lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/copyoutput1.png" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/copyoutput1.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/copyoutput.png" width="228" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/copyoutput.png"&gt;&lt;/a&gt; 
&lt;p&gt;Next, we set the relays. Relay 0 (which is the On button if you wired as suggested above) is turned on while relay 1 (the Off button) is turned off. This is held for 2 seconds to allow the water to squirt out by putting the thread to sleep. Then, the relays are switched. The Off button is pressed (relay 1) and the On button is opened (relay 0). This is held for half a second, and then both relays are returned to their open positions. When this completes, we terminate our current thread so the process can begin again. Note that we wrap the call to &lt;b&gt;Abort&lt;/b&gt; in an exception handler. When a thread is aborted, an exception is generated by the CLR. In this case we don’t care about the exception, so it is caught and thrown away. 
&lt;p&gt;At this point, you have two ways to handle resetting the software. One option is to add an additional &lt;b&gt;Thread.Sleep&lt;/b&gt; call to the method above, wait for several minutes, and reset &lt;b&gt;pumpOn&lt;/b&gt; to false:&amp;nbsp;&amp;nbsp;&lt;pre class="csharpcode"&gt;...&lt;/pre&gt;&lt;pre class="csharpcode"&gt;ifKit.outputs[1] = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

&lt;span class="rem"&gt;// wait two minutes&lt;/span&gt;
Thread.Sleep(120000);

pumpOn = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

&lt;span class="kwrd"&gt;try&lt;/span&gt;
... &lt;/pre&gt;
&lt;p&gt;The other option is to add a button to the &lt;b&gt;MainForm&lt;/b&gt; and set the &lt;b&gt;pumpOn&lt;/b&gt; member variable to false when clicked. This will allow you to manually reset the effect after the candy has been handed out and the door is closed. 
&lt;p&gt;To do this, simply drag a button over to the &lt;b&gt;MainForm&lt;/b&gt;, double-click it, and add the following to the generated &lt;b&gt;Click&lt;/b&gt; event handler: &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnReset_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
{
    pumpOn = &lt;span class="kwrd"&gt;false&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;h3&gt;&lt;b&gt;Running the Application&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;Press F5 to compile and run the application. When running, click on the &lt;b&gt;File&lt;/b&gt; menu and choose the appropriate option to open the camera type you have. For the AIC-250W, we will be using the MJPEG URL option. You can connect to this camera with the following URL: 
&lt;p&gt;http://&amp;lt;camera’s IP address&amp;gt;/mjpeg.cgi 
&lt;p&gt;If everything has gone to plan, you should see the output from the camera show up in the center of the window. 
&lt;p&gt;&lt;a href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/app1.png" mce_href="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/app1.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="226" src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/app.png" width="240" border="0" mce_src="http://coding4fun.net/images/MotionDetectingBloodSquirtingHalloweenSk_12F2E/app.png"&gt;&lt;/a&gt; 
&lt;p&gt;The red lines around objects in the scene denote changes sensed by the software. 
&lt;h3&gt;&lt;b&gt;Final Tweaks&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;For my environment, I noticed that the motion detection alarm was a bit too sensitive. If you find the same, there is a simple modification you can make to decrease the sensitivity. 
&lt;p&gt;The level at which the alarm is set is determined by a private member variable inside the &lt;b&gt;Camera &lt;/b&gt;class. If we expose that variable through a public property, we can then set that property when our application starts. By testing various values of this property, you should find one that is suitable for your area. 
&lt;p&gt;Open the &lt;b&gt;Camera.cs&lt;/b&gt; file and add the following property to the code: &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// AlarmLevel property&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; AlarmLevel
{
    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; alarmLevel; }
    set { alarmLevel = &lt;span class="kwrd"&gt;value&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;p&gt;Next, move back to the &lt;b&gt;MainForm.cs&lt;/b&gt; file. Look for a method named &lt;b&gt;OpenVideoSource&lt;/b&gt;. This method is where the &lt;b&gt;Camera&lt;/b&gt; object is created. Right below the call to the &lt;b&gt;Camera&lt;/b&gt; object’s constructor, add the following line, substituting a value that works for you: &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// create camera&lt;/span&gt;
Camera camera = &lt;span class="kwrd"&gt;new&lt;/span&gt; Camera( source, detector );

&lt;span class="rem"&gt;// ADD: level at which alarm is fired&lt;/span&gt;
camera.AlarmLevel = 0.010;
&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;For some additional fun, note that the &lt;b&gt;Motion&lt;/b&gt; menu of the application contains an option to record video when motion is detected. With this checked, the application will write an AVI file out to its running directory when the alarm is fired…that is, when the scream is played and the blood is squired on your unsuspecting visitor! 
&lt;h3&gt;&lt;b&gt;Putting It All Together&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;The final setup is quite simple. 
&lt;ol&gt;
&lt;li&gt;Fill up a bucket of water and add the red food coloring. 
&lt;li&gt;Submerge the pump (or the intake hose) into the water. 
&lt;li&gt;Hide the bucket behind a covered stand or inside a box. 
&lt;li&gt;Place the skull on top of the stand or box with the tubing running down into the pump’s output. 
&lt;li&gt;Plug the pump into the remote controlled A/C power outlet. 
&lt;li&gt;For some extra fun, plug a strobe light into the remote controlled outlet as well! 
&lt;li&gt;Plug that outlet into your outdoor power outlet, or run a cord to an outlet inside your home. 
&lt;li&gt;Configure and install the camera in an inconspicuous location near the skull and plug it into an outlet that isn’t the remote-controlled outlet. Make sure the camera is mounted sturdily so the camera doesn’t move and interfere with the motion detection. 
&lt;li&gt;Hide some external PC speakers near the skull and run the audio cable inside your home to your PC or laptop. (Make sure to turn up the volume!) 
&lt;li&gt;Back inside, plug the Phidget board (with the remote control connected to it ) into a USB port on your PC. 
&lt;li&gt;If you are using a wired camera of some sort, plug that in as well. 
&lt;li&gt;Run the application and wait for someone to approach the door!&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;When the software senses motion on the camera, the sound will play through the speakers and the relays will fire, turning on the outlet, which will fire the water pump. The “blood” will spray out of the skull and terrify the person outside that you’ve either a) just watched on the output screen, or b) recorded to an AVI file for later embarrassment. When you are ready to engage the gadget again, just click the “Reset” button and wait for the next visitor. 
&lt;h3&gt;&lt;b&gt;Conclusion&lt;/b&gt; &lt;/h3&gt;
&lt;p&gt;That’s all there is to it! With a bit of soldering and some off-the-shelf components, you can create a scary, fun, and wet surprise for your trick-or-treaters! &lt;/p&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3&gt;Bio&lt;/h3&gt;
&lt;p&gt;Though Brian is a recognized .NET expert with over 6 years experience developing .NET solutions, and over 9 years of professional experience architecting and developing solutions using Microsoft technologies and platforms, he has been "coding for fun" for as long as he can remember.&amp;nbsp; Outside the world of .NET and&amp;nbsp;business applications, Brian enjoys developing&amp;nbsp;both hardware and software projects in the areas of gaming, robotics, and&amp;nbsp;whatever else strikes his fancy for the next ten minutes.&amp;nbsp;He rarely passes up an opportunity to dive into a C/C++&amp;nbsp;or assembly language project.&amp;nbsp; You can reach Brian via his blog at &lt;a href="http://www.brianpeek.com/" target="_blank"&gt;http://www.brianpeek.com/&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=905480" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/events/default.aspx">events</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/halloween/default.aspx">halloween</category></item></channel></rss>