<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
   <channel>
      <title>Attilan Software: C#, .NET, Image Tools for Forms</title>
      <link>http://www.attilan.com/</link>
      <description>Constructing software tools in C#, .NET, and Windows Forms.</description>
      <language>en</language>
      <copyright>Copyright 2008</copyright>
      <lastBuildDate>Tue, 18 Nov 2008 11:00:15 -0800</lastBuildDate>
      <generator>http://www.sixapart.com/movabletype/?v=4.1</generator>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

      
      <item>
         <title>Interview Coding: atoi, itoa in C</title>
         <description><![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>]]></description>
         <link>http://www.attilan.com/2008/11/interview-coding-atoi-itoa-in.php</link>
         <guid>http://www.attilan.com/2008/11/interview-coding-atoi-itoa-in.php</guid>
         <category>Interview Coding</category>
         <pubDate>Tue, 18 Nov 2008 11:00:15 -0800</pubDate>
      </item>
      
      <item>
         <title>Retaining Software Engineers: Why People Leave For Startups and Why They Should Stay</title>
         <description><![CDATA[<p>I've been extremely privileged to work for two industry titans during my career: Microsoft (1990-1993) and Oracle (1995-1997).&#160; I'm grateful for the experience and the knowledge that I acquired at each one.&#160; In both cases, I left each company and left behind some opportunities that I will miss forever.&#160; </p>  <p>While Microsoft, in my opinion, treated software engineers better than any company on Earth, I don't regret leaving when I did.&#160; If I hadn't moved away from Seattle, I wouldn't have met my wife in California and I've always said she's worth a billion dollars to me.&#160; Oracle, however, was located a few miles away from my wife's condo in Burlingame.&#160; Leaving Oracle to work at various failed startups was a bad decision in hindsight; I wish I had deeply considered what I was tossing away when I left.</p>  <p>Managers at places like Microsoft, Oracle, Intel, IBM, and your own company dread the day a valuable engineer walks into their office and tenders their resignation.&#160; In many cases, those employees are leaving to go to startup or smaller company that gives them something the larger company cannot.&#160; A herd mentality can quickly develop and suddenly you are facing a brain-drain of epic proportions.&#160; </p>  <p>Here's a short list of reasons why engineers will want to resign.&#160; I know them all because I gave them, perhaps foolishly, at various points in my career:</p>  <p><strong>1.&#160; Company X gives the engineer a larger base salary than the current company does.</strong></p>  <p>When I worked for Microsoft and Oracle in the 1990s, the base salary was lower than many other companies in the same industry.&#160; Both companies could make up for it in terms of stock options.&#160; In the present day, that doesn't work for them as well as it does for Google (although their stock has been deflating along with everything else).&#160; I heard recent stories that Oracle engineers were dissatisfied with their pay, leaving for a higher salary, then returning a few years later, retaining their new base salary.&#160; That's because it's difficult for managers to justify raises over 3-5% per year.&#160; Nevertheless, Oracle HR dreads seeing former employees return, because it costs more and makes the existing engineers envious.</p>  <p><strong>Solution:</strong>&#160; If the discrepancy in the salary isn't too large, point out the other benefits your company offers.&#160; Both Microsoft and Oracle have superb health benefits and nice little perks like health club memberships.&#160; Health benefits are increasingly more important as we get older.&#160; Point out that smaller companies often cut benefits when times are tough.&#160; If the salary difference is really large and you can't bump it up, try to compensate with a bonus.&#160; </p>  <p><strong>2.&#160; Company X gives the engineer a greater direct impact on the final product.</strong></p>  <p>Larger companies are notoriously top-heavy, bureaucratic, and slow to react to change.&#160; When the development process becomes so bureaucratized that no voice of common sense can prevail, engineers start to feel suppressed.&#160; I think the most effective description of this is <a href="http://moishelettvin.blogspot.com/2006/11/windows-shutdown-crapfest.html">Moishe Lettvin's description of working on the Vista shutdown menu at Microsoft</a>.&#160; An engineer who is unhappy working under those conditions will look forward to working at a company where they can check in code that appears in the product very quickly.</p>  <p><strong>Solution:</strong> This is a tough one to fight against.&#160; I think it is one of the top reasons why people get frustrated and leave.</p>  <p>The best solution I can think of is to tell the engineer to stick around and eventually things will change.&#160; The Vista example is a good one.&#160; Steven Sinofsky became the senior vice president over the Windows team in 2007, after Vista was released.&#160; Sinofsky is extremely intelligent, an able prognosticator of where technology is leading, but he's also retained what I call "the common sense factor", the ability to look at when things are obviously not working and figure out how to turn that around.&#160; While I have no inside knowledge of what it is like to work on the Windows 7 team, from what I've seen at the PDC and read about the build discipline that has been instituted, it appears to have changed.</p>  <p>It's happened to me at many other companies as well.&#160; There were many times when a manager or VP seemed to be driving our development team into a concrete wall.&#160; Eventually, these individuals moved elsewhere and better management replaced them.&#160; All of sudden, it seemed like we were working for a different company.</p>  <p>Based on personal experience, this is the best thing for an engineer at a company with a steady future.&#160; It's a tough sell with people who want immediate gratification.&#160; When an engineer leaves, they get the gratification of making an impact, but at the same time, they lose what they attained (seniority, vacation, etc) at the larger organization.&#160; If they had stayed longer, they might have had more impact as a result of the inevitable reorg.</p> ]]></description>
         <link>http://www.attilan.com/2008/11/retaining-software-engineers-p.php</link>
         <guid>http://www.attilan.com/2008/11/retaining-software-engineers-p.php</guid>
         <category>Software Industry</category>
         <pubDate>Sun, 16 Nov 2008 18:10:08 -0800</pubDate>
      </item>
      
      <item>
         <title>C# Coding Shortcuts: IsNullorEmpty, Path object, BackgroundWorker, MethodInvoker.</title>
         <description><![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>]]></description>
         <link>http://www.attilan.com/2008/11/c-coding-shortcuts-isnulloremp.php</link>
         <guid>http://www.attilan.com/2008/11/c-coding-shortcuts-isnulloremp.php</guid>
         <category>.NET Framework</category>
         <pubDate>Sun, 16 Nov 2008 11:21:27 -0800</pubDate>
      </item>
      
      <item>
         <title>Converting from uint to a Hexadecimal string value in C#</title>
         <description><![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>]]></description>
         <link>http://www.attilan.com/2008/11/converting-from-uint-to-a-hexa.php</link>
         <guid>http://www.attilan.com/2008/11/converting-from-uint-to-a-hexa.php</guid>
         <category>.NET Framework</category>
         <pubDate>Fri, 14 Nov 2008 22:28:29 -0800</pubDate>
      </item>
      
      <item>
         <title>Interview Coding: Reversing a Singly Linked List in C</title>
         <description><![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><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; You could create a C++ solution to this problem, using templates, but that could take much longer.</p>

<p>Let's create a linked list, four nodes, with the values ABCD.&#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;
    node* node4 = <span class="kwrd">new</span> node(<span class="str">'d'</span>);
    node3-&gt;next = node4;
    node4-&gt;next = NULL;</pre>
<style type="text/css">

<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; That's perfectly valid, yet when I see this type of problem, I think about using <a href="http://en.wikipedia.org/wiki/Recursion_(computer_science)" target="_blank">recursion</a>, which is how I tried to address it:</p>

<pre class="csharpcode"><span class="rem">// Reverse a singly linked list.</span>
<span class="rem">// Take the head of the list and return the new head of</span>
<span class="rem">// the reversed list.</span>
node* revlist(node* head)
{
    node* ptr = head;
    node* newHead = NULL;
    <span class="rem">// if the list is empty, return NULL, or</span>
    <span class="rem">// if the list has only 1 item, return that item.</span>
    <span class="kwrd">if</span> ((ptr == NULL) ||  (ptr-&gt;next == NULL))
    {
        <span class="kwrd">return</span> ptr;
    }
    <span class="rem">// Linked list has 2 or more items.</span>
    <span class="rem">// Are we at the end of the list?</span>
    <span class="kwrd">if</span> (ptr-&gt;next-&gt;next != NULL)
    {
        <span class="rem">// no, keep traversing the list until the end.</span>
        newHead = revlist(ptr-&gt;next);
    }
    <span class="kwrd">else</span>
    {
        <span class="rem">// the new head of the list is the last item.</span>
        newHead = ptr-&gt;next;
    }
    <span class="rem">// next item points to the previous item.</span>
    ptr-&gt;next-&gt;next = ptr;
    <span class="rem">// previous item is now the tail, it points to NULL.</span>
    ptr-&gt;next = NULL;
    <span class="rem">// return the head of the reverse linked list.</span>
    <span class="kwrd">return</span> newHead;
 }</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>This is pretty straightforward.&#160; The function starts at the head of the singly linked list and returns the new head of the reversed linked list.&#160; It does not leave the original list untouched.&#160; For that, we would need to make a copy, but we're trying to keep this solution simple. </p>

<p>Let's examine this section by section.&#160; The first if-statement is vital:</p>

<pre class="csharpcode">    <span class="rem">// if the list is empty, return NULL, or</span>
    <span class="rem">// if the list has only 1 item, return that item.</span>
    <span class="kwrd">if</span> ((ptr == NULL) ||  (ptr-&gt;next == NULL))
    {
        <span class="kwrd">return</span> ptr;
    }</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>If the linked list has 0 items, the head ptr is NULL.&#160; We must detect this and return NULL.&#160; Alternatively, if this list has only 1 node, there's nothing to reverse.&#160; We must detect this and return back that node to the caller.</p>

<pre class="csharpcode">    <span class="rem">// Linked list has 2 or more items.</span>
    <span class="rem">// Are we at the end of the list?</span>
    <span class="kwrd">if</span> (ptr-&gt;next-&gt;next != NULL)
    {
        <span class="rem">// no, keep traversing the list until the end.</span>
        newHead = revlist(ptr-&gt;next);
    }</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>This if-statement uses recursion to traverse the linked list all the way to the last two nodes.&#160; If the list is ABCD, the first time this function is called, it's looking at B-&gt;next and detecting if that is NULL.&#160; Since it is not, it calls revlist again, with B as the head of the list.&#160; It will be called another time, pointing to C as the head of the list.</p>

<pre class="csharpcode">    <span class="kwrd">else</span>
    {
        <span class="rem">// the new head of the list is the last item.</span>
        newHead = ptr-&gt;next;
    }</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>When C is the head, the else clause will be executed.&#160; At this point, we are at the next to last node in the linked list.&#160; The new head of the reversed linked list will be the last node in the original list.&#160; C-&gt;next points to D.&#160; The D node will be the new head.</p>

<pre class="csharpcode">    <span class="rem">// next item points to the previous item.</span>
    ptr-&gt;next-&gt;next = ptr;
    <span class="rem">// previous item is now the tail, it points to NULL.</span>
    ptr-&gt;next = NULL;</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 that we've found the head of the reverse list, it's time to start swapping nodes.&#160; The first time we execute this code ptr is really the C node.&#160; C points to D, the tail of the list.&#160; Now we swap them.&#160; D points to the previous node, C.&#160; C points to NULL, because it is now the tail.&#160; As the recursive stack unwinds, the rest of the list is reversed:</p>

<p>ptr == C, C -&gt; D, swap, reversed list is D -&gt; C</p>

<p>ptr == B, B -&gt; C, swap, reversed list is D -&gt; C -&gt; B</p>

<p>ptr == A, A -&gt; B, swap, reversed list is D -&gt; C -&gt; B -&gt; A</p>

<p>Finally, we need to return the new head of the reversed linked list:</p>

<pre class="csharpcode">    <span class="rem">// return the head of the reverse linked list.</span>
    <span class="kwrd">return</span> newHead;</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 seems obvious, but a mistake could be made in the previous if-statement if you don't set newhead in the recursive call.&#160; Once the last node in the old linked list is found, it is returned through the recursive stack.</p>

<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>]]></description>
         <link>http://www.attilan.com/2008/11/interview-coding-reversing-a-s.php</link>
         <guid>http://www.attilan.com/2008/11/interview-coding-reversing-a-s.php</guid>
         <category>Interview Coding</category>
         <pubDate>Fri, 14 Nov 2008 10:47:22 -0800</pubDate>
      </item>
      
      <item>
         <title>Numbing the Pain of Whiteboard Coding During Interviews</title>
         <description><![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>]]></description>
         <link>http://www.attilan.com/2008/11/numbing-the-pain-of-whiteboard.php</link>
         <guid>http://www.attilan.com/2008/11/numbing-the-pain-of-whiteboard.php</guid>
         <category>Interview Coding</category>
         <pubDate>Wed, 12 Nov 2008 12:50:18 -0800</pubDate>
      </item>
      
      <item>
         <title>Interview Coding: Fibonacci function</title>
         <description><![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>]]></description>
         <link>http://www.attilan.com/2008/11/interview-coding-fibonacci-fun.php</link>
         <guid>http://www.attilan.com/2008/11/interview-coding-fibonacci-fun.php</guid>
         <category>Interview Coding</category>
         <pubDate>Wed, 12 Nov 2008 12:26:27 -0800</pubDate>
      </item>
      
      <item>
         <title>Crystal Image Toolkit 0.82 released: Bug fixes and minor enhancements</title>
         <description><![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>]]></description>
         <link>http://www.attilan.com/2008/10/crystal-image-toolkit-082-rele.php</link>
         <guid>http://www.attilan.com/2008/10/crystal-image-toolkit-082-rele.php</guid>
         <category>Crystal Toolkit</category>
         <pubDate>Sat, 18 Oct 2008 23:42:49 -0800</pubDate>
      </item>
      
      <item>
         <title><![CDATA[Cory Doctorow&rsquo;s Little Brother and the Sony PSP as an E-Book Reader]]></title>
         <description><![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>]]></description>
         <link>http://www.attilan.com/2008/08/cory-doctorows-little-brother.php</link>
         <guid>http://www.attilan.com/2008/08/cory-doctorows-little-brother.php</guid>
         <category></category>
         <pubDate>Mon, 18 Aug 2008 01:11:00 -0800</pubDate>
      </item>
      
      <item>
         <title>Crystal Image Toolkit 0.81: Header Groups for Image Thumbnail Grid View</title>
         <description><![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>]]></description>
         <link>http://www.attilan.com/2008/07/crystal-image-toolkit-081-head.php</link>
         <guid>http://www.attilan.com/2008/07/crystal-image-toolkit-081-head.php</guid>
         <category>Crystal Toolkit</category>
         <pubDate>Wed, 30 Jul 2008 23:02:00 -0800</pubDate>
      </item>
      
      <item>
         <title>Crystal Image Toolkit 0.80: Thumbnail scaling, Image tracking in C# .Net</title>
         <description><![CDATA[<p>Crystal Image Toolkit 0.80 is ready to <a href="http://www.attilan.com/downloads/Crystal_Toolkit_080.zip" target="_blank">download</a>.&#160; </p>  <p>New Features:</p>  <ul>   <li>CrystalImageGridView now has ZoomFactor: allows scaling of thumbnail images!     <br />See ZoomImageGrid demo and Crystal Picture Show Controller demo. </li>    <li>CrystalPictureTracker: Pan Window that works with CrystalPictureShow.     <br />See Crystal Picture Show Controller demo. </li>    <li>CrystalPictureShow: Hand cursors that allow the user to drag zoomed images around. </li>    <li>CrystalImageGridView now has a new rounded rect border style.&#160; Check out the groovy red borders in the Picture Show Controller demo.</li>    <li>Crystal Toolkit now integrates <a href="http://logging.apache.org/log4net/index.html" target="_blank">log4net</a>.&#160; See CrystalLogger object.      <br />You can get even more debug logging by declaring CRYSTAL_DEBUG in project properties/build.</li> </ul>  <p>And now it's demo time, with Marvel comics pictures, of course:</p>  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="470" alt="CrystalImageGridView using ZoomFactor to scale thumbnails" src="http://www.attilan.com/WindowsLiveWriter/CrystalImageToolkit0.80Thumbnailscal.Net_1B5F/CrystalPicDemo_thumb_zooming_3.png" width="700" border="0" /></p>  <p><strong>CrystalImageGridView: ZoomFactor</strong> applied to zoom to a larger thumbnail image.&#160; <a href="http://www.attilan.com/2008/05/scaling-thumbnail-images-with.php">See my earlier article</a> that explains how to set this up.&#160; Changes were made to CrystalPictureShowController to add a second trackbar object to control thumbnail zooming.&#160; </p>  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="528" alt="CrystalPictureTracker working with CrystalPictureBox" src="http://www.attilan.com/WindowsLiveWriter/CrystalImageToolkit0.80Thumbnailscal.Net_1B5F/CrystalPicDemo_tracker_window_3.png" width="700" border="0" /> </p>  <p><strong>CrystalPictureTracker: Panning</strong> (controlling CrystalPictureBox) in separate window.&#160; Tracker window appears when image is larger than client area.&#160; You can close it, make it appear again by clicking on the Pan Window button.</p>  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="525" alt="Red rounded borders" src="http://www.attilan.com/WindowsLiveWriter/CrystalImageToolkit0.80Thumbnailscal.Net_1B5F/CrystalPicDemo_roundrect_3.png" width="700" border="0" /> </p>  <p><strong>CrystalImageGridView: Rounded borders on selected images.</strong>&#160; There is now a property called <strong>BorderState</strong> that allows you to switch between these rounded borders and the old square frame.&#160; Also, notice that in the split view mode, the CrystalPictureShowController hides the thumbnail trackbar and toolstrip objects auto-magically.&#160;&#160; Thumbnail sizes in the split mode are fixed, whereas in the vertical orientation (with a sheet of thumbnails) they can be scaled.</p>  <p>This release comes in a ZIP file. Simply unzip the contents to your hard drive, navigate to the root Attilan folder, and double click on <strong>CrystalDemo.sln</strong>. This solution file contains the Crystal Toolkit plus demo programs. Just build the solution (which compiles the CrystalToolkit library first) and run the demo programs to see how they work. You can run the demo programs without building the source by clicking on &quot;<strong>StartDemo.bat</strong>&quot; in the root Attilan folder or <strong>CrystalDemoLauncher.exe</strong> in Attilan\bin.</p>  <p>Download: <a href="http://www.attilan.com/downloads/Crystal_Toolkit_080.zip" target="_blank">Crystal Image Toolkit 0.80</a>.&#160; Totally free, open-source, C# .NET Framework 2.0 for Windows Forms.&#160; </p>]]></description>
         <link>http://www.attilan.com/2008/05/crystal-image-toolkit-080-thum.php</link>
         <guid>http://www.attilan.com/2008/05/crystal-image-toolkit-080-thum.php</guid>
         <category>Crystal Toolkit</category>
         <pubDate>Tue, 27 May 2008 20:07:03 -0800</pubDate>
      </item>
      
      <item>
         <title>Scaling Thumbnail Images with C# WinForms, CrystalImageGridView</title>
         <description><![CDATA[<p>I haven't posted any articles here for quite a while.&#160; You might think I've given up on the Crystal Toolkit, but not yet!&#160; I've been making various improvements, bug fixes, and enhancements.&#160; It's slowly getting better.&#160; Probably by the time I am done, Windows Forms will be dead!</p>  <p>Here's a big feature, coming very soon in <a href="http://www.attilan.com/2008/05/crystal-image-toolkit-080-thum.php">Crystal Toolkit 0.80</a>, that I've wanted for my own image viewing programs: zooming the thumbnail images that are contained within CrystalImageGridView.&#160; Previously I was only able to allow users to set the CellSize property and that was it.&#160; If you had a thumbnail image that was 300 x 300, you were stuck with that until you changed that property and had the internal grid recalculate itself.&#160; It might have worked, but the images would all have to be re-thumbnailed at that new size, and a lot of time would be wasted.</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>

    <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">/// Sets up the Matrix object used for displaying the image.</span></pre>

    <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>

    <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">/// &lt;param name=&quot;gfx&quot;&gt;Graphics object used for drawing.&lt;/param&gt;</span></pre>

    <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">/// &lt;param name=&quot;zoomScale&quot;&gt;Scale used for matrix.&lt;/param&gt;</span></pre>

    <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: #0000ff">protected</span> <span style="color: #0000ff">virtual</span> <span style="color: #0000ff">void</span> SetupMainImageMatrix(Graphics gfx, <span style="color: #0000ff">float</span> zoomScale)</pre>

    <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> {</pre>

    <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>     gfx.ResetTransform();</pre>

    <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>

    <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">// Set up the transformation to handle zooming and panning.</span></pre>

    <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>     Matrix mx = <span style="color: #0000ff">new</span> Matrix();</pre>

    <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>&#160; </pre>

    <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">// Account for the scroll position.</span></pre>

    <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>     mx.Translate(AutoScrollPosition.X, AutoScrollPosition.Y);</pre>

    <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>&#160; </pre>

    <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>     <span style="color: #008000">// Account for the zoom factor.</span></pre>

    <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>     mx.Scale(zoomScale, zoomScale);</pre>

    <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>

    <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: #008000">// Set the transform into the global transform for the specified Graphics context.</span></pre>

    <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>     gfx.Transform = mx;</pre>

    <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>&#160; </pre>

    <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>     <span style="color: #008000">// Set the interpolation mode.</span></pre>

    <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>     gfx.InterpolationMode = _interpolationMode;</pre>

    <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> }</pre>
  </div>
</div>

<p>To make thumbnail scaling work in the new release, I've taken some code and patterns found in <strong>CrystalPictureBox</strong>.&#160; In that class, I used a Matrix object and set the scale according to a property I called <strong>ZoomFactor</strong>.&#160; This enabled me to present an image in <strong>CrystalPictureBox</strong> at any scale I desired, like from 30% of full size to 300% of full size.</p>

<p><strong>CrystalImageGridView</strong> now has a property called <strong>ZoomFactor</strong>.&#160; Using this, the entire grid can be displayed at a percentage of the full sized grid.&#160; To implement an image grid that goes from small images to medium images to large images, you would just set the <strong>ZoomFactor</strong> in the image grid, and the object takes care of the rest.</p>

<p>How it works: </p>

<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="374" alt="Setting up CrystalImageGridView for large thumbnails" src="http://www.attilan.com/WindowsLiveWriter/ZoomingThumbnailImageswithCCrystalImageG_CEC5/ZoomFormSetting_3.png" width="604" border="0" /> </p>

<p>First, setup a Form and drop the <strong>CrystalImageGridView</strong> onto the form.&#160; Set the <strong>CellSize</strong> property to the largest possible size that you wish to display.&#160; In this case, I chose a cell size of 375 x 375.&#160; If you set it up this way, the thumbnailer object (internal to the grid) will make thumbnail images at this size, providing users with a crisp view.&#160; It's easier to downscale a larger image than it is to upscale a smaller image.&#160; Now, an alternative way to do this could have been a different pattern--where we send out a signal that we are changing the size and thumbnail the viewable images on the spot.&#160; Windows Explorer and several other programs do this.&#160; Perhaps in the future I will provide an alternative method like this.&#160; The advantage of this method is that the image scaling is pretty fast.&#160; The disadvantage is that the thumbnailed image requires more disk space at the largest possible size.</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">float</span>[] zoomFactor = { .30f, .45f, .60f, .75f, .90f, 1.0f };</pre>
  </div>
</div>

<p>The <strong>ZoomFactor</strong> property is set by a trackbar in my little example program (which will be in Crystal Toolkit 0.80).&#160; The zoom factors are predefined in array.&#160; At the lower end of the scale (represented by setting the trackbar all the way to the left) we have 30% of the full size 375x375, which is 125x125.&#160; At the upper end, we have 100% of the thumbnail size.&#160; There is a trackbar on the form with Minimum set to 0 and Maximum set to 5, to match the settings in the array.</p>

<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="516" alt="CrystalImageGridView with ZoomFactor at 30%" src="http://www.attilan.com/WindowsLiveWriter/ZoomingThumbnailImageswithCCrystalImageG_CEC5/ZoomDemo_125_6.png" width="700" border="0" />&#160; </p>

<p>When the program is launched, the default ZoomFactor is set to 0.30 (125x125).&#160; I've got about 24 thumbnails displaying here.&#160; Notice how the text for the image is still visible at this 30% setting, this was actually the trickiest part of the whole deal (and there may be bugs left to find in that regard).&#160; OK, I've got the Hulk selected in the middle of the screen, keep an eye on him.</p>

<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="513" alt="CrystalImageGridView with ZoomFactor at 50%" src="http://www.attilan.com/WindowsLiveWriter/ZoomingThumbnailImageswithCCrystalImageG_CEC5/ZoomDemo_50_3.png" width="700" border="0" /> </p>

<p>Here the ZoomFactor is set close to 50%.&#160; The grid has repositioned the images as the ZoomFactor increased in size.&#160; The Hulk remains selected, in the center of the grid so that the user can view his beautiful face.&#160; Is that a booger in his hose?&#160; Let's zoom it up further.</p>

<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="516" alt="CrystalImageGridView with ZoomFactor at 100%" src="http://www.attilan.com/WindowsLiveWriter/ZoomingThumbnailImageswithCCrystalImageG_CEC5/ZoomDemo_100_3.png" width="700" border="0" /> </p>

<p>Finally, here's what the CrystalImageGridView looks like with the ZoomFactor at 100% (375x375).&#160; We've got two images side by side, the Hulk is still selected and viewable.&#160; And it's not a booger, it's this wild Marvel character called Ant-Man, making a quick exit from the Hulk's gamma irradiated body.</p>

<p>With good luck, I should be posting Crystal Toolkit 0.80 with this feature this Memorial Day.&#160; Nuff said.</p>]]></description>
         <link>http://www.attilan.com/2008/05/scaling-thumbnail-images-with.php</link>
         <guid>http://www.attilan.com/2008/05/scaling-thumbnail-images-with.php</guid>
         <category>Crystal Toolkit</category>
         <pubDate>Fri, 23 May 2008 15:10:52 -0800</pubDate>
      </item>
      
      <item>
         <title>SVN, Windows Vista, and mysterious closed connections</title>
         <description><![CDATA[<p>Ever had one of those days when you spent fighting with your operating system when you should have been getting real work done?  I just had one of them.  My computer at home is much faster and better equipped to do development work than my work laptop.  We use SVN for source code control.  For SVN client access, we use <a href="http://www.syntevo.com/smartsvn/index.html">SmartSVN from SyntEvo</a>.  After setting up our repository URL in the SmartSVN, I was able to browse our repository folder structure, and begin to check out a project.  But after retrieving a few files, it would crap out with errors like "<strong>connection closed</strong>" or "<strong>svn: null</strong>".</p>

<p>When things like this go wrong, most people would just give up or go back to the laptop.  But this is the sort of the thing that makes me crazy until I find out what the problem is.  I had my laptop--which worked with the same SVN settings on my home network.  The difference was the work laptop was Windows XP SP 2--and my home desktop computer was Windows Vista.  A-ha!  Windows Firewall?  Turned it off, same thing.  McAfee Virus Scan?  Uninstalled it, same thing.  DLink router?  Disabled the firewall, allow network access, same thing.</p>

<p>Searched SmartSVN forums--no answer.  Tried TortoiseSVN--same problem.  Tried another product called Syncro SVN--again, same behavior.  I'm falling further behind on my deadline, when I give up and write to our terrific IT captain from <a href="http://www.ancientgeek.com/">Ancient Geek</a> that he was right--Vista sucks.</p>

<p>Luckily, I did, because he told me what the real problem was--the TCP/IP auto tuning feature that Vista has.  According to this article at ChapterZero:</p>

<p><em>Microsoft Windows Vista has auto-tuning enabled for TCP/IP which continually adjusts itself. It increases file transfer speed on the network but in some cases it may actually slow down everything which is accessing network. Auto-tuning also slows down network browsing of other machines on the network.</em></p>

<p>It's easy to check and see what your current TCP/IP receive tuning level is.  Open up a CMD window with admin priviliges and type:</p>

<p><strong>netsh interface tcp show global</strong></p>

<p>Then if it's on and you want to turn it off:</p>

<p><strong>netsh interface tcp set global autotuning=disabled</strong></p>

<p>More detailed steps are given for this at <a href="http://www.speedguide.net/faq_in_q.php?qid=247">SpeedGuide</a>.</p>

<p>No wonder I drove myself nuts.  I kept searching and searching for anything network related in the Control Panel and it wasn't there.  Now that I've disabled this feature, both SmartSVN and TortoiseSVN are working fine.  Thank you, <a href="http://www.ancientgeek.com/">Ancient Geek</a>!<br />
</p>]]></description>
         <link>http://www.attilan.com/2007/12/svn-windows-vista-and-mysterio.php</link>
         <guid>http://www.attilan.com/2007/12/svn-windows-vista-and-mysterio.php</guid>
         <category>Windows Vista</category>
         <pubDate>Sun, 02 Dec 2007 21:10:55 -0800</pubDate>
      </item>
      
      <item>
         <title>Transparent Color in C# control: Bug fix details</title>
         <description><![CDATA[<p>I thought it might be interesting to document the recent code modifications to CrystalGradientControl to allow sub-classes (CrystalLabel and CrystalPictureBox) to have transparent backgrounds.</p>

<p>As most Windows Forms programmers know, setting the BackColor to Transparent is the way to allow transparent backgrounds in most controls.  I wanted to support the same convention.  However, setting the BackColor to Transparent result in a nasty message ("Control does not support transparent background colors").  To fix this, I had to call SetStyles to declare that my color does support transparency:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> CrystalGradientControl()
{
  SetStyle(ControlStyles.SupportsTransparentBackColor, 
           <span class="kwrd">true</span>);
}</pre>

<p>Next, I wanted to override the property (from the base class Control), BackColor.  Why?  Because when BackColor is set to Transparent, I needed to set an internal property called TransparentMode to True.  TransparentMode triggers a number of things best described on <a href="http://www.bobpowell.net/transcontrols.htm">Bob Powell's article on transparent controls</a>.  This was all I needed to do:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">override</span> Color BackColor
{
    get
    {
        <span class="kwrd">return</span> <span class="kwrd">base</span>.BackColor;
    }
    set
    {
        <span class="kwrd">if</span> (<span class="kwrd">base</span>.BackColor != <span class="kwrd">value</span>)
        {
          <span class="kwrd">base</span>.BackColor = <span class="kwrd">value</span>;
          TransparentMode = 
            (<span class="kwrd">base</span>.BackColor == Color.Transparent);
          <span class="kwrd">this</span>.InvalidateEx();
        }
    }
}</pre>

<p>Now my controls allowed the transparent color, but the background was still getting painted black.  Why?  Because in my override of OnPaintBackground, I needed to call the base class when TransparentMode was set to true, to allow the parent Form to repaint the background:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnPaintBackground
                    (PaintEventArgs pevent)
{
    <span class="kwrd">if</span> (TransparentMode)
    {
        <span class="kwrd">base</span>.OnPaintBackground(pevent);
        <span class="kwrd">return</span>;
    }

    PaintGradientBackground(pevent.Graphics);
}
</pre>

<p>There you have it, a few simple fixes.  When I first started this toolkit, I didn't know how programmers set the transparent color.  I made a mistake in having the TransparentMode property be public and totally ignoring BackColor.  Now I've hidden TransparentMode from the Forms designer and allow programmers to do it the traditional way.</p>]]></description>
         <link>http://www.attilan.com/2007/07/transparent-color-in-c-control.php</link>
         <guid>http://www.attilan.com/2007/07/transparent-color-in-c-control.php</guid>
         <category>Crystal Toolkit</category>
         <pubDate>Mon, 09 Jul 2007 01:11:11 -0800</pubDate>
      </item>
      
      <item>
         <title>Transparent CrystalLabel and CrystalPictureBox</title>
         <description><![CDATA[<p>CrystalLabel and CrystalPictureBox were not allowing Transparent backgrounds.  This is a bug that was fixed in <a href="http://www.attilan.com/2007/07/crystal_toolkit_alpha_release_10.php">Crystal Toolkit version 0.77</a>.  I have to admit that I am more focused on the gradient properties of these controls--doing the transparency thing was a side experiment.  I've been tempted to drop the transparent mode altogether (and I have done that in CrystalTrackBar, which has numerous problems).  However, I found a pretty simple fix to allow the Label and PictureBox controls to retain a transparent background.</p>

<p>How do you set these controls to have a Transparent background?  By default, you have the gradient mode set when you drag CrystalLabel and CrystalPictureBox onto your form:</p>

<p><img alt="gradient_control.jpg" src="http://www.attilan.com/gradient_control.jpg" width="450" height="341" /></p>

<p>To attain this gradient setting, you need to have BackColor set to Control, and then Color1 and Color2 make up the gradient blend of colors:</p>

<p><img alt="gradient_control_setting.jpg" src="http://www.attilan.com/gradient_control_setting.jpg" width="266" height="258" /></p>

<p>Now, if you want the Transparent background, simply set BackColor to Transparent (on the Web tab of the color property dialog).  This is the standard way to set transparency with other .NET controls.  When I started this toolkit, I was ignorant of that fact.  Internally within the CrystalGraidentControl class, setting BackColor to Transparent makes the TransparentMode property true.</p>

<p><img alt="transparent_control_setting.jpg" src="http://www.attilan.com/transparent_control_setting.jpg" width="269" height="249" /></p>

<p>The end result is that both the CrystalLabel and CrystalPictureBox controls have a transparent background and allow the wallpaper in the form to show through.  This sample code is in the <a href="http://www.attilan.com/2007/07/crystal_toolkit_alpha_release_10.php">CrystalToolkit 0.77</a>, called TestAttilanTransparent.</p>

<p><img alt="transparent_control.jpg" src="http://www.attilan.com/transparent_control.jpg" width="450" height="342" /><br />
</p>]]></description>
         <link>http://www.attilan.com/2007/07/transparent-crystallabel-and-c.php</link>
         <guid>http://www.attilan.com/2007/07/transparent-crystallabel-and-c.php</guid>
         <category>Crystal Toolkit</category>
         <pubDate>Sun, 08 Jul 2007 13:20:55 -0800</pubDate>
      </item>
      
   </channel>
</rss>
