<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Attilan Software: C#, .NET, Image Tools for Forms</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/" />
    <link rel="self" type="application/atom+xml" href="http://www.attilan.com/atom.xml" />
    <id>tag:www.attilan.com,2008-04-23://3</id>
    <updated>2009-11-18T05:57:49Z</updated>
    <subtitle>Constructing software tools in C#, .NET, and Windows Forms.</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Personal 4.1</generator>

<entry>
    <title>A Simple Way to Change the Color of a Highlighted List View Item in XAML</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2009/11/a-simple-way-to-change-the-col.php" />
    <id>tag:www.attilan.com,2009://3.935</id>

    <published>2009-11-18T05:57:49Z</published>
    <updated>2009-11-18T05:57:49Z</updated>

    <summary> I haven’t worked with Windows Forms that much since last December.&#160; This year, I’ve worked on projects that involve ASP.NET, Linq to Sql, and web services.&#160; I’m currently taking a class in WPF from Foothill College—you can visit Cal...</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="C# Coding Tips" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="WPF and XAML" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="List view items with Highlight brush set to Red" border="0" alt="List view items with Highlight brush set to Red" src="http://www.attilan.com/ListviewitemswithHighlightbrushsettoRed.png" width="322" height="232" /> </p>  <p>I haven’t worked with Windows Forms that much since last December.&#160; This year, I’ve worked on projects that involve ASP.NET, Linq to Sql, and web services.&#160; I’m currently taking a class in WPF from Foothill College—you can <a href="http://www.schrotenboer.com/foothill/csharp.htm" target="_blank">visit Cal Schrotenboer’s page</a> to see a description of the classes offered.&#160; The classes are all conducted online and you don’t have to travel to the campus at all.&#160; In addition, you can join the MSDN Academic Alliance program and get access to Microsoft software (include Expression Studio and Windows 7).</p>  <p>Learning WPF has been extremely fun and rewarding, but at times, frustrating!&#160; I’m trying to do as much in XAML as possible.&#160; I am doing an Image Viewer for my last class project, making great strides in some areas—and then getting stuck when I try to add what must be the most simple feature ever: changing the ListViewItem selected color.&#160; </p>  <p>But due to my ignorance a simple task can take hours!&#160; My only desire was to see the color of selected items changed to something other than the default.</p>  <p>My first take—which led me down the wrong path—was to add a Style Trigger.&#160; The Trigger would set the Background color when IsSelected was true on the ListViewItem.&#160; Or so I thought!</p>  <pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Style</span> <span style="color: #ff0000">TargetType</span>=<span style="color: #0000ff">&quot;{x:Type ListViewItem}&quot;</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Style.Resources</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">SolidColorBrush</span> <span style="color: #ff0000">x</span>:<span style="color: #ff0000">Key</span>=<span style="color: #0000ff">&quot;SelectedBackgroundBrush&quot;</span> <span style="color: #ff0000">Color</span>=<span style="color: #0000ff">&quot;DarkCyan&quot;</span> <span style="color: #0000ff">/&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Style.Resources</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Style.Triggers</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">Trigger</span> <span style="color: #ff0000">Property</span>=<span style="color: #0000ff">&quot;IsSelected&quot;</span> <span style="color: #ff0000">Value</span>=<span style="color: #0000ff">&quot;true&quot;</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">      <span style="color: #0000ff">&lt;</span><span style="color: #800000">Setter</span> <span style="color: #ff0000">Property</span>=<span style="color: #0000ff">&quot;Background&quot;</span> <span style="color: #ff0000">Value</span>=<span style="color: #0000ff">&quot;Red&quot;</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">      <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Setter</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Trigger</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Style.Triggers</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Style</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>Nope, no matter how I tried to massage that, it didn’t work.&#160; Even more frustrating, I changed IsSelected to IsMouseOver and that worked fine.</p>

<p>As William Han explained to me on <a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/f10c6c9c-a869-42c3-8695-0f9b04bf615b/" target="_blank">.NET Developer Forums</a>, ListViewItem's base type ListBoxItem changes a Border background in control template instead of ListBoxItem.Background on the selected item.&#160; William suggested a workaround could be modifying SystemColors.HighlightBrush since ListBoxItem's control template uses it.</p>

<p>Here’s what did work:</p>

<pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Page.Resources</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">Style</span> <span style="color: #ff0000">TargetType</span>=<span style="color: #0000ff">&quot;ListViewItem&quot;</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            <span style="color: #0000ff">&lt;</span><span style="color: #800000">Style.Resources</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">                <span style="color: #0000ff">&lt;</span><span style="color: #800000">SolidColorBrush</span> <span style="color: #ff0000">x</span>:<span style="color: #ff0000">Key</span>=<span style="color: #0000ff">&quot;{x:Static SystemColors.HighlightBrushKey}&quot;</span> <span style="color: #ff0000">Color</span>=<span style="color: #0000ff">&quot;Red&quot;</span><span style="color: #0000ff">/&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">            <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Style.Resources</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">        <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Style</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Page.Resources</span><span style="color: #0000ff">&gt;</span>  
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">ListView</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">ListViewItem</span><span style="color: #0000ff">&gt;</span>Item 1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ListViewItem</span><span style="color: #0000ff">&gt;</span>    
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">ListViewItem</span><span style="color: #0000ff">&gt;</span>Item 2<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ListViewItem</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">ListViewItem</span><span style="color: #0000ff">&gt;</span>Item 3<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ListViewItem</span><span style="color: #0000ff">&gt;</span>    
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">ListView</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span></pre></pre>

<p>It’s a brute force method—changing the highlight color for all ListViewItem objects, but it works, as you can see by the Kaxaml screenshot on top.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Crystal Image Toolkit on CodeProject and misc Crystal articles</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/12/crystal-image-toolkit-on-codep.php" />
    <id>tag:www.attilan.com,2008://3.670</id>

    <published>2008-12-07T20:49:52Z</published>
    <updated>2008-12-07T20:49:52Z</updated>

    <summary>Yesterday, I placed version 1.0.0. of Crystal Image Toolkit on CodeProject with an expanded version of the tutorial. If you’re visiting here from CodeProject, here is an index of articles I’ve written about misc features in the Crystal Image Toolkit:...</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Crystal Toolkit" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>Yesterday, I placed version 1.0.0. of <a href="http://www.codeproject.com/KB/graphics/crystal_image_grid_viewer.aspx" target="_blank">Crystal Image Toolkit on CodeProject</a> with an expanded version of the <a href="http://www.attilan.com/2008/12/tutorial-1-adding-an-image-thu.php">tutorial</a>.</p>  <p>If you’re visiting here from CodeProject, here is an index of articles I’ve written about misc features in the Crystal Image Toolkit:</p>  <ol>   <li><a href="http://www.attilan.com/2008/12/factory-for-crystalcollector.php">Factory For Crystal Collector</a>.</li>    <li><a href="http://www.attilan.com/2008/07/crystal-image-toolkit-081-head.php">Header Groups for Image Thumbnail Grid View</a>.</li>    <li><a href="http://www.attilan.com/2008/05/scaling-thumbnail-images-with.php">Scaling Thumbnail Images with CrystalImageGridView</a>.</li>    <li><a href="http://www.attilan.com/2008/05/crystal-image-toolkit-080-thum.php">A brief explanation of the pan window for CrystalPictureShow</a>.</li>    <li><a href="http://www.attilan.com/2007/04/new-samples-illustrate-how-to.php">Screenshots of using CrystalMemoryCollector with CrystalPictureShow to create a wait dialog</a>.</li> </ol>  <p>The articles may refer to earlier versions of the toolkit, please ignore and use the latest version.&#160; The samples included in the toolkit will give you a better idea of how to use the various features mentioned in the articles.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Tutorial 1: Adding an Image Thumbnail control to a Form</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/12/tutorial-1-adding-an-image-thu.php" />
    <id>tag:www.attilan.com,2008://3.668</id>

    <published>2008-12-06T21:14:22Z</published>
    <updated>2008-12-06T21:14:22Z</updated>

    <summary>Part one of a series of tutorials explaining how to use the Crystal Image Toolkit.&#160; In this example, I will show you how to quickly add an image thumbnail control to your Windows Form application. First of all, download the...</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Crystal Toolkit" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Windows Forms" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>Part one of a series of tutorials explaining how to use the <a href="http://www.attilan.com/2008/12/crystal-image-toolkit-100-rele.php">Crystal Image Toolkit</a>.&#160; In this example, I will show you how to quickly add an image thumbnail control to your Windows Form application.</p>  <p>First of all, download the latest Crystal Image Toolkit from my <a href="http://www.attilan.com/downloads/">downloads</a> page.&#160; Compile the code using the solution that I provided.&#160; </p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/Designer%20toolbox_2.png"><img title="Designer toolbox" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="220" alt="Designer toolbox" src="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/Designer%20toolbox_thumb.png" width="244" border="0" /></a> </p>  <p>Create a new Windows Forms application in Visual Studio. In the Visual Studio toolbox, add a new tab called Crystal Image Toolkit (to separate it from Crystal Reports) and add the controls found in CrystalToolkit.dll.</p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/step%201%20-%20drop%20CrystalImageGridView%20on%20Form_2.png"><img title="step 1 - drop CrystalImageGridView on Form" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="454" alt="step 1 - drop CrystalImageGridView on Form" src="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/step%201%20-%20drop%20CrystalImageGridView%20on%20Form_thumb.png" width="504" border="0" /></a> </p>  <p>Select the control called “CrystalImageGridView”.&#160; This is the control that displays the thumbnail images.&#160; Drag this control onto your new Form.</p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/step%202%20-%20set%20properties_2.png"><img title="step 2 - set properties" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="263" alt="step 2 - set properties" src="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/step%202%20-%20set%20properties_thumb.png" width="257" border="0" /></a> </p>  <p>Now go to the Properties window, with “crystalImageGridView1” selected.&#160; Change the Dock property to Fill.&#160; Change the Orientation property to Vertical.</p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/Control%20after%20set%20properties_2.png"><img title="Control after set properties" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="444" alt="Control after set properties" src="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/Control%20after%20set%20properties_thumb.png" width="504" border="0" /></a> </p>  <p>After you set the properties, the image grid control should look like the above picture.&#160; The blue borders simply give you an idea of what the image items will look like in the selected state.&#160; The broken image bitmap is just a placeholder.&#160; At runtime, your images will be placed inside this blue rectangle.&#160; Yes, you can change many other properties, including the border color, background color, and so on.&#160; But for now, let’s accept the defaults.</p>  <p>Let’s write a little bit of code.&#160; Go to the events tab and double click on the Load event of the Form.&#160; Now that you are in Form1.cs, let’s add this field:</p>  <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, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">   <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">     <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #008000">/// &lt;summary&gt;</span></pre>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> <span style="color: #008000">/// CrystalCollector object, assists in retrieving image files in a specified folder.</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> <span style="color: #008000">/// &lt;/summary&gt;</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> <span style="color: #0000ff">private</span> CrystalCollector _theCollector = <span style="color: #0000ff">null</span>;</pre><br />
  </div><br />
</div></p>

<p>The CrystalCollector object is the controller in this framework.&#160; </p>

<p>The collector works with the CrystalImageGridView and the CrystalImageGridModel.&#160; It finds image files set in the ImageLocation property, creates objects to mirror those files as CrystalImageItem objects, and places those within the model.&#160; The collector spawns a background thread to start thumbnailing the image items; this thread sends events to the view to tell it when an image thumbnail is available.&#160; That is what happens behind the scenes, but here in this simple example, you only need to add this method for your Form:</p>

<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, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
  <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> InitCollector()</pre>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     _theCollector =</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>         CrystalCollectorFactory.DefaultFactory.CreateCollector(CrystalCollectorType.CrystalFileCollector);</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>&#160; </pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     <span style="color: #008000">// Add the CrystalImageGridView object to the collector.</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>     <span style="color: #008000">// The collector will work with the view to draw the images.</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>     _theCollector.SetupView(crystalImageGridView1);</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>&#160; </pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>     <span style="color: #008000">// Optional:</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span>     <span style="color: #008000">// Set an initial folder to collect images.</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>     <span style="color: #008000">// If no folder is set, collector starts at MyPictures in WinXP or Pictures folder in Vista</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span>     <span style="color: #008000">//CrystalCollectorFactory.DefaultFactory.InitCollectorSource(&quot;c:\\myImages&quot;, _theCollector);</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>&#160; </pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>     <span style="color: #008000">// Tell CrystalFileCollector to collect the images in the ImageLocation folder.</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span>     _theCollector.CollectImages();</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span> }</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span>&#160; </pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> Form1_Load(<span style="color: #0000ff">object</span> sender, EventArgs e)</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  20:</span> {</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  21:</span>     InitCollector();</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  22:</span> }</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  23:</span>&#160; </pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  24:</span> <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnFormClosing(FormClosingEventArgs e)</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  25:</span> {</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  26:</span>     <span style="color: #0000ff">if</span> (_theCollector != <span style="color: #0000ff">null</span>)</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  27:</span>     {</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  28:</span>         _theCollector.StopCollection();</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  29:</span>     }</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  30:</span>     <span style="color: #0000ff">base</span>.OnFormClosing(e);</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  31:</span> }</pre><br />
  </div><br />
</div></p>

<p>InitCollector creates the collector object using a factory.&#160; The type it chooses is a file-based collector.&#160; You could just create a new CrystalFileCollector yourself, but it is better to use the Factory.&#160; This can be used to track down objects getting created/destroyed later.</p>

<p>Once the collector has been created, we call SetupView, passing in the CrystalImageGridView object that we dropped onto the Form.&#160; This must be done before we gather any images.&#160; The collector creates a CrystalImageGridModel object and links up the view to it.&#160; The model must know about certain view properties, which affects how the image items will be displayed.</p>

<p>CollectImages is called at the end, which tells the collector to look at the ImageLocation and start gathering data about the images found there.&#160; In this case, we did not set the ImageLocation—the default is set to your Pictures folder (on Vista) or MyPictures folder (in WinXP).&#160; If you want to initialize another ImageLocation, use the code I commented out above the call to CollectImages.</p>

<p>Form1_Load calls InitCollector.&#160; But there’s also the override to OnFormClosing, which calls the StopCollector method on the collector object.&#160; This call will stop any background threads going on to thumbnail the images.</p>

<p><a href="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/Simple%20form%20with%20thumbnail%20image%20control_2.png"><img title="Simple form with thumbnail image control" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="416" alt="Simple form with thumbnail image control" src="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/Simple%20form%20with%20thumbnail%20image%20control_thumb.png" width="504" border="0" /></a> </p>

<p>When you press F5 and run, you should see the thumbnails for whatever images are in your Pictures folder.&#160; Hopefully, they will be images of friends, family, and pets instead of comic book images!&#160; Play around with this form—you should see that the control responds to resizing events, making the number of image items per row grow or shrink the form.&#160; You can do ctrl-click and shift-click on image items for multiple selection as well.</p>

<p><a href="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/Thumbnail%20image%20location_2.png"><img title="Thumbnail image location" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="502" alt="Thumbnail image location" src="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/Thumbnail%20image%20location_thumb.png" width="704" border="0" /></a> </p>

<p>Where are these thumbnail images stored?&#160; The CrystalThumbnailer object, which does the work of creating them, has a property called ThumbnailLocationRoot.&#160; By default, it is your AppData folder, under the name of your Company and Product name.&#160; The collector creates a sub folder here, based on the hash number of the original location.&#160; It stores the thumbnails here—the largest thumbnail size it needs to display.&#160; In these simple demos, the thumbnails will exist permanently.&#160; I’ve decided the behavior to retain or erase them is application dependent and left the choice up to you.</p>

<p></p>

<p></p>

<p></p>

<p>This is obviously a very simple example, but I have included many sample Form applications in the toolkit.</p>

<p>SimpleImageGridDemo shows a slightly more complex version of this application, by allowing you to open any folder and view the thumbnail images.</p>

<p><a href="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/PictureShowDemo_2.png"><img title="PictureShowDemo" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="454" alt="PictureShowDemo" src="http://www.attilan.com/WindowsLiveWriter/Tutorial1AddinganImageThumbnailcontrolto_B28D/PictureShowDemo_thumb.png" width="604" border="0" /></a> </p>

<p>PictureShowControllerDemo shows you how to create a more realistic picture viewing application.&#160; A split container is used to hold the CrystalImageGridView in Horizontal orientation on the bottom pane.&#160; The top pane contains the CrystalPictureShow control, which is used to display images, magnify them, and present slideshows.&#160; There’s also a panning window that appears whenever the image is displayed in a non-fit mode.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Crystal Image Toolkit: 1.0.0 release, Factory and Refactoring</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/12/crystal-image-toolkit-100-rele.php" />
    <id>tag:www.attilan.com,2008://3.667</id>

    <published>2008-12-06T20:18:00Z</published>
    <updated>2009-02-25T15:44:11Z</updated>

    <summary> Crystal Image Toolkit 1.0.0 is ready to download. Enhancements: Factory object:&#160; CrystalCollectorFactory was added to allow you to create the correct collector objects based on file or folder input.&#160; Using this factory will help keep track of when objects...</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Crystal Toolkit" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Downloads" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p></p>  <p>Crystal Image Toolkit 1.0.0 is ready to <a href="http://www.attilan.com/downloads/Crystal_Toolkit_100.zip">download</a>.</p>  <p><strong><u>Enhancements:</u></strong></p>  <p><strong>Factory object:</strong>&#160; CrystalCollectorFactory was added to allow you to create the correct collector objects based on file or folder input.&#160; Using this factory will help keep track of when objects are created.&#160; See <a href="http://www.attilan.com/2008/12/factory-for-crystalcollector.php">this post for details</a>.    <br /></p>  <p><strong>CrystalCollector:</strong> added StopCollector as a pure virtual method.&#160; StopCollector stops the collection operation initiated by CollectImages.</p>  <p>   <br /><strong>CrystalCollector:</strong>&#160; SortCrystalList with CrystalSortType.DisplayName will now sort the image items with case insensitivity.&#160; This sort option uses DisplayNameLower property in CrystalImageItem.</p>  <p>   <br /><strong>CrystalImageItem:</strong>&#160; Added ImageCorrupted property.&#160; True means image is corrupt and cannot be displayed, false means it is safe to display.</p>  <p>   <br /><strong>CrystalImageItem:</strong>&#160; Added DisplayNameLower property.&#160; Takes the DisplayName string and does a ToLower call.</p>  <p>   <br /><strong>CrystalImageItem, CrystalCollector, and CrystalImageGridModel</strong> all implement <strong>IDisposable</strong>.&#160; This objects hold references to Image objects, which can now be disposed of more efficiently.</p>  <p>   <br /><strong>Event notification: </strong> All events are now broadcast using the EventNotifier class.&#160; This utility walks through the invocation list of a multi-cast delegate and checks to see if InvokeRequired is true before calling the delegate. </p>  <p><strong><u>Code Cleanup:</u></strong></p>  <p><strong>Exception Handling Refactoring: </strong>Previously, the Crystal&#160; Image Toolkit was eating all exceptions.&#160; This was a bad practice and actually hid threading errors that were occurring in the forms and controls that were using the toolkit.&#160; Now those exception handlers have all been removed, except for one in CrystalFileCollector:&#160; LoadImage.&#160; The exception here is caught when an image is corrupt and cannot be loaded from the disk.&#160; In that case, ImageCorrupted in CrystalImageItem is set to true, see below.</p>  <p>   <br /><strong>CrystalCollector:</strong> AddView method was removed.&#160; I had intended to support multiple views, but I need to wrap up this toolkit for the time being and move on to other projects.&#160; Only 1 view is supported.&#160; AddView has been changed to SetupView.&#160; The internal list of views has been removed.</p>  <p>&#160;</p>  <p><strong>Download:</strong> <a href="http://www.attilan.com/downloads/Crystal_Toolkit_100.zip">Crystal Image Toolkit 1.0.0</a>.&#160; Totally free, open-source, C# .NET Framework 2.0 for Windows Forms, works with both Visual Studio 2005 and 2008.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Factory for CrystalCollector</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/12/factory-for-crystalcollector.php" />
    <id>tag:www.attilan.com,2008://3.663</id>

    <published>2008-12-03T17:05:47Z</published>
    <updated>2008-12-03T17:05:47Z</updated>

    <summary> I’ve implemented a factory for all the CrystalCollector-based objects in the upcoming release of the Crystal Toolkit.&#160; Using the factory helps keep track of objects getting created and deleted.&#160; I’ve also implemented IDispose in CrystalCollector and CrystalImageGridModel.&#160; These objects...</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Crystal Toolkit" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p><a href="http://www.attilan.com/WindowsLiveWriter/FactoryforCrystalCollector_7FF2/factory%20diagram_4.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px; display: inline" title="Factory Diagram for Crystal Collector objects." border="0" alt="Factory Diagram for Crystal Collector objects." src="http://www.attilan.com/WindowsLiveWriter/FactoryforCrystalCollector_7FF2/factory%20diagram_thumb_1.png" width="704" height="439" /></a> </p>  <p>I’ve implemented a factory for all the CrystalCollector-based objects in the upcoming release of the Crystal Toolkit.&#160; Using the factory helps keep track of objects getting created and deleted.&#160; I’ve also implemented IDispose in CrystalCollector and CrystalImageGridModel.&#160; These objects keep a reference to Image objects that need to be released when the Crystal objects are no longer needed.&#160; CrystalLogger, which works with log4net, reports when CrystalCollectors are created in the factory and released in the Dispose methods.</p>  <p>The next version of the Crystal Toolkit will be 1.0, at last.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Interview Coding: Reverse a string in C</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/11/interview-coding-reverse-a-str.php" />
    <id>tag:www.attilan.com,2008://3.656</id>

    <published>2008-11-21T19:00:22Z</published>
    <updated>2008-11-21T19:14:19Z</updated>

    <summary>Here&apos;s another question that is often asked, reversing a string in C.  I think most people can get through this one easily, creating a temporary char variable and swapping the first and last values.  However, I came across a slight optimization to this method.</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Interview Coding" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="interviewcoding" label="Interview Coding" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>Here's another question that is often asked, reversing a string in C.&#160; I think most people can get through this one easily, creating a temporary char variable and swapping the first and last values.&#160; However, I came across a slight optimization to this method:</p>  <pre class="csharpcode"><span class="kwrd">char</span> *strrev2(<span class="kwrd">char</span> *s,<span class="kwrd">int</span> n)
{
       <span class="kwrd">int</span> i=0;
       <span class="kwrd">while</span> (i&lt;n/2)
       {
           <span class="rem">//uses the null character as the temporary storage,</span>
           <span class="rem">// for the front character.</span>
           *(s+n) = *(s+i);
           <span class="rem">// swap the front and last character.</span>
           *(s+i) = *(s + (n - i -1));
           <span class="rem">// put the front character in n-1 position.</span>
           *(s+n-i-1) = *(s+n);
           i++;
       }
       <span class="rem">// tie off the string with the NULL character.</span>
       *(s+n) = <span class="str">'\0'</span>;
       <span class="kwrd">return</span> s;
}
<span class="kwrd">char</span>* strrev(<span class="kwrd">char</span>* s)
{
       <span class="kwrd">return</span> strrev2(s, strlen(s));
}</pre>
<style type="text/css">
.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; }</style>

<p>With this example, you don't need a temporary variable.&#160; You use the char at the end of the string, the one that holds the NULL (\0) character that marks the end of the string.&#160; Just remember to put the NULL character back when you are done.</p>

<p>A slight twist: afterward, the interviewer may ask you how to reuse this code to reverse a sentence.&#160; This is why I wrote strrev2.&#160; I won't write the code that does this, but here's the general algorithm:</p>

<ol>
  <li>Call strrev to reverse the entire string at one time.</li>

<p>  <li>Take the new string, parse the tokens separated by whitespace and delimeters.</li></p>

<p>  <li>Reverse each token inside the reversed sentence string.</li></p>

<p>  <li>The result should be a perfectly reversed string.</li><br />
</ol></p>]]>
        
    </content>
</entry>

<entry>
    <title>Interview Coding: atoi, itoa in C</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/11/interview-coding-atoi-itoa-in.php" />
    <id>tag:www.attilan.com,2008://3.654</id>

    <published>2008-11-18T19:00:15Z</published>
    <updated>2008-11-18T19:00:15Z</updated>

    <summary>Converting a string to an integer is another classic interview question.&#160; I was asked this one during my Microsoft interview in 1991 and I was so nervous I butchered it badly.&#160; I still remember sweating bullets even now, almost twenty...</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Interview Coding" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>Converting a string to an integer is another classic interview question.&#160; I was asked this one during my Microsoft interview in 1991 and I was so nervous I butchered it badly.&#160; I still remember sweating bullets even now, almost twenty years later.&#160; Fortunately, the manager took pity and allowed me to play a debugging exercise where I discovered the mistakes I had made.</p>  <p>The function atoi is shorthand for ascii to integer.&#160; You call it like this:</p>  <pre class="csharpcode">    <span class="kwrd">int</span> fooval = atoi(<span class="str">&quot;123&quot;</span>);</pre>
<style type="text/css">

<p></p>

<p></p>

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>It can be written in a few lines of code, but it hinges on your awareness of the <a href="http://www.asciitable.com/" target="_blank">Ascii table</a>.&#160; ASCII stand for American Standard Code for Information Interchange; it’s the fundamental building block that allows computers to exchange information.&#160; There are codes for uppercase alphanumeric characters (A-Z) in the range 65-90, and the lowercase alphanumeric characters (a-z) in the range 97-122.&#160; Numerals 0-9 are in the range 48-57.&#160; Your knowledge of the Ascii table can help you not only with these interview coding exercises, but many others as well.</p>

<p>Another concept that will aid you is the knowledge of how C works with character pointers:</p>

<pre class="csharpcode"><span class="kwrd">char</span>* index = <span class="str">&quot;123&quot;</span>;</pre>
<style type="text/css">

<p></p>

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style><style type="text/css"></p>

<p></p>

<p></p>

<p>.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>The index variable is a pointer, but it points at the first character in the char string (1).&#160; If you increment the index, it will point at the next char value (2).&#160; You can determine when you’ve reached the end of the string by testing the value to see if it is the NULL character, \0.&#160; All C strings are terminated by this value.&#160; You have to remember to look for the NULL character when searching C strings, and if you are creating a new string, you have to remember to place that at the end.</p>

<p>Now that we are armed with this knowledge, we can write atoi:</p>

<pre class="csharpcode"><span class="kwrd">int</span> atoi( <span class="kwrd">char</span>* pStr ) 
{
  <span class="kwrd">int</span> iRetVal = 0; 
 
  <span class="kwrd">if</span> ( pStr )
  {
    <span class="kwrd">while</span> ( *pStr &amp;&amp; *pStr &lt;= <span class="str">'9'</span> &amp;&amp; *pStr &gt;= <span class="str">'0'</span> ) 
    {
      iRetVal = (iRetVal * 10) + (*pStr - <span class="str">'0'</span>);
      pStr++;
    }
  } 
  <span class="kwrd">return</span> iRetVal; 
}</pre>
<style type="text/css">

<p></p>

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>This implementation starts off by clearing out iRetVal with 0.&#160; In case the string is NULL or empty, the return value will be 0.&#160; We loop through the string, looking for numeric characters.&#160; When we encounter one, we determine the integer value (*pstr - ‘0’) and add that iRetVal.&#160; iRetVal gets multiplied by 10 to make the correct scale value.&#160; Note that the first time around, iRetVal is 0.&#160; Finally, we increment the char index to move to the next character in the string.</p>

<p>This is pretty simple and straightforward, although it isn’t perfect.&#160; What if there is a negative sign in the string (“-123’).&#160; Whenever you write code during an interview, it won’t be perfect.&#160; It’s important to be able to identify weaknesses and bugs in your code to the interviewer.</p>

<p>The reverse function for integer to ascii, itoa, is a bit more complex.&#160; I was asked to write this just a couple of years ago during an interview.&#160; Funny enough, the engineer who asked me to write it was an ex-Microsoft engineer.&#160; I solved it correctly for a default case where the number is base 10.&#160; He showed me a way to write it for base 10, base 16, or any base value.&#160; You will call itoa like this:</p>

<pre class="csharpcode">    printf(<span class="str">&quot;itoa(123) = %s\n&quot;</span>,itoa(123));</pre>
<style type="text/css">

<p></p>

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>This is the default way of calling itoa.&#160; The return value is “123” which is output by the printf function.&#160; But, as this ex-Microsoft engineer asked me, what if we wanted to output the hexadecimal value, “7b”?&#160; You would call an overloaded itoa function like this, with the base (16 for hexadecimal) like this:</p>

<pre class="csharpcode">    printf(<span class="str">&quot;itoa(123) = %s\n&quot;</span>,itoa(123, 16));</pre>
<style type="text/css">

<p></p>

<p>.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>Now let’s write the function.&#160; We will actually write two functions here.&#160; If you do this during interview, you will score extra points.&#160; First the itoa function that takes the base as the second parameter:</p>

<pre class="csharpcode"><span class="kwrd">char</span> *itoa(<span class="kwrd">int</span> n, <span class="kwrd">int</span> b) 
{
    <span class="kwrd">static</span> <span class="kwrd">char</span> digits[] = <span class="str">&quot;0123456789abcdefghijklmnopqrstuvwxyz&quot;</span>;
    <span class="kwrd">int</span> i=0, sign;
    <span class="kwrd">char</span> *s = <span class="kwrd">new</span> <span class="kwrd">char</span>[100];
    
    <span class="kwrd">if</span> ((sign = n) &lt; 0)
        n = -n;

<p>    <span class="kwrd">do</span> {<br />
        s[i++] = digits[n % b];<br />
    } <span class="kwrd">while</span> ((n /= b) &gt; 0);</p>

<p>    <span class="kwrd">if</span> (sign &lt; 0)<br />
        s[i++] = <span class="str">'-'</span>;<br />
    s[i] = <span class="str">'\0'</span>;</p>

<p>    <span class="kwrd">return</span> strrev(s);<br />
}</pre><br />
<style type="text/css"></p>

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>And now the default itoa function, which assumes the most common case, where we call it for base 10 numbers:</p>

<pre class="csharpcode"><span class="kwrd">char</span> *itoa(<span class="kwrd">int</span> n) 
{
    <span class="kwrd">return</span> itoa(n, 10);
}</pre>
<style type="text/css">

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>This itoa function with the base parameter makes use of a character array called digits.&#160; This array contains the values 0-9, followed by the lowercase alphanumeric values a-z.&#160; These values will be used for the individual characters in the return string value:</p>

<pre class="csharpcode">    <span class="kwrd">static</span> <span class="kwrd">char</span> digits[] = <span class="str">&quot;0123456789abcdefghijklmnopqrstuvwxyz&quot;</span>;</pre>
<style type="text/css">

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>The first thing we need to do is check the sign of the number we need to convert.&#160; Is it less than 0?&#160; If so, we’ll need to remember this for later.</p>

<p>Now we do a tight compact loop through number n:</p>

<pre class="csharpcode">    <span class="kwrd">do</span> {
        s[i++] = digits[n % b];
    } <span class="kwrd">while</span> ((n /= b) &gt; 0);</pre>
<style type="text/css">

<p>.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>The char string holding the return value starts getting the individual digits chopped off number n.&#160; We chop them off using the modulus operator: %.&#160; When b is set to 10 and n is 123, <strong>n % b</strong> becomes 123 mod 10.&#160; The value of that mod is 3.&#160; Index 3 inside the digits array is the character ‘3’.</p>

<p>The loop prunes the digits off the number n.&#160; N gets reduced (by the base number) as the loop goes on with the expression “<strong>n /= b</strong>”.&#160; When N is 123, the first time through this loop, it becomes 12.</p>

<p>Let’s picture what happens to the return char string s and integer n as the loop progresses:</p>

<p><strong>First pass:</strong>&#160; n = 12, s = “3”</p>

<p><strong>Second pass:</strong> n = 1, s = “32”</p>

<p><strong>Third pass:</strong> n = 0, s = “321”</p>

<p>The loop terminates when n reaches 0.&#160; Now we take a look at the sign value.&#160; If the number was negative, we had the char minus sign (1).&#160; Don’t forget to mark the end of the string with the NULL character as I mentioned previously.</p>

<p>Now we almost have the return string value, except it is in reverse.&#160; You can call strrev to reverse it back to the proper form and return the value.</p>

<p>This may lead into writing a function to reverse a string value…which I will write next time.</p>]]>
        
    </content>
</entry>

<entry>
    <title>C# Coding Shortcuts: IsNullorEmpty, Path object, BackgroundWorker, MethodInvoker.</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/11/c-coding-shortcuts-isnulloremp.php" />
    <id>tag:www.attilan.com,2008://3.652</id>

    <published>2008-11-16T19:21:27Z</published>
    <updated>2008-11-16T19:25:27Z</updated>

    <summary>Here&apos;s a few things that I discovered during the past year, thanks to my co-workers (Andy, Jon, Geoff).  Some of these items are so simple that I was embarrassed not to know about them. </summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term=".NET Framework" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="C# Coding Tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>I once heard <a href="http://www.sellsbrothers.com/" target="_blank">Chris Sells</a> (in a podcast with <a href="http://www.hanselman.com/" target="_blank">Scott Hanselman</a>) mention that the .NET Framework is so vast, that he was constantly uncovering objects/methods that he had already written himself.&#160; Here's a few things that I discovered during the past year, thanks to my co-workers (Andy, Jon, Geoff).&#160; Some of these items are so simple that I was embarrassed not to know about them.&#160; Here is the list:</p>  <p>1.&#160; The simple <strong>string.IsNullOrEmpty</strong> method.&#160; </p>  <pre class="csharpcode"> <span class="kwrd">if</span> (<span class="kwrd">string</span>.IsNullOrEmpty(imageFileName))
   <span class="kwrd">return</span> <span class="kwrd">false</span>;</pre>
<style type="text/css">

<p></p>

<p></p>

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>Before I encountered this, I was always writing C++ style tests like "if (string != null) &amp;&amp; (if string.Length &gt; 0)".&#160; Doing both in one shot is a great piece of shorthand.</p>

<p>2.&#160; The powerful <strong>Path</strong> object.&#160; </p>

<pre class="csharpcode">Path.GetDirectoryName(filePathName);</pre>
<style type="text/css">

<p></p>

<p></p>

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>One of the first things I did in C# was to port over a number of C++ methods that dissected a path string, chopping off the extension, returning the folder path, etc.&#160; A nice exercise, but it was totally unnecessary.&#160; The Path object has the following methods: <strong>GetDirectoryName, GetExtension, GetFileName, GetFileNameWithoutExtension</strong>.</p>

<p>3.&#160; The beautiful <strong>BackgroundWorker</strong> object.</p>

<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> PSPUnpackWorker : BackgroundWorker 
{
    <span class="kwrd">public</span> PSPUnpackWorker()
    {
        WorkerReportsProgress = <span class="kwrd">true</span>;
        WorkerSupportsCancellation = <span class="kwrd">true</span>;
        DoWork += PSPUnpackWorker_DoWork;
    }</pre>
<style type="text/css">

<p></p>

<p>.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>Have you ever wanted to perform a task in a background thread?&#160; You can easily spawn off a worker thread on your own by creating a Thread object and calling Start.&#160; But what if you wanted your worker thread to raise an event, to tell you it's completed step X out of 100?&#160; And perhaps hook up this data to a progress bar control?</p>

<p>Don't do it the hard way, the .NET Framework is all setup to accommodate this pattern already with the BackgroundWorker object.</p>

<p>The <a href="http://www.attilan.com/downloads/">ComicShowControllerDemo in the Crystal Toolkit</a> has an example of a BackgroundWorker communicating to a ProgressBar control.&#160; First, as shown above, I derive my own specialized class from the BackgroundWorker.&#160; In the constructor, I set the properties in base class to true, WorkerReportsProgress and WorkerSupportsCancellation.&#160; The former property allows me to call the ReportProgress method.&#160; The control containing the ProgressBar can subscribe to the ProgressChanged event of the background worker and determine the percentage of completion.</p>

<pre class="csharpcode">PSPUnpackWorker _unpackWorker = <span class="kwrd">new</span> PSPUnpackWorker();
_unpackWorker.ProgressChanged += unpackWorker_ProgressChanged;
_unpackWorker.RunWorkerCompleted += unpackWorker_RunWorkerCompleted;
_unpackWorker.RunWorkerAsync();</pre>
<style type="text/css">
.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; }</style><style type="text/css">

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>When RunWorkerAsync is called, the DoWork method inside PSPUnpackWorker is executed:</p>

<pre class="csharpcode"><span class="kwrd">void</span> PSPUnpackWorker_DoWork(<span class="kwrd">object</span> sender, DoWorkEventArgs e)
{
    <span class="kwrd">foreach</span> (CrystalImageItem imageItem <span class="kwrd">in</span> Collector.GridModel)
    {
        <span class="kwrd">if</span> (CancellationPending)
        {
            e.Cancel = <span class="kwrd">true</span>;
            <span class="kwrd">return</span>;
        }        
        ....
        <span class="kwrd">if</span> (CanRaiseEvents)
        {
            <span class="kwrd">float</span> percent = ((<span class="kwrd">float</span>)++index/(<span class="kwrd">float</span>)Collector.GridModel.Count)*100f;
            <span class="kwrd">int</span> percentDone = Convert.ToInt32(percent);
            ReportProgress(percentDone);
        }
    }
    e.Result = <span class="kwrd">true</span>;
}</pre>
<style type="text/css">
.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; }</style>

<p>Inside the DoWork method, you can perform whatever tasks are required in the background worker.&#160; I've sandwiched these between checking to see if a cancel action was requested at the beginning, and reporting the progress at the end.</p>

<p>4.&#160; The mighty <strong>MethodInvoker</strong> object.</p>

<pre class="csharpcode">_imageForm.Invoke(<span class="kwrd">new</span> MethodInvoker(<span class="kwrd">delegate</span>
 {
     _viewerMain.SetImageInfo(imageInfo);
     _viewerMain.ToolTipText = imageItem.ToolTipText;

<p>     SetScale();<br />
 }));</pre><br />
<style type="text/css"></p>

<p></p>

<p></p>

<p>.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>In Windows Forms programming, you often encounter the problem of needing to update the controls on the main form, running in the main UI thread.&#160; If you try to update these controls without using Invoke or BeginInvoke, you will no doubt encounter an error such as <strong>"Cross-thread operation not valid: Control X accessed from a thread other than the thread it was created on."</strong></p>

<p>You could take the main Windows Form, test InvokeRequired, and then call Invoke or BeginInvoke.&#160; You would have to create a delegate and pass this as a parameter.&#160; The delegate would take care of calling the controls on the main form.</p>

<p>There's an easier way: use an Anonymous method, coupled with the MethodInvoker (as shown above).&#160; Using this technique, it's like creating an inline delegate.&#160; The code inside the delegate has access to the outerscope variables, such as imageInfo.&#160; It's another great piece of shorthand.</p>

<p>When the code inside the delegate portion becomes too large, I will place them inside a new method, and call that method within the MethodInvoker:</p>

<pre class="csharpcode">ImageGridView.BeginInvoke(
    <span class="kwrd">new</span> MethodInvoker(<span class="kwrd">delegate</span>
    {
        InitInitialImageImp(index, ignoreGroupHeader);
    }));</pre>
<style type="text/css">

<p></p>

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>You can find some other interesting tips about MethodInvoker and using invoke with UI controls <a href="http://timl.net/2008/01/begininvoke-methodinvoker-and-anonymous.html" target="_blank">on TimL's .NET Blog</a>.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Converting from uint to a Hexadecimal string value in C#</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/11/converting-from-uint-to-a-hexa.php" />
    <id>tag:www.attilan.com,2008://3.651</id>

    <published>2008-11-15T06:28:29Z</published>
    <updated>2008-11-16T17:33:38Z</updated>

    <summary><![CDATA[Here's a short but useful static funtion: converting a uint into a properly formatted hexadecimal string value in C#. public static string ConvertToHexString(uint value) { StringBuilder builder = new StringBuilder(&quot;0x&quot;); builder.Append(Convert.ToString(value, 16).PadLeft(8, '0')); return builder.ToString(); } .csharpcode, .csharpcode pre {...]]></summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term=".NET Framework" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="C# Coding Tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>Here's a short but useful static funtion: converting a uint into a properly formatted hexadecimal string value in C#.</p>  <pre class="csharpcode">        <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">string</span> ConvertToHexString(<span class="kwrd">uint</span> <span class="kwrd">value</span>)
        {
            StringBuilder builder = <span class="kwrd">new</span> StringBuilder(<span class="str">&quot;0x&quot;</span>);
            builder.Append(Convert.ToString(<span class="kwrd">value</span>, 16).PadLeft(8, <span class="str">'0'</span>));
            <span class="kwrd">return</span> builder.ToString();
        }</pre>
<style type="text/css">

<p>.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>This is pretty self-explanator, but the ToString method on Convert takes an optional second parameter for the base, which we sit to base 16 for the hexadecimal string value.&#160; If you run this test code:</p>

<pre class="csharpcode"><span class="kwrd">string</span> test = ConvertToHexString(177);</pre>
<style type="text/css">
.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; }</style>

<p>The hex string value for 177 returned is: <strong>0x000000b1</strong>.&#160; The PadLeft method after the ToString call gives us the leading zeroes.&#160; Without PadLeft, all we would see is <strong>0xb1</strong>.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Interview Coding: Reversing a Singly Linked List in C</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/11/interview-coding-reversing-a-s.php" />
    <id>tag:www.attilan.com,2008://3.650</id>

    <published>2008-11-14T18:47:22Z</published>
    <updated>2008-11-14T18:52:01Z</updated>

    <summary>Here&apos;s a classic interview whiteboard exercise: reversing a singly linked list.  This was extremely popular in the 1980s and 1990s, because C/C++ were the most popular languages at that time.  You had to have a basic knowledge of pointers, linked lists, allocating/deallocating memory, etc, and you could guarantee that this question would be asked.</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Interview Coding" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="interviewcoding" label="Interview Coding" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>Here's a classic interview whiteboard exercise: reversing a singly linked list.&#160; This was extremely popular in the 1980s and 1990s, because C/C++ were the most popular languages at that time.&#160; You had to have a basic knowledge of pointers, linked lists, allocating/deallocating memory, etc, and you could guarantee that this question would be asked.&#160; But as we've moved into languages liked Java and C#, which provide advanced functionality to manage the heap with garbage collection, and especially with C#'s use of generic collections in .NET Framework 2.0, most of us have pleasantly forgotten about the drudge work in managing linked lists.&#160; But it's still a valid interview question, though when you are asked, it's like getting hit with an arctic blast of wind.</p>  <p>I will present a solution in C, perhaps not the perfect one, as there are many approaches.</p>  <p>First of all, let's define a Node structure that is the building block of the linked list:</p>  <pre class="csharpcode"><span class="rem">// Node structure representing a single item in the list.</span>
<span class="kwrd">struct</span> node
{
    node(<span class="kwrd">char</span> val) {a = val;}
    <span class="kwrd">char</span> a;
    node* next;
};</pre>
<style type="text/css">

<p></p>

<p></p>

<p></p>

<p></p>

<p><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>This is a very simple Node structure, it contains a single char, and a pointer to the next node in the linked list.&#160; The constructor takes a char value so we can construct the object and set the value at the same time.&#160; You want to keep this simple during the interview.&#160; </p>

<p>Let's create a linked list, three nodes, with the values ABC.&#160; It won't be necessary for you to write this code during the interview, but just in case you were born after 1980 and never saw a linked list constructed before, here it is:</p>

<pre class="csharpcode">    <span class="rem">// Test revlist with a list of 4 items, abcd.</span>
    node* head = NULL;
    node* node1 = <span class="kwrd">new</span> node(<span class="str">'a'</span>);
    head = node1;
    node* node2 = <span class="kwrd">new</span> node(<span class="str">'b'</span>);
    node1-&gt;next = node2;
    node* node3 = <span class="kwrd">new</span> node(<span class="str">'c'</span>);
    node2-&gt;next = node3;
    node3-&gt;next = NULL;</pre>
<style type="text/css">

<p></p>

<p></p>

<p></p>

<p></p>

<p>.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: consolas, "Courier New", courier, monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}<br />
.csharpcode pre { margin: 0em; }<br />
.csharpcode .rem { color: #008000; }<br />
.csharpcode .kwrd { color: #0000ff; }<br />
.csharpcode .str { color: #006080; }<br />
.csharpcode .op { color: #0000c0; }<br />
.csharpcode .preproc { color: #cc6633; }<br />
.csharpcode .asp { background-color: #ffff00; }<br />
.csharpcode .html { color: #800000; }<br />
.csharpcode .attr { color: #ff0000; }<br />
.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}<br />
.csharpcode .lnum { color: #606060; }</style></p>

<p>Now let's write the function that reverses this list.&#160; There are a few ways to do it.&#160; One way is to loop through the list, create a temporary node pointer, and swap node pairs until you get to the end.&#160; </p>

<pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #008000">// Reverse a singly linked list.</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #008000">// Take the head of the list and return the new head of</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"><span style="color: #008000">// the reversed list.</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">node* revlist_simple(node* head)
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">{
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #008000">// init the return value (new head) to null</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  node *ret = NULL;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #008000">// walk thru the existing list.</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #008000">// let's say it's a -&gt; b -&gt; c</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">while</span> (head != NULL) 
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  {
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #008000">// tmp = a, b, c</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    node *tmp = head;
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #008000">// head = b, c, null</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    head = head-&gt;next;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #008000">// a-&gt;next = null</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #008000">// b-&gt;next = a</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #008000">// c-&gt;next b</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    tmp-&gt;next = ret;
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #008000">// ret = a</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #008000">// ret =b</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    <span style="color: #008000">// c</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">    ret = tmp;
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  }
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #008000">// now the list is:</span>
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #008000">// c-&gt; b -&gt; a -&gt; null</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">   <span style="color: #008000">// return the head of the reverse linked list.</span>
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">  <span style="color: #0000ff">return</span> ret;
</pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px">}
</pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px"></pre></pre>

<p>As I said at the beginning of this article, this isn't the only way to reverse a linked list.&#160; There are many other approaches that are probably more efficient.</p>

<p>Thank you to the commenter who suggested this much simpler approach, rather than the first clunky way I tried to do it.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Numbing the Pain of Whiteboard Coding During Interviews</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/11/numbing-the-pain-of-whiteboard.php" />
    <id>tag:www.attilan.com,2008://3.649</id>

    <published>2008-11-12T20:50:18Z</published>
    <updated>2008-11-21T19:08:21Z</updated>

    <summary>Programmers and software developers must undergo a series of tests and trials during their interview process before they are judged worthy.  During a phone screen you typically get questions that test your basic knowledge of Windows, C# and .NET Framework, and if you pass that stage you are invited for an in-person interview.  During that interview, at least one person on the development team will ask you to go to the whiteboard and write some code.</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Interview Coding" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="interviewcoding" label="Interview Coding" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>Programmers and software developers must undergo a series of tests and trials during their interview process before they are judged worthy.&#160; During a phone screen you typically get questions that test your basic knowledge of Windows, C# and .NET Framework, and if you pass that stage you are invited for an in-person interview.&#160; During that interview, at least one person on the development team will ask you to go to the whiteboard and write some code.&#160; <a href="http://www.joelonsoftware.com/articles/fog0000000073.html">Joel on Software</a> has some pretty good guidelines on what sort of code a candidate will write.</p>  <p>It's a great technique for detecting if the person really is a coder/programmer and not a poser.&#160; (Or, as one of my college professors once said, to weed out the <a href="http://www.imdb.com/title/tt0083929/" target="_blank">Spicolis</a>.)&#160; Whenever my company is hiring someone, myself or someone on my team will make the candidate perform this coding exercise.</p>  <p>However, when I am the candidate, I look forward to whiteboard coding about as much as a trip to the dentist.&#160; I actively dread the moment when someone says, go to the whiteboard and write some code.&#160; I feel a certain pain in my mind, akin to that dreaded pinch when the dentist injects Novocain into my mouth.&#160; When I arrive at the whiteboard, my mind goes blank.&#160; My knees feel weak.&#160; I feel as if I suddenly belong in the marketing group.&#160; Only I'm not thin or attractive enough to work in marketing.</p>  <p>Therefore, to overcome this fear, I've started collecting all kinds of interview whiteboard coding examples, and will share them with you here.&#160; Most of the code you will see here is not the code I wrote during my interview.&#160; But even if the interview went well or it was a disaster, I went home and tried to write the code when I was more relaxed.</p>  <p>I review these examples before going into a new interview.&#160; I don't memorize the code per se; I do remember the general pattern of the solution and stumble through it on the whiteboard.</p>  <p>I'll be writing several articles in the weeks ahead, but this post will keep an index of all whiteboard code, which will be written in C:</p>  
<p><a href="http://www.attilan.com/2008/11/interview-coding-fibonacci-fun.php">Interview Coding: Fibonacci sequence</a></p>
<p><a href="http://www.attilan.com/2008/11/interview-coding-reversing-a-s.php">Interview Coding: Reversing a Singly Linked List in C</a></p>
<p><a href="http://www.attilan.com/2008/11/interview-coding-atoi-itoa-in.php">Interview Coding: atoi, itoa in C</a></p>
<p><a href="http://www.attilan.com/2008/11/interview-coding-reverse-a-str.php">Interview Coding: Reverse a string in C</a></p>]]>
        
    </content>
</entry>

<entry>
    <title>Interview Coding: Fibonacci function</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/11/interview-coding-fibonacci-fun.php" />
    <id>tag:www.attilan.com,2008://3.648</id>

    <published>2008-11-12T20:26:27Z</published>
    <updated>2008-11-12T20:42:07Z</updated>

    <summary>Writing a function that returns the nth number in a Fibonacci sequence can either be the easiest interview whiteboard question or the hardest.  If you&apos;re like me, your daily activities revolve around events, delegates, background threads, data grid views, custom controls, or reading about some new area of C# and .NET that you&apos;ve never encountered before.  A strange sequence of numbers stuns you like a phaser on Star Trek. </summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Interview Coding" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="interviewcoding" label="Interview Coding" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>Writing a function that returns the nth number in a Fibonacci sequence can either be the easiest interview whiteboard question or the hardest.&#160; If you're like me, your daily activities revolve around events, delegates, background threads, data grid views, custom controls, or reading about some new area of C# and .NET that you've never encountered before.&#160; A strange sequence of numbers stuns you like a phaser on Star Trek.&#160; Even worse, you've probably heard of Fibonacci during your days at the University or in other interviews, but you just can't recall what it is.</p>  <p>If you're unfamiliar with Fibonacci, the interviewer will usually prep you by giving you a list of the first few numbers:</p>  <p><strong>0 1 1 2 3 5 8 13 21</strong></p>  <p>The interviewer should explain the most obvious property of the Fibonacci sequence: each number is the sum of the previous two numbers, if N &gt; 1.&#160; 1 is the sum of 0+1, 2 is the sum of 1+1, 3 is the sum of 2+1, etc.&#160; There are other properties of the Fibonacci sequence, which you can read about on <a href="http://en.wikipedia.org/wiki/Fibonacci_number" target="_blank">this Wikipedia article</a>.</p>  <p>You will be asked to write a function that returns the result of Fib(n).&#160; The Wikipedia article explains clearly, if N &gt; 1, the Fibonacci result is F(n-1) + F(n-2).&#160; If you see this, you can almost write the code, but it may not be explained to you in this fashion.&#160; The interviewer may tell you that Fib(1) == 1, and Fib(5) == 5.&#160; How can that be?&#160; It's helpful to think of the Fibonacci sequence in an array, starting at index 0:</p>  <table border="1" cellspacing="0" cellpadding="2" width="400"><tbody>     <tr>       <td valign="top" width="44"><strong>F0</strong></td>        <td valign="top" width="44"><strong>F1</strong></td>        <td valign="top" width="44"><strong>F2</strong></td>        <td valign="top" width="44"><strong>F3</strong></td>        <td valign="top" width="45"><strong>F4</strong></td>        <td valign="top" width="45"><strong>F5</strong></td>        <td valign="top" width="45"><strong>F6</strong></td>        <td valign="top" width="45"><strong>F7</strong></td>        <td valign="top" width="42"><strong>F8</strong></td>     </tr>      <tr>       <td valign="top" width="44">0</td>        <td valign="top" width="45">1</td>        <td valign="top" width="45">1</td>        <td valign="top" width="46">2</td>        <td valign="top" width="46">3</td>        <td valign="top" width="47">5</td>        <td valign="top" width="47">8</td>        <td valign="top" width="47">13</td>        <td valign="top" width="46">21</td>     </tr>   </tbody></table>  <p>&#160;</p>  <p>Now you can see, ironically enough, that Fib(5) is 5, but there's a logical reason, it's at index 5.&#160; Fib(4) doesn't equal 4, it equals 3, because it is the 4th (after 0) in the sequence.&#160; Once you understand that, you can start to write the code:</p>  <pre class="csharpcode"><span class="kwrd">int</span> fib(<span class="kwrd">int</span> n)
{
    <span class="kwrd">if</span> (n &lt;= 1)
        <span class="kwrd">return</span> n;

<p>    <span class="kwrd">return</span> fib(n-1) + fib(n-2);<br />
}</pre></p>

<p>This is the preferred way to write a Fibonacci function, because it uses <a href="http://en.wikipedia.org/wiki/Recursion_(computer_science)" target="_blank">recursion</a>.&#160; If N is 0 or 1, that value will be returned.&#160; If N is greater than 1, the fib function calls itself recursively, not once, but twice, with the 2 previous numbers in the sequence, n-1 and n-2.&#160; If you call this with N set to 2, then fib will call itself twice with fib(1) and fib(0), which will return 1 and 0, and the sum will be 1.&#160; It works like this for any higher value as well.</p>

<p>The wrong approach would be to set the Fibonacci sequence in a pre-defined array, and going to the Nth index and returning the value there.&#160; But the interviewer will point out that the sequence can go on infinitely and you could never set down all the values.</p>

<p>This is not a perfect function.&#160; If the numbers are negative, a negative value is returned.&#160; You can argue that there will be a buildup of recursive stack values (if N is 10000 the stack will be enormous), or that we are losing performance by making two recursive calls in one function.</p>

<p>Why is recursion the preferred method?&#160; It makes the code simple and easy to understand.&#160; If you look at the Fibonacci definition in the Wikipedia article, the code above resembles that pseudocode definition almost perfectly.&#160; You've solved the problem in the fewest lines of code.&#160; We always hope to hire programmers who can deliver elegant solutions to complex problems.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Crystal Image Toolkit 0.82 released: Bug fixes and minor enhancements</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/10/crystal-image-toolkit-082-rele.php" />
    <id>tag:www.attilan.com,2008://3.646</id>

    <published>2008-10-19T06:42:49Z</published>
    <updated>2008-10-19T06:49:42Z</updated>

    <summary>Crystal Image Toolkit 0.82 is ready to download. Minor Enhancements: CrystalImageItem: Added DisplayName property. This property will be used by CrystalImageGridView when it draws the text for the image item.&#160; The DisplayName is separate and distinct from the ImageName.&#160; ImageName...</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Crystal Toolkit" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Downloads" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p>Crystal Image Toolkit 0.82 is ready to <a href="http://www.attilan.com/downloads/Crystal_Toolkit_082.zip">download</a>.</p>  <p><strong><u>Minor Enhancements:</u></strong></p>  <p><strong>CrystalImageItem</strong>: Added <strong>DisplayName</strong> property. </p>  <p>This property will be used by CrystalImageGridView when it draws the text for the image item.&#160; The DisplayName is separate and distinct from the ImageName.&#160; ImageName for CrystalFileCollector is the name of the image file &quot;image.png&quot; whereas DisplayName could be &quot;image1&quot;. </p>  <p>If DisplayName is not set, it will default to the value in ImageName. </p>  <p><strong>CrystalImageItem</strong>: SplitImagePath now sets DisplayName as well as ImageName, ImageLocation. </p>  <p><strong>CrystalImageItem</strong>: ToString() method uses DisplayName instead of ImageName. </p>  <p><strong>CrystalImageGridModel</strong>, added new methods to help skip <strong>CrystalGroupItem</strong> objects...</p>  <ol>   <li>FirstNonHeaderIndex:      <br />&#160;&#160;&#160; Finds the index of the first item in the model that is not a CrystalGroupItem. </li>    <li>LastNonHeaderIndex:      <br />&#160;&#160;&#160; Finds the index of the last item in the model that is not a CrystalGroupItem. </li>    <li>PrevNonHeaderIndex:      <br />&#160;&#160;&#160; Finds the index of the previous item in the model that is not a CrystalGroupItem. </li>    <li>NextNonHeaderIndex:      <br />&#160;&#160;&#160; Finds the index of the next item in the model that is not a CrystalGroupItem. </li> </ol>  <p><strong>CrystalImageGridView</strong>: ShowThumbnails property added. </p>  <p>Set this property to false if you do not want anything displayed in the image grid view.&#160; Only the gradient background will be shown. Setting the property back to true displays the thumbnail images. </p>  <p><strong>CrystalImageGridView</strong>: DrawImageTitle now uses CrystalImageItem's DisplayName property for the title text. </p>  <p><strong>CrystalComicShowController</strong>: unpack-wait dialog now positioned within the main form. </p>  <p><strong>CrystalComicShowControllerDemo</strong>: Enhanced to convert images in CBR/CBZ files to a size compatible for viewing on the Sony PSP.&#160; Fixed crashing bugs and sorting bugs from previous release. </p>  <p><strong><u>Bug Fixes:</u></strong></p>  <p><strong>CrystalFileCollector</strong>: Images that have the hidden file attribute are now skipped when CollectImages is executed. </p>  <p><strong>CrystalFileCollector, CrystalMemoryZipCollector, CrystalRarCollector</strong>:     <br />Initial sorting of list was incorrect.&#160; The sorting of the list must be done before the list/group item is added to the model. </p>  <p><strong>CrystalImageGridView</strong>, <strong>CrystalPictureShow</strong>, <strong>CrystalPictureShowController</strong>:     <br />Critical bug fixes where the controls tried to display or scroll to image item objects that were actually CrystalGroupItem objects.&#160; The above methods are used to avoid them when necessary. </p>  <p><strong>CrystalPictureShowController</strong>: Bug fix in DisplayImage.&#160; Operations on the main GUI thread (_imageForm) synchronized with an Invoke and code inside MethodInvoker. </p>  <p><strong>CrystalThumbnailer</strong>: Store method creates thumbnail folder if it does not exist. </p>  <p><strong>CrystalThumbnailer</strong>: GetThumbnailName method bug fix, forward slashes '/' converted to '\'.&#160; This was found in zip/rar files. </p>  <p><strong><u>Code Cleanup:</u></strong> </p>  <p><strong>CrystalImageItem</strong>: protected fields now change to private.     <br />To access these values in child classes, you have to use the Properties encapsulating these fields. </p>  <p><strong>CrystalTools</strong>: Class is now static (and therefore, sealed).&#160; </p>  <p>Redundant Exception handlers were removed in various classes.&#160; </p>  <p><u>NOTE</u>: Exception handling will be revised in a near-future release.     <br />Currently the toolkit is eating the exceptions and logging them; they obviously need to be thrown back to other objects in many cases.</p>  <p>Download: <a href="http://www.attilan.com/downloads/Crystal_Toolkit_082.zip">Crystal Image Toolkit 0.82</a>.&#160; Totally free, open-source, C# .NET Framework 2.0 for Windows Forms, works with both Visual Studio 2005 and 2008.</p>]]>
        
    </content>
</entry>

<entry>
    <title><![CDATA[Cory Doctorow&rsquo;s Little Brother and the Sony PSP as an E-Book Reader]]></title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/08/cory-doctorows-little-brother.php" />
    <id>tag:www.attilan.com,2008://3.633</id>

    <published>2008-08-18T08:11:00Z</published>
    <updated>2008-11-21T18:24:03Z</updated>

    <summary>Here&apos;s a roundabout story about I&apos;ve reinvigorated my Sony Playstation Portable, which would not have been possible without Cory Doctorow&apos;s excellent novel, Little Brother.</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Tools" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="corydoctorow" label="Cory Doctorow" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="littlebrother" label="Little Brother" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sonypsp" label="Sony PSP" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p></p>  <p></p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/CoryDoctorowsLittleBrothermakesmeturnthe_B0F1/0035_2.jpg"><img title="Cory Doctorow&#39;s Little Brother in Sony PSP Image viewer" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="276" alt="Cory Doctorow&#39;s Little Brother in Sony PSP Image viewer" src="http://www.attilan.com/WindowsLiveWriter/CoryDoctorowsLittleBrothermakesmeturnthe_B0F1/0035_thumb.jpg" width="484" border="0" /></a> </p>  <p>Here's a roundabout story about I've reinvigorated my Sony Playstation Portable, which would not have been possible without Cory Doctorow's excellent novel, <a href="http://craphound.com/littlebrother" target="_blank">Little Brother</a>.</p>  <p>I've been flirting with the Amazon Kindle for months ever since it went on sale.&#160; It's a cool device for a book lover.&#160; Imagine being able to carry around tons of books everywhere you go.&#160; Being able to download a book after reading a review in the Sunday newspaper.&#160; It's fantastic...except for the limitations.&#160; DRM on the books that you download isn't very cool.&#160; I think what really galls me is that Amazon charges for downloading blogs (via RSS) when you can easily get them for free online.&#160; Charging to email/convert documents to the Kindle device is another thing I cannot understand.&#160; Combine all of these things with the high price of the Kindle and I just cannot make that purchase.</p>  <p>Which made me turn to my Sony Playstation Portable.&#160; I've let this device languish for the past two years after I stopped commuting to San Francisco on BART.&#160; In the back of my mind, I've had this idea that the PSP, with it's brilliant screen display and brightness controls, could be a great e-book reader.&#160; After visiting Cory Doctorow's <a href="http://craphound.com/littlebrother/download/" target="_blank">Little Brother download page</a>, where he provides the novel in a variety of formats (under Creative Commons license), I finally decided to give it a try and see if one of those would work on the PSP.</p>  <p>The result is that none of them worked that well.&#160; It's amazing that after being first sold in 2005 in North America, the Sony PSP still does not have an Adobe PDF Reader.&#160; I found one that used to work, but apparently not on firmware 4.05.&#160; I suppose I could have gotten that to work if I flashed the PSP with a hacked set of firmware, but I want to keep up with the official builds from Sony, as I have a Playstation 3 and want to use my PSP in conjunction with that.&#160; </p>  <p>Next, I tried the HTML version of Little Brother, which I copied over to the PSP/COMMON folder and pointed the PSP's browser at that location.&#160; The HTML version looked superb, the text was very readable, and you can increase/decrease the text size very easily.</p>  <p>However, there were some problems with reading books in HTML format on the PSP.&#160; Paging/scrolling to see the next page is a pain, when you must use the arrow keys on the left hand side of the device.&#160; If the entire book is in one HTML file, you cannot jump between chapters that easily.&#160; When I stopped near Chapter 3, then the next time I started the PSP, I spent a long time scrolling down (using square button + down) to get to that section.&#160; I read that some Sony ebook fans will break up novels into several HTML chunks and link the whole thing together in an index file.&#160; Too much work for me!</p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/CoryDoctorowsLittleBrothermakesmeturnthe_B0F1/psp_ebook_creator_2.png"><img title="PSP EBook Creator" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="404" alt="PSP EBook Creator" src="http://www.attilan.com/WindowsLiveWriter/CoryDoctorowsLittleBrothermakesmeturnthe_B0F1/psp_ebook_creator_thumb.png" width="404" border="0" /></a> </p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p>A friend of mine suggested converting the document into a series of JPG files and using the Sony PSP Photo/Image viewer.&#160; I was really dubious about this until I found the <a href="http://www.download.com/Psp-Ebook-Creator/3000-2125_4-10499628.html" target="_blank">PSP EBook Creator on download.com</a>.&#160; What the heck, I decided to give it a shot.&#160; The PSP E-book Creator takes a text file file as the input/source, parses it and creates a series of JPG images.&#160; It gives you a number of options for formatting the text: you can choose the font that you want, the font color, the background color, etc.&#160; It may take a while to determine the best font to read on the PSP screen, I've found that either Arial or Verdana works best for me.</p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p>The e-book creator parsed and split the Little Brother source text into 897 jpg files, which I copied over to the PSP's PHOTO folder, under a subfolder called LB.&#160; When I turn on the PSP, I simply navigated to the Photo slot, select Memory Stick, select the LB folder, select page 1 and pressed X.&#160; Voila, the first page appears and it's easily readable.&#160; To go to the next page, you just press the right shoulder button on top of the PSP.&#160; The PSP can easily be held in one hand with a finger resting on the next button to advance pages.&#160; The left shoulder button allows you to go to the previous page.</p>  <p>Several things are great about this.&#160; Little Brother took up about 40 mb on my Sony Memory stick, which is pretty small.&#160; Having the book split up into X number of jpgs allows you to quickly find the last page you were on: just press the down arrow to scroll down quickly to page 222 or whatever.&#160; The Sony PSP has a brightness control on the front that allows you to see the screen during the daytime or at night.&#160; This is really convenient if you're reading in bed and don't want to disturb your partner with a bright screen--the lowest brightness level works perfectly in total darkness.&#160; You have no idea how long I've searched for a solution to this problem!&#160; </p>  <p>What are the disadvantages of this method?&#160; There are two big ones.&#160; You can't customize the text size dynamically, and the glassy Sony PSP screen is not readable outdoors in the sunlight, due to the glare bouncing off the screen.&#160; I usually read indoors, so this is not a problem for me.</p>  <p>Unlike the Kindle, where finding/downloading books is a breeze, finding content to download and convert is a challenge, as not every author is as generous as Cory Doctorow.&#160; But if you're used to downloading other media, you can find content to use with the PSP E-Book Creator, although usually the content will need to be converted to text.&#160; You can look for books that are in RTF or HTML format and convert to text using a number of programs (Internet Explorer, Firefox, Microsoft Word, etc).&#160; Books in PDF file format can also be converted to text.&#160; You can also find books in the Microsoft Reader format (.LIT files), and use the free <a href="http://www.processtext.com/abclit.html" target="_blank">ABC Amber LIT Converter program</a> to convert them.</p>  <p>I've got about a dozen books, many of them recent books that I purchased in hardback (plus all of Doctorow's other novels), on my Sony PSP.&#160; I bought a SanDisk 4 GB memory stick for about $40 on Amazon to hold this content, along with 12 episodes of LOST and a number of comic books that I want to read on my next vacation.&#160; With all this content available, playing games on the PSP seems like a bonus feature.</p>  <p>Little Brother is a very engaging book, I devoured it in a couple of days after getting on my PSP.&#160; Little Brother is a young adult novel (although just as good for adults) about a high school kid named Marcus Yallow (aka w1n5t0n) in San Francisco. San Francisco is attacked by terrorists and the Department of Homeland Security swoops in and starts heavily monitoring all citizens. Marcus fights back against the DHS by hacking his Xbox with an operating system called &quot;Paranoid Linux&quot; and inspiring a group of young techno-geeks to help him out.&#160; I highly recommend it.</p>  <p>Link: <a href="http://www.download.com/Psp-Ebook-Creator/3000-2125_4-10499628.html" target="_blank">PSP E-Book Creator</a></p>  <p>Link: <a href="http://www.processtext.com/abclit.html" target="_blank">ABC Amber Lit Converter</a></p>  <p>Link: <a href="http://craphound.com" target="_blank">Cory Doctorow's Craphound</a></p>  <p>Link: <a href="http://craphound.com/littlebrother/" target="_blank">Little Brother site</a></p>  <p>Download: <a href="http://www.attilan.com/downloads/little_brother_psp.zip" target="_blank">Little Brother for Sony PSP (Image files, zipped).</a></p>]]>
        
    </content>
</entry>

<entry>
    <title>Crystal Image Toolkit 0.81: Header Groups for Image Thumbnail Grid View</title>
    <link rel="alternate" type="text/html" href="http://www.attilan.com/2008/07/crystal-image-toolkit-081-head.php" />
    <id>tag:www.attilan.com,2008://3.632</id>

    <published>2008-07-31T06:02:00Z</published>
    <updated>2008-07-31T06:02:00Z</updated>

    <summary>Crystal Image Toolkit 0.81 is ready to download. New Feature: Header group items are now part of CrystalCollector, CrystalImageGridModel, and CrystalImageGridView.&#160; You can now assign a group of thumbnail images to a collapsible header.&#160; To illustrate this, here’s a screenshot...</summary>
    <author>
        <name>Richard Guion</name>
        
    </author>
    
        <category term="Crystal Toolkit" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Downloads" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.attilan.com/">
        <![CDATA[<p><strong>Crystal Image Toolkit 0.81</strong> is ready to <a href="http://www.attilan.com/downloads/Crystal_Toolkit_081.zip" target="_blank">download</a>. </p>  <p><strong>New Feature</strong>: Header group items are now part of <strong>CrystalCollector, CrystalImageGridModel, and CrystalImageGridView</strong>.&#160; You can now assign a group of thumbnail images to a collapsible header.&#160; To illustrate this, here’s a screenshot from the demo application “HeaderGroupItemDemo” which is included in the project:</p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/Cry.81HeaderGroupsforImageThumbnailGridV_143D0/HeaderGroupItem1_2.png"><img title="HeaderGroupItem1" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="592" alt="HeaderGroupItem1" src="http://www.attilan.com/WindowsLiveWriter/Cry.81HeaderGroupsforImageThumbnailGridV_143D0/HeaderGroupItem1_thumb.png" width="671" border="0" /></a> </p>  <p>There are four header groups visible that you can see here (FF, Hulk, Iron Man, Spider-Man).&#160; Each contains a set of thumbnails.&#160; The arrow icon indicates the expanded state; you can replace this icon in the framework as I am just using a free icon here.&#160; Likewise you can replace the folder icon to represent something unique about this group of images if you wish.&#160; But what’s important to note here is that the header group can be collapsed/expanded by clicking on it:</p>  <p><a href="http://www.attilan.com/WindowsLiveWriter/Cry.81HeaderGroupsforImageThumbnailGridV_143D0/HeaderGroupItemCollapsed_2.png"><img title="HeaderGroupItemCollapsed" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="455" alt="HeaderGroupItemCollapsed" src="http://www.attilan.com/WindowsLiveWriter/Cry.81HeaderGroupsforImageThumbnailGridV_143D0/HeaderGroupItemCollapsed_thumb.png" width="671" border="0" /></a> </p>  <p>Here I’ve collapsed two of the header items and left the other ones open.&#160; You can see I have CrystalImageItem objects selected in each of the header groups.</p>  <p>In the C# code, Header groups translates to a CrystalGroupItem object containing a List of CrystalImageItem objects.&#160; Each object now has a Parent property so it knows the group that it belongs to.&#160; The biggest change in the collector is that now every GridModel has at least one root header. In the default mode, for backward compatibility, the header item is not displayed (ShowHeaders is set to false in CrystalImageGridView). This may cause problems in older applications that use CrystalImageGridView and try to navigate to item 0 in the GridModel.&#160; You will need to do a test, such as: &quot;if (theImage is CrystalGroupItem)&quot;.&#160; See InitInitialImageImp in CrystalPictureShowController.cs for how to deal with this situation.</p>  <p>CrystalCollector now has an additional abstract method that requires you to CollectImages on a CrystalGroupItem object.&#160; CrystalFileCollector implements this method and creates a default root header for simplicity.&#160; But if you want to explicitly create CrystalGroupItem objects and add them to the collector, you do it like this:</p>  <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, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">   <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">     <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> CrystalGroupItem groupItem = <span style="color: #0000ff">new</span> CrystalGroupItem();</pre>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> groupItem.ImageName = <span style="color: #006080">&quot;Fantastic Four&quot;</span>;</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> groupItem.ImageLocation = <span style="color: #006080">&quot;..\\..\\SampleImages\\Fantastic Four&quot;</span>;</pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> <span style="color: #008000">// Optional: set a unique image icon for this group header item in the image grid.</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span> <span style="color: #008000">//groupItem.FullImage = my Image icon;</span></pre></p>

<p>    <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, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span> _theCollector.CollectImages(groupItem);</pre><br />
  </div><br />
</div></p>

<p>This is a bit of an early release of the header group feature.&#160; In the future, I will add additional style bits for the header text font, add a border state around the header item, perhaps add mouse over events for it.</p>

<p>There are several bug fixes to the toolkit, which is why I wanted to release it now, even though this feature is a bit early.&#160; To see all the bug fixes, please read the release notes in the zip file.</p>

<p>Download: <a href="http://www.attilan.com/downloads/Crystal_Toolkit_081.zip" target="_blank">Crystal Image Toolkit 0.81</a>.&#160; Totally free, open-source, C# .NET Framework 2.0 for Windows Forms.</p>]]>
        
    </content>
</entry>

</feed>
