<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sunstorm Blog</title>
	<atom:link href="http://www.sunstormlabs.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sunstormlabs.net/blog</link>
	<description>We make the storm in your head</description>
	<lastBuildDate>Thu, 17 Dec 2009 17:30:59 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Exceptions in BackgroundWorker</title>
		<link>http://www.sunstormlabs.net/blog/2009/12/17/exceptions-in-backgroundworker/</link>
		<comments>http://www.sunstormlabs.net/blog/2009/12/17/exceptions-in-backgroundworker/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 17:28:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/?p=135</guid>
		<description><![CDATA[To save 15 minutes of confusion.
If an exception is thrown in a BackgroundWorker&#8217;s DoWork handler, the backgroundworker will catch it and place the exception in RunWorkerCompleted&#8217;s e.Error.
If it seems like the Exception&#8217;s still being thrown with no apparent way to catch it, it&#8217;s because if e.Error is not null. When that&#8217;s the case, e.Result will throw [...]]]></description>
			<content:encoded><![CDATA[<p>To save 15 minutes of confusion.</p>
<p>If an exception is thrown in a BackgroundWorker&#8217;s DoWork handler, the backgroundworker <em>will</em> catch it and place the exception in RunWorkerCompleted&#8217;s e.Error.</p>
<p>If it seems like the Exception&#8217;s still being thrown with no apparent way to catch it, it&#8217;s because if e.Error is not null. When that&#8217;s the case, e.Result will throw that error (wrapped in a TargetInvocationException) when accessed. Do not access e.Result without checking for e.Error first.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> worker_RunWorkerCompleted<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, RunWorkerCompletedEventArgs e<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  EndCreate<span style="color: #000000;">&#40;</span>e.<span style="color: #0000FF;">Error</span>, e.<span style="color: #0000FF;">Result</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">// &lt;--- THIS WILL CRASH IF e.Error IS NOT NULL</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> worker_RunWorkerCompleted<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, RunWorkerCompletedEventArgs e<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">// THIS WILL NOT.</span>
  <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>e.<span style="color: #0000FF;">Error</span> <span style="color: #008000;">==</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
    EndCreate<span style="color: #000000;">&#40;</span>e.<span style="color: #0000FF;">Error</span>, e.<span style="color: #0000FF;">Result</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #000000;">&#125;</span>
  <span style="color: #0600FF;">else</span> <span style="color: #000000;">&#123;</span>
    EndCreate<span style="color: #000000;">&#40;</span>e.<span style="color: #0000FF;">Error</span>, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">// accessing e.Result throws the exception</span>
  <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2009/12/17/exceptions-in-backgroundworker/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Studio for Eclipse</title>
		<link>http://www.sunstormlabs.net/blog/2009/06/06/zend-studio-for-eclipse/</link>
		<comments>http://www.sunstormlabs.net/blog/2009/06/06/zend-studio-for-eclipse/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 02:22:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Rants]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/2009/06/06/zend-studio-for-eclipse/</guid>
		<description><![CDATA[Right, lets get this out of the way. Zend Studio for Eclipse is a great tool and no other PHP IDEs come near to its level of Intellisense smarts, features, and integration. I’ve been using it steadily since version 5, before it was Eclipse, and I don’t see myself stopping in the future.
That said…
Most code [...]]]></description>
			<content:encoded><![CDATA[<p>Right, lets get this out of the way. Zend Studio for Eclipse is a great tool and no other PHP IDEs come near to its level of Intellisense smarts, features, and integration. I’ve been using it steadily since version 5, before it was Eclipse, and I don’t see myself stopping in the future.</p>
<p>That said…</p>
<p>Most code editors have figured out this whole code folding thing where you click on the minus button next to the function block and it collapses into a neat declaration.</p>
<p>Zend Studio has this too, only with a slight twist. Most of the times it works right. Other times, it forgets to fold bits. Yet other times, especially when folding PHPDoc blocks, the fold swallows whole unrelated fields/functions that happen to be next to the one I want to fold, declaration and everything. Nice.</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="zend-collapse-faggotry" border="0" alt="zend-collapse-faggotry" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2009/06/zendcollapsefaggotry.png" width="504" height="95" /> </p>
<p>I could understand this slipping past testing given how intermittent it is, but ZS’s been around for at least a couple of years, and it’s got like a dozen version updates, one of which explicitly touted having better folding. Yeah, it’s better, because before it screwed up half the time rather than a 10th of the time. It still sucks.</p>
<p>And while on the subject of sucking, in what universe is it sensible that if I edit a file that exists in a ZS project outside of the environment, and then try to open it in ZS, it flips out in glorious fashion:</p>
<p>&#160;<a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2009/06/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2009/06/image-thumb.png" width="743" height="592" /></a> </p>
<p>And then I right click on the offending file, click on Refresh, and it’s happy again. If it knows it’s out of sync, why the hell can’t it refresh it automatically? The file’s <em>right there</em>!</p>
<p>Makes me want to hit it. Surely I can’t be the only one running into this stuff?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2009/06/06/zend-studio-for-eclipse/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Changelogs are nice</title>
		<link>http://www.sunstormlabs.net/blog/2009/02/20/changelogs-are-nice/</link>
		<comments>http://www.sunstormlabs.net/blog/2009/02/20/changelogs-are-nice/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 12:09:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Rants]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/?p=114</guid>
		<description><![CDATA[I&#8217;m talking to you, Windows Live 8046.206. If you&#8217;re going to make me go through a 5 minute installation, you could at least tell me what&#8217;s changed so I can look forward to it, especially when your latest update has no visible changes.
You see, I&#8217;m thrilled at the knowledge that some piece of the software [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m talking to you, Windows Live 8046.206. If you&#8217;re going to make me go through a 5 minute installation, you could at least tell me what&#8217;s changed so I can look forward to it, especially when your latest update has no visible changes.</p>
<p>You see, I&#8217;m <em>thrilled</em> at the knowledge that some piece of the software I use every day received an update and got a little bit better. Maybe a potential security problem was solved, maybe some performance was added, or maybe some kink was ironed out. Whatever it was, I love the feeling that something that was making my life an insignificant bit harder is going to go away in the new release. Even if it didn&#8217;t affect me before, the knowledge that it&#8217;s not ever going to gives me a little bit of peace of mind.</p>
<p>But, you know, I have to know about it. If I don&#8217;t, I can&#8217;t feel good about it.</p>
<p>And it&#8217;s especially mean of you to have a large &#8220;What&#8217;s new&#8221; button that just takes me to your homepage. Then you&#8217;re just being a cocktease.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2009/02/20/changelogs-are-nice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Initializing DataRows</title>
		<link>http://www.sunstormlabs.net/blog/2009/02/09/initializing-datarows/</link>
		<comments>http://www.sunstormlabs.net/blog/2009/02/09/initializing-datarows/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 17:51:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/?p=108</guid>
		<description><![CDATA[How many ways are there to initialize a new DataRow with new values?


Set the DefaultValue property on the respective DataColumns.
This works fine for static values. However, you&#8217;re likely using the DataSet designer in Visual Studio, and it will hose itself if you try to set a GUID because it can&#8217;t tell them apart from a [...]]]></description>
			<content:encoded><![CDATA[<p>How many ways are there to initialize a new DataRow with new values?</p>
<ol>
<li>
<h3>Set the DefaultValue property on the respective DataColumns.</h3>
<p>This works fine for static values. However, you&#8217;re likely using the DataSet designer in Visual Studio, and it will hose itself if you try to set a GUID because it can&#8217;t tell them apart from a string. Plus, initializing with dynamic values like <code>DateTime.Now</code> won&#8217;t work because you&#8217;ll end up with the date of the creation of the column rather than the date of the row.</li>
<li>
<h3>Initialize after creating it, but before adding it to the DataTable.</h3>
<p>If you&#8217;re creating the row manually, you can just set any initial values before adding it to the table. None of the values, indices, etc. are validated until that happens. Strong typed datasets are even nice enough to generate methods that take and return rows of your type.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">MyDataSet ds <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> MyDataSet<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
MyTableRow row <span style="color: #008000;">=</span> ds.<span style="color: #0000FF;">MyTable</span>.<span style="color: #0000FF;">NewMyTableRow</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
row.<span style="color: #0000FF;">ID</span> <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Guid<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
row.<span style="color: #0000FF;">CreatedOn</span> <span style="color: #008000;">=</span> DateTime.<span style="color: #0000FF;">Now</span><span style="color: #008000;">;</span>
ds.<span style="color: #0000FF;">MyTable</span>.<span style="color: #0000FF;">AddMyTableRow</span><span style="color: #000000;">&#40;</span>row<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

</li>
<li>
<h3>Override the OnTableNewRow of the DataTable in a derived class. <em>This doesn&#8217;t actually work.</em></h3>
<p>Like the derived classes created by the strong typed table generator. You can get to this method if you use the DataSet&#8217;s helpful partial class definition:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">// Note: does not actually work</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">partial</span> <span style="color: #FF0000;">class</span> MyDataSet <span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">partial</span> <span style="color: #FF0000;">class</span> MyTable <span style="color: #000000;">&#123;</span>
        <span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> OnTableNewRow<span style="color: #000000;">&#40;</span>DataTableNewRowEventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
            MyDataSet.<span style="color: #0000FF;">MyTableRow</span> row <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>MyDataSet.<span style="color: #0000FF;">MyTableRow</span><span style="color: #000000;">&#41;</span>e.<span style="color: #0000FF;">Row</span><span style="color: #008000;">;</span>
            row.<span style="color: #0000FF;">ID</span> <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Guid<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            row.<span style="color: #0000FF;">CreatedOn</span> <span style="color: #008000;">=</span> DateTime.<span style="color: #0000FF;">Now</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF;">base</span>.<span style="color: #0000FF;">OnTableNewRow</span><span style="color: #000000;">&#40;</span>e<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>It doesn&#8217;t work because <strong>this method is never called <a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98383">unless you also attach a handler to the TableNewRow event</a></strong>, defeating the whole point of creating a virtual method. GG, Microsoft. This set me back a whole afternoon trying to figure out why some of my tables ran the method and others didn&#8217;t.</p>
<p>You can overcome this if you&#8230;</li>
</ol>
<p><span id="more-108"></span></p>
<ol start="3">
<li>
<h3>Handle the TableNewRow event of the DataTable.</h3>
<p>Good if you want to initialize with external values of some kind, but you can also attach the handler from inside the typed DataTable if you override the <code>EndInit()</code> method, which being part of <code>ISupportInitialize</code>, Visual Studio calls every time the table is initialized in a designer. If you use the dataset outside of the designer, well, you&#8217;re screwed.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">partial</span> <span style="color: #FF0000;">class</span> MyDataSet <span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">partial</span> <span style="color: #FF0000;">class</span> MyTable <span style="color: #000000;">&#123;</span>
        <span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> EndInit<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
            <span style="color: #0600FF;">this</span>.<span style="color: #0000FF;">TableNewRow</span> <span style="color: #008000;">+=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, TableNewRowEventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&amp;</span>gt<span style="color: #008000;">;</span> <span style="color: #000000;">&#123;</span> <span style="color: #008080; font-style: italic;">// use 'delegate' if not C# 3.0</span>
                MyDataSet.<span style="color: #0000FF;">MyTableRow</span> row <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>MyDataSet.<span style="color: #0000FF;">MyTableRow</span><span style="color: #000000;">&#41;</span>e.<span style="color: #0000FF;">Row</span><span style="color: #008000;">;</span>
                row.<span style="color: #0000FF;">ID</span> <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Guid<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
                row.<span style="color: #0000FF;">CreatedOn</span> <span style="color: #008000;">=</span> DateTime.<span style="color: #0000FF;">Now</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF;">base</span>.<span style="color: #0000FF;">OnTableNewRow</span><span style="color: #000000;">&#40;</span>e<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

</li>
<li>
<h3>Use a BindingSource and handle the AddingNew event.</h3>
<p>You bound your dataset to a bunch of controls, and now you want to create new rows with data that&#8217;s only available in your presentation tier. BindingSources let you control the row creation process completely if you handle the AddingNew event. The downside is that you have to create the whole thing manually, and to do that you have to know how BindingSources work.</p>
<p>Another caveat is that the BindingSource&#8217;s Position won&#8217;t move to the newly created item, like it would otherwise. You&#8217;ll have to do that yourself.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">myBindingSource.<span style="color: #0000FF;">AddingNew</span> <span style="color: #008000;">+=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, AddingNewEventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&amp;</span>gt<span style="color: #008000;">;</span> <span style="color: #000000;">&#123;</span>
    DataRowView view <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>DataView<span style="color: #000000;">&#41;</span>myBindingSource.<span style="color: #0000FF;">List</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">AddNew</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    MyDataSet.<span style="color: #0000FF;">MyTableRow</span> row <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>MyDataSet.<span style="color: #0000FF;">MyTableRow</span><span style="color: #000000;">&#41;</span>view.<span style="color: #0000FF;">Row</span><span style="color: #008000;">;</span>
    row.<span style="color: #0000FF;">ID</span> <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Guid<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    row.<span style="color: #0000FF;">CreatedOn</span> <span style="color: #008000;">=</span> DateTime.<span style="color: #0000FF;">Now</span><span style="color: #008000;">;</span>
    e.<span style="color: #0000FF;">NewObject</span> <span style="color: #008000;">=</span> view<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>There&#8217;s a better way in which you don&#8217;t have to create the DataRowView&#8230;</li>
<li>
<h3>Use a BindingSource and handle the ListChanged event.</h3>
<p>This is the easiest way to initialize rows directly on the BindingSource. Unlike the AddingNew method, the BindingSource creates the row, and sets the Position to the new item.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">myBindingSource.<span style="color: #0000FF;">ListChanged</span> <span style="color: #008000;">+=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, ListChangedEventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&amp;</span>gt<span style="color: #008000;">;</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>e.<span style="color: #0000FF;">ListChangedType</span> <span style="color: #008000;">==</span> ListChangedType.<span style="color: #0000FF;">ItemAdded</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
        DataRowView view <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>DataRowView<span style="color: #000000;">&#41;</span>myBindingSource<span style="color: #000000;">&#91;</span>e.<span style="color: #0000FF;">NewIndex</span><span style="color: #000000;">&#93;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>view.<span style="color: #0000FF;">IsNew</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #008080; font-style: italic;">// Check if the row is in its detached state</span>
            MyDataSet.<span style="color: #0000FF;">MyTableRow</span> row <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>MyDataSet.<span style="color: #0000FF;">MyTableRow</span><span style="color: #000000;">&#41;</span>view.<span style="color: #0000FF;">Row</span>
            row.<span style="color: #0000FF;">ID</span> <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Guid<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            row.<span style="color: #0000FF;">CreatedOn</span> <span style="color: #008000;">=</span> DateTime.<span style="color: #0000FF;">Now</span><span style="color: #008000;">;</span>
            bs.<span style="color: #0000FF;">ResetItem</span><span style="color: #000000;">&#40;</span>e.<span style="color: #0000FF;">NewIndex</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">// this is needed to get the controls to show the new values that we just set.</span>
        <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>The ListChanged event is called twice. First when the row is created in its detached state, and then again when it&#8217;s added to the Rows collection of the DataTable. We only need to handle it the first time. The call to ResetItem will make sure that all the bound controls read the new values.</li>
<li>
<h3>Use control-specific events.</h3>
<p>Some controls have their own events to initialize new rows. I don&#8217;t recommend using this approach, because it&#8217;s too control-specific. It&#8217;s much more interoperable to initialize at the BindingSource. You never know how that AddNew might be called.</li>
</ol>
<p>Depending on what kind of data you&#8217;re initializing, and in which tier, you might need to mix and match. #4 for the data tier and #6 for the forms do the job for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2009/02/09/initializing-datarows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Windows and me</title>
		<link>http://www.sunstormlabs.net/blog/2008/11/20/windows_and_me/</link>
		<comments>http://www.sunstormlabs.net/blog/2008/11/20/windows_and_me/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 12:07:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/?p=103</guid>
		<description><![CDATA[As it turns out, I share a birthday with the Windows OS. Windows is exactly one year older than me. I&#8217;ll drink to that.
I am not the only one.
Nifty.
]]></description>
			<content:encoded><![CDATA[<p>As it turns out, I share a birthday with the Windows OS. Windows is exactly one year older than me. I&#8217;ll drink to that.</p>
<p><a href="http://www.withinwindows.com/2008/11/20/say-happy-birthday-to-microsoft-windows-and-i/" target="_blank">I am not the only one.</a></p>
<p>Nifty.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2008/11/20/windows_and_me/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Goodbye, b2evo</title>
		<link>http://www.sunstormlabs.net/blog/2008/11/03/goodbye-b2evo/</link>
		<comments>http://www.sunstormlabs.net/blog/2008/11/03/goodbye-b2evo/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 12:59:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Rants]]></category>
		<category><![CDATA[b2evolution]]></category>
		<category><![CDATA[faggotry]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/?p=3</guid>
		<description><![CDATA[b2evolution didn&#8217;t go quite as well as I had hoped. A couple of days ago it started giving me HTTP 406 errors for some posts for no apparent reason, and filling my error log with fascinating things like&#8230;
[15-Oct-2008 04:52:15] b2evolution error: MySQL error! / Duplicate entry 'c-events-are-accessors' for key 2(Errno=1062) / Your query: DataObject::dbinsert()INSERT INTO [...]]]></description>
			<content:encoded><![CDATA[<p>b2evolution didn&#8217;t go quite as well as I had hoped. A couple of days ago it started giving me HTTP 406 errors for some posts for no apparent reason, and filling my error log with fascinating things like&#8230;</p>
<blockquote><p><code>[15-Oct-2008 04:52:15] b2evolution error: MySQL error! / Duplicate entry 'c-events-are-accessors' for key 2(Errno=1062) / Your query: DataObject::dbinsert()INSERT INTO evo_items__item (post_datestart, post_creator_user_ID, post_notifications_status, post_renderers, post_status, post_locale, post_priority, post_main_cat_ID, post_ptyp_ID, post_url, post_excerpt, post_urltitle, post_comment_status, post_title, post_content, post_wordcount, post_datecreated, post_datemodified, post_lastedit_user_ID) / VALUES ('2008-10-15 12:52:14', '1', 'noreq', 'b2evSmil.b2evALnk.evo_videoplug.b2WPAutP.evo_code', 'draft', 'en-US', '3', 16, 1, '', '', 'c-events-are-accessors', 'open', 'C# events are accessors', 'An interesting feature of C# I discovered recently is that events are actually accessors, [...] is', 60, '2008-10-15 12:52:14', '2008-10-15 12:52:14', 1) in /home/sonic12/public_html/sunstormlabs/inc/_core/model/db/_db.class.php at line 568 / REQUEST_URI: /admin.php / HTTP_REFERER: <a href="http://www.sunstormlabs.net/admin.php?ctrl=items&amp;action=new&amp;blog=1">http://www.sunstormlabs.net/admin.php?ctrl=items&amp;action=new&amp;blog=1</a><br />
[30-Oct-2008 04:51:01] XML error: Invalid document end at line 2, column 1</code></p></blockquote>
<p>Being patient with software faggotry like the programmer I am, I promptly fixed the error by installing WordPress.</p>
<p>I was fed up with b2evolution anyway. It was doing a lot of stuff that I didn&#8217;t care for, and wasn&#8217;t doing a lot of stuff that I did want. It had support for multiple blogs for people with MPD, and statistics rendered useless by Analytics, but it also had some 3 good (ie: not fixed width) skins available, couldn&#8217;t do comments and their formatting right, had at least 3 URLs for everything, wasn&#8217;t very friendly about posting images, no decent syntax highlighting plugin, and I was feeling left out of all the WordPress feature wanking I keep seeing on other blogs.</p>
<p>The irony is that I picked b2evo in the first place <em>because it wasn&#8217;t WordPress</em> and I wanted to be different. No matter how much I try to convince myself that &#8220;alternative&#8221; doesn&#8217;t mean &#8220;worse&#8221; in every possible context, 10 out of 10.1 times I get a cockslap to the face. Why do I bother?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2008/11/03/goodbye-b2evo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# events are actually accessors</title>
		<link>http://www.sunstormlabs.net/blog/2008/10/15/c-events-are-actually-accessors/</link>
		<comments>http://www.sunstormlabs.net/blog/2008/10/15/c-events-are-actually-accessors/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 21:00:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[delegates]]></category>
		<category><![CDATA[events]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/?p=32</guid>
		<description><![CDATA[An interesting feature of C# I discovered recently is that events are actually accessors into Multicast Delegates, much like properties are accessors into other fields.

private string myData;
public string MyData // A property
&#123;
  get &#123; return myData; &#125; // called when the property is read
  set &#123; myData = value; &#125; // called when [...]]]></description>
			<content:encoded><![CDATA[<p>An interesting feature of C# I discovered recently is that events are actually accessors into Multicast Delegates, much like properties are accessors into other fields.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">private</span> <span style="color: #FF0000;">string</span> myData<span style="color: #008000;">;</span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> MyData <span style="color: #008080; font-style: italic;">// A property</span>
<span style="color: #000000;">&#123;</span>
  get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> myData<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span> <span style="color: #008080; font-style: italic;">// called when the property is read</span>
  set <span style="color: #000000;">&#123;</span> myData <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span> <span style="color: #008080; font-style: italic;">// called when the property is written to</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">private</span> EventHandler myDataChanged<span style="color: #008000;">;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">event</span> EventHandler MyDataChanged <span style="color: #008080; font-style: italic;">// An event</span>
<span style="color: #000000;">&#123;</span>
  add <span style="color: #000000;">&#123;</span> myDataChanged <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>EventHandler<span style="color: #000000;">&#41;</span><span style="color: #FF0000;">Delegate</span>.<span style="color: #0000FF;">Combine</span><span style="color: #000000;">&#40;</span> myDataChanged, value <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span> <span style="color: #008080; font-style: italic;">// called when a handler is attached</span>
  remove <span style="color: #000000;">&#123;</span> myDataChanged <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>EventHandler<span style="color: #000000;">&#41;</span><span style="color: #FF0000;">Delegate</span>.<span style="color: #0000FF;">Remove</span><span style="color: #000000;">&#40;</span> myDataChanged, value <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span> <span style="color: #008080; font-style: italic;">// called when a handler is detached</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p><span id="more-32"></span></p>
<p>A vanilla event declaration, without the accessors, does this internally. It also acquires a lock every time it accesses the EventHandler to be thread safe, which we&#8217;re not doing here, and you should, if you need the safety.</p>
<p>A great application of this is to simulate &#8220;bubble&#8221; events in WinForms like in ASP.NET. Take for example a form with a user control with a button in it. If I wanted to receive the button&#8217;s click event on the form, I would have to either expose the button, or handle its event in the control, and raise a different one on the control:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> MyControl <span style="color: #008000;">:</span> UserControl
<span style="color: #000000;">&#123;</span>
  <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">event</span> EventHandler MyButtonClick<span style="color: #008000;">;</span>
  Button btn<span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #0600FF;">public</span> MyControl<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
  <span style="color: #000000;">&#123;</span>
    btn <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Button<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    btn.<span style="color: #0000FF;">Click</span> <span style="color: #008000;">+=</span> <span style="color: #008000;">new</span> EventHandler<span style="color: #000000;">&#40;</span> btn_Click <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #000000;">&#125;</span>
&nbsp;
  <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> myBtn_Click<span style="color: #000000;">&#40;</span> <span style="color: #FF0000;">object</span> sender, EventArgs e <span style="color: #000000;">&#41;</span>
  <span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span> MyButtonClick <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span> <span style="color: #000000;">&#41;</span>
      MyButtonClick<span style="color: #000000;">&#40;</span> sender, e <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> MyForm <span style="color: #008000;">:</span> Form
<span style="color: #000000;">&#123;</span>
  MyControl ctl<span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #0600FF;">public</span> Form<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
  <span style="color: #000000;">&#123;</span>
    ctl <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> MyControl<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    ctl.<span style="color: #0000FF;">MyButtonClick</span> <span style="color: #008000;">+=</span> <span style="color: #008000;">new</span> EventHandler<span style="color: #000000;">&#40;</span> ctl_MyButtonClick <span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #000000;">&#125;</span>
&nbsp;
  <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">void</span> ctl_MyButtonClick<span style="color: #000000;">&#40;</span> <span style="color: #FF0000;">object</span> sender, EventArgs e <span style="color: #000000;">&#41;</span>
  <span style="color: #000000;">&#123;</span>
    <span style="color: #008080; font-style: italic;">// Button clicked on the control!</span>
  <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>This can get rather bothersome and ugly if you have many buttons. Using an event accessor you can take the handler and attach it to anything you like, so you can just pass-through the handler directly to the button(s).</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> MyControl <span style="color: #008000;">:</span> UserControl
<span style="color: #000000;">&#123;</span>
  Button btn<span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #0600FF;">public</span> MyControl<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
  <span style="color: #000000;">&#123;</span>
    btn <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Button<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #000000;">&#125;</span>
&nbsp;
  <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">event</span> EventHandler MyButtonClick
  <span style="color: #000000;">&#123;</span>
    add <span style="color: #000000;">&#123;</span> btn.<span style="color: #0000FF;">Click</span> <span style="color: #008000;">+=</span> value<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
    remove <span style="color: #000000;">&#123;</span> btn.<span style="color: #0000FF;">Click</span> <span style="color: #008000;">-=</span> value<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
  <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>There&#8217;s one caveat to this technique, and that&#8217;s when you handle the event somewhere upstream, the &#8220;sender&#8221; would be the button, not the MyControl. This might break encapsulation, and if that&#8217;s important to you, the handle/re-raise method is the way to go.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2008/10/15/c-events-are-actually-accessors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to dismantle a Logitech G15 keyboard</title>
		<link>http://www.sunstormlabs.net/blog/2008/05/23/how-to-dismantle-a-logitech-g15-keyboard/</link>
		<comments>http://www.sunstormlabs.net/blog/2008/05/23/how-to-dismantle-a-logitech-g15-keyboard/#comments</comments>
		<pubDate>Fri, 23 May 2008 21:00:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[dismantle]]></category>
		<category><![CDATA[g15]]></category>
		<category><![CDATA[keyboard]]></category>
		<category><![CDATA[logitech]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/?p=35</guid>
		<description><![CDATA[My Logitech G15 got wet again and none of the keys were working. The logical thing to do, then, is to take it apart and try to figure out what&#8217;s wrong with it.
Note: Don&#8217;t try this at home. It WILL irrevocably void your warranty, and you can easily cause permanent damage to the keyboard.

First, we [...]]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://en.wikipedia.org/wiki/Logitech_G15">Logitech G15</a> got wet again and none of the keys were working. The logical thing to do, then, is to take it apart and try to figure out what&#8217;s wrong with it.</p>
<p><strong>Note: Don&#8217;t try this at home. It <em>WILL</em> irrevocably void your warranty, and you can easily cause permanent damage to the keyboard.</strong></p>
<p><span id="more-35"></span></p>
<p>First, we need to unscrew all the screws on the bottom plate. The top plate is also locked down by a bunch of plastic hooks, which can be pulled back with the help of a thin screwdriver. Be careful with the silver plastic, since it scratches very easily.</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-1.jpg"><img class="alignnone size-medium wp-image-36" title="dismantle-g15-1" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-1-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-2.jpg"><img class="alignnone size-medium wp-image-37" title="dismantle-g15-2" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-2-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>The LCD is attached to the top cover with a small FPCB to the main circuit. It can be removed by pulling up the little clamp that holds it in the socket.</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-3.jpg"><img class="alignnone size-medium wp-image-38" title="dismantle-g15-3" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-3-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-4.jpg"><img class="alignnone size-medium wp-image-39" title="dismantle-g15-4" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-4-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>All of the important electronics are at the top of the keyboard. It&#8217;s rare for the electronics to break during a spill since most of the water gets on the keys themselves. Our next task is to remove the silver plastic panel, the one on which all the keys are.</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-5.jpg"><img class="alignnone size-medium wp-image-40" title="dismantle-g15-5" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-5-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-6.jpg"><img class="alignnone size-medium wp-image-41" title="dismantle-g15-6" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-6-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>First, it has to be unscrewed. The clear plastic bits that go under it also unscrew at the top, and the FPCB connections can be carefully detached by easing them out of their sockets.</p>
<p>Again, there are plastic hooks holding it in place. These are easier to go around. The bottom ones can be released by bending and twisting the keyboard a bit, and if not there are a handy set of holes one can use to get to them with a thin screwdriver.</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-8.jpg"><img class="alignnone size-medium wp-image-42" title="dismantle-g15-8" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-8-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-9.jpg"><img class="alignnone size-medium wp-image-43" title="dismantle-g15-9" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-9-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-10.jpg"><img class="alignnone size-medium wp-image-44" title="dismantle-g15-10" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-10-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>This should get the keyplate separated from the keyboard.</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-11.jpg"><img class="alignnone size-medium wp-image-45" title="dismantle-g15-11" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-11-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-12.jpg"><img class="alignnone size-medium wp-image-46" title="dismantle-g15-12" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-12-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-13.jpg"><img class="alignnone size-medium wp-image-47" title="dismantle-g15-13" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-13-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>Underneath it, we can see a clear plastic plate and the LEDs used for backlighting the keys. Some of it&#8217;s wet; I&#8217;m on the right track. The real problem lies under it though, so lets get that off too.</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-14.jpg"><img class="alignnone size-medium wp-image-48" title="dismantle-g15-14" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-14-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-15.jpg"><img class="alignnone size-medium wp-image-49" title="dismantle-g15-15" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-15-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>The backlighting LEDs and their circuits sit in the gaps in the plastic. All those litle white dots diffuse the LED light all over the keyboard.</p>
<p>Beneath it, we have a flexible PCB printed on a transparent substrate. This is what detects keystrokes. It&#8217;s made up of three layers. All those little lines are a very thin layer of conductive material. The middle layer is just a separator that keeps them separated until a key pushes them together. Every top-bottom combination is unique, and when they&#8217;re connected, the keyboard can figure out which key&#8217;s being pressed.</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-16.jpg"><img class="alignnone size-medium wp-image-50" title="dismantle-g15-16" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-16-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-17.jpg"><img class="alignnone size-medium wp-image-51" title="dismantle-g15-17" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-17-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>What pushes them together is this rubber membrane, which also makes the keys pop back up after being pressed.</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-18.jpg"><img class="alignnone size-medium wp-image-52" title="dismantle-g15-18" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-18-300x225.jpg" alt="" width="300" height="225" /></a><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-19.jpg"><img class="alignnone size-medium wp-image-53" title="dismantle-g15-19" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-19-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>The problem with this, is that these FPCBs are extremely easy to erode with liquids. Having killed a Saitek Eclipse keyboard before by spilling stuff on it, I already know what to look for&#8230;</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-20.jpg"><img class="alignnone size-medium wp-image-54" title="dismantle-g15-20" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-20-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>Dirty, dissolved or corroded connections. This spells doom for all any any keys that they connect to. I&#8217;m still trying to find a good way to clean these that&#8217;ll keep them intact, and I&#8217;m not sure if it&#8217;s even possible. A wet cotton Q-tip seems to do the job, but it&#8217;s important not to use any cleaning products, because they melt the connections right off.</p>
<p>They can be easily tested with a multimeter. Most have a setting that will beep if there&#8217;s a connection.</p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-21.jpg"><img class="alignnone size-medium wp-image-56" title="dismantle-g15-21" src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/dismantle-g15-21-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>Those top connections are definately dead. Just my luck, these control the space bar, the letters A, Z, and parts of the keypad. Not exactly ignorable.</p>
<p>I&#8217;ve called Logitech, and they don&#8217;t sell separate parts. So I either fix it, or get a new keyboard.</p>
<p>Last time, I tried to repair the Saitek using liquid silver. However, the way it is, it&#8217;s hard to apply and takes ages to dry, and, well, didn&#8217;t work. This time I want to try a silver ink pen, which is claimed to be the same, but easier to use.</p>
<p>I&#8217;ve ordered one off eBay. While it doesn&#8217;t come in, I&#8217;ll be using a generic crapo-cheapo keyboard.</p>
<p>Exciting conclusion coming soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2008/05/23/how-to-dismantle-a-logitech-g15-keyboard/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The joys of FLAC</title>
		<link>http://www.sunstormlabs.net/blog/2008/05/02/the-joys-of-flac/</link>
		<comments>http://www.sunstormlabs.net/blog/2008/05/02/the-joys-of-flac/#comments</comments>
		<pubDate>Sat, 03 May 2008 06:15:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Music]]></category>
		<category><![CDATA[flac]]></category>
		<category><![CDATA[mp3]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/?p=25</guid>
		<description><![CDATA[Lets imagine that you have some music in MP3 format, and you&#8217;ve never heard the original source. This could be because you downloaded it from the internet, or bought it at an online music store like iTunes. You imagine that you&#8217;re getting the full musical experience with your 192kbps MP3, because you can listen to [...]]]></description>
			<content:encoded><![CDATA[<p>Lets imagine that you have some music in MP3 format, and you&#8217;ve never heard the original source. This could be because you downloaded it from the internet, or bought it at an online music store like iTunes. You imagine that you&#8217;re getting the full musical experience with your 192kbps MP3, because you can listen to it perfectly well with no distortion or anything, and if the music really needs it, just bump it up to 320kbps to make it absolutely indistinguishable from CD quality.</p>
<p>For the most part, that&#8217;s true, to the point that standard MP3s cover most peoples&#8217; listening needs. I&#8217;ve happily built up a 40+GB MP3 library for several years because of this. But only to a point. My opinion changed when I discovered <a href="http://flac.sourceforge.net/">FLAC</a>.</p>
<p><span id="more-25"></span></p>
<blockquote><p>FLAC stands for Free Lossless Audio Codec, an audio format similar to MP3, but lossless, meaning that audio is compressed in FLAC without any loss in quality. This is similar to how Zip works, except with FLAC you will get much better compression because it is designed specifically for audio[...]</p></blockquote>
<p>MP3 is a <em>lossy</em> format. That means that in order to reduce the size of the music file, an MP3 encoder will actually chop off parts of the sound. Like a JPEG, it gets away with this, because the parts that it cuts off are the ones that you are least expected to miss, such as frequencies that aren&#8217;t audible by the human ear. Depending on the bitrate of the file, it can be more or less zealous in cropping down the sounds.</p>
<p>FLAC is lossless, which means that it keeps <em>everything</em>, exactly as in the original. When ripped from your standard <a href="http://en.wikipedia.org/wiki/Red_Book_%28audio_CD_standard%29">Red Book</a> CD, that&#8217;s a mighty <strong>1411.2 kbps</strong> of pure, unadulterated sound.</p>
<div id="attachment_26" class="wp-caption alignnone" style="width: 245px"><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/mp3-flac-comparison.jpg"><img src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/mp3-flac-comparison-235x300.jpg" alt="MP3-FLAC comparison" title="MP3-FLAC comparison" width="235" height="300" class="size-medium wp-image-26" /></a><p class="wp-caption-text">MP3-FLAC comparison</p></div>
<p>An easy demonstration of just how much of a difference that is, is simply to listen to it. <a href="http://www.muzicman82.net/2007/09/07/to-flac-or-not-a-lossless-vs-mp3-comparison/">I took the above image from a MP3/FLAC comparison, made by someone that knows more about this than me, that shows what you get if you subtract the sound of an MP3 recording from the original source</a>. I was quite astonished when I heard it, because there&#8217;s just <em>so much sound</em> getting cut! Even taking in account <a href="http://en.wikipedia.org/wiki/Psychoacoustics">psychoacoustics</a>, there&#8217;s just <em>too much</em> to convince me that the difference is indistinguishable.</p>
<p>It seems that this is a pointless argument, unless you can actually prove that you can hear the difference with an <a href="http://en.wikipedia.org/wiki/ABX_test">ABX double blind test</a> (<a href="http://www.hydrogenaudio.org/forums/index.php?showtopic=57379">bringing it up on an enthusiast forum is sure to bring forth a barrage of furiously masturbating people which will quickly point this out</a>). And while I didn&#8217;t go as far as setting up a scientific experiment, I fell in love with FLAC because I can&#8217;t help but notice that when compared to <strong>commercial grade</strong> MP3s, for a lot of music, it <em>does</em> make a significant difference.</p>
<p>You can really appreciate the increase in resolution. All the subtle and intricate background effects like drum riffs and beats, become sharp and well defined, with the sound&#8217;s &#8220;contour&#8221; much easier to distinguish. Voices sound clearer and with more depth. You even start noticing things like the sound of the singer&#8217;s breathing. Everything gets more &#8220;oomph&#8221; to it. You can almost <em>feel</em>, even if not hear, all of the supposedly &#8220;inaudible&#8221; frequencies, and the sound becomes a lot more friendly to high volume listening. And what astounds me the most is that FLACs actually let me hear parts and effects of the music, which I simply previously didn&#8217;t know of at all. Things like stereo effects, subtle modulations, little sounds and decorations, and so many more tiny things. It&#8217;s almost like rediscovering my favorite music all over again.</p>
<p>Of course, it depends on the music. There are some things that are worth it, and others that aren&#8217;t. A lot of music doesn&#8217;t need all that quality because it doesn&#8217;t actually make use of all of the resolution. But if you take something like <a href="http://www.youtube.com/watch?v=q-c94VVU7zc">the rich and deep sounds and vocals of Muse</a>, or the <a href="http://ie.youtube.com/watch?v=oGECJP3phyY">addictive electronic pulse of Daft Punk</a>, or just about any live recordings, and FLAC completely blows MP3 out of the water.</p>
<div id="attachment_27" class="wp-caption alignnone" style="width: 310px"><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/daftpunk-pyramid.jpg"><img src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/daftpunk-pyramid-300x200.jpg" alt="Daft Punk in concert" title="Daft Punk pyramid" width="300" height="200" class="size-medium wp-image-27" /></a><p class="wp-caption-text">Daft Punk in concert</p></div>
<p>And of course, you actually need a decent sound rig to be able to produce the difference in the first place. If you have an integrated sound card, and basic computer speakers, you&#8217;re not going to get much more than MP3 has to offer anyway. Despite all the wild claims of being &#8220;Ultra Clear 3D Hi-Fi Xtreme!&#8221; that chipset manufacturers make, all integrated sound cards sound like utter crap, even for basic things. I&#8217;ve checked this with every motherboard I&#8217;ve owned, and always ended up disappointed. I personally have a Creative X-Fi rigged up to an old <a href="http://www.superfi.co.uk/index.cfm/page/moreinfo.cfm/Product_ID/831">Technics SADX850</a> living room amplifier that I confiscated from my parents for never using. That&#8217;s connected to a pair of large, 80 watt front speakers, and three smaller satellites for surround. </p>
<p><a href="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/technics-amplifier.png"><img src="http://www.sunstormlabs.net/blog/wp-content/uploads/2008/11/technics-amplifier.png" alt="" title="Technics SADX850 Amplifier" width="350" height="138" class="alignnone size-full wp-image-28" /></a></p>
<p>I still lack a dedicated subwoofer, so I also linked it with an old Creative 2.1 speaker set for the bass. It&#8217;s not the best approach, and any real audiophile will wince at the sight of it, but it works quite well. I have a large room to fill with sound, and most computer speakers are designed for covering a small range. At full volume, my rig can be heard two floors down. This is where FLAC really shines.</p>
<p>All of this isn&#8217;t really a compression problem as much as a publishing problem. Keep in mind I&#8217;m comparing FLACs with the kind of MP3s one would normally own &#8211; commercial grade MP3s, not handcrafted laboratory MP3s. You can certainly get a lot more from MP3s if you know what you&#8217;re doing and rip them yourself from the original, with the right codecs and the right settings. However, Most MP3s are either downloaded straight from the internet (and judging by the growth of the digital music industry, that tendency will keep growing), or ripped using Media Player, or some other consumer software.</p>
<p>I&#8217;ve worked for two years at <a href="http://www.musicaonline.pt/">MusicaOnline</a>, a digital music shop in Portugal. The usual &#8220;process&#8221; for publishing digital music isn&#8217;t exactly refined. The way things are done, you can easily end up with a &#8220;320 kbps&#8221; file, that got artificially padded up from a 128 kbps WMP/iTunes rip, and was re-encoded half a dozen times by an automated encoding server. I&#8217;ve seen this happen in front of me, and it made me cringe. This wouldn&#8217;t happen if the music got encoded in FLAC, since there&#8217;s no way to rip it in a way that affects the quality of the resulting audio. No matter how you do it, you still get all the same data.</p>
<p>The main reason that lossless methods aren&#8217;t widespread yet is that FLAC files are on average <strong>4 or 5 times bigger</strong> than their 320 kbps MP3 counterparts. An entire CD can easily cost you ~400MB of disk space, plus the increased download time, if you&#8217;re not ripping it yourself. Its size isn&#8217;t friendly to portables either, and because of that, FLAC doesn&#8217;t have the widespread hardware support that MP3 enjoys either. There&#8217;s only <a href="http://flac.sourceforge.net/links.html#hardware">a handful of portable players that can handle it</a>, but the list is growing.</p>
<p>It&#8217;s also very hard to find digital music stores that sell lossless music, and as usual, it&#8217;s file sharing networks that are leading the way. If you feel that some music could make use of FLAC&#8217;s increased quality, then you can usually <a href="http://btjunkie.org/search?q=FLAC">find it on a torrent search</a>. Provided you actually bought the music, <em>obviously</em>.</p>
<p>The size of FLACs doesn&#8217;t intimidate me. Disk space doesn&#8217;t cost much, and drive capacities are counted in <em>terabytes</em> these days. Broadband internet has become widespread as well. We already waste tons of bandwidth on HDTV just so we can inspect the pores on actors&#8217; faces, so why not increase the quality of my audio content as well?</p>
<p>In any case, now that FLAC&#8217;s popularity is increasing and FLAC rips are becoming easier to come by, I&#8217;ve started to migrate parts of my library to it. It&#8217;s still a painful process because of the size and availability, but so far it&#8217;s been paying off. I&#8217;ve been enjoying a lot of music all over again, on a whole different level, and it&#8217;s just awesome. So if you love music as much as I do, give FLAC a try. You might find yourself surprised at all the things you&#8217;ve been missing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2008/05/02/the-joys-of-flac/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>I hate Javascript, but I love JQuery</title>
		<link>http://www.sunstormlabs.net/blog/2008/04/29/i-hate-javascript-but-i-love-jquery/</link>
		<comments>http://www.sunstormlabs.net/blog/2008/04/29/i-hate-javascript-but-i-love-jquery/#comments</comments>
		<pubDate>Tue, 29 Apr 2008 22:34:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.sunstormlabs.net/blog/?p=59</guid>
		<description><![CDATA[When it comes to the web, I prefer to stay on the server, where it&#8217;s safe. I love the stability of the environment I get in server side code, and I detest the client side chaos that goes on in the faggotry of browser wars and their incompatibilities and differences.
If I can, I try to [...]]]></description>
			<content:encoded><![CDATA[<p>When it comes to the web, I prefer to stay on the server, where it&#8217;s safe. I love the stability of the environment I get in server side code, and I detest the client side chaos that goes on in the faggotry of browser wars and their incompatibilities and differences.</p>
<p>If I can, I try to avoid scripting completely. In the current state of browser affairs, I don&#8217;t feel like I can rely on Javascript for anything more than decoration and minor UI enhancements. When I do have to work with Javascript (and by that I mean any client side scripting language), I do it in a very conservative, &#8220;1.0&#8243; way.</p>
<p><span id="more-59"></span></p>
<p><a href="http://valorin.net/thoughts/forget_ajax_use_jue/">This post explains my feelings well</a>, and even goes as far as to propose the term &#8220;JUE&#8221;, for &#8220;Javascript Usability Enhancement&#8221;:</p>
<blockquote><p>AJAX [Javascript on the whole], should only be implemented after the page has complete functionality, and should only be used to enhance the usability of the webpage. Every function which is possible through the AJAX, should also be possible in the same or similar way without the AJAX (but usually with an extra page-load or two).</p></blockquote>
<p>This isn&#8217;t just about usabilty, unobtrusiveness, or separation of code though. There are plenty of advantages on starting from the server side and working your way up. Some of my favorites are&#8230;</p>
<ul>
<li><strong>Security:</strong> You can&#8217;t rely on client side validation because it&#8217;s so easy to by pass that even my computer illiterate mother accidentally does it on occasion. HTTP is an open protocol; it&#8217;s stupid to think that well behaved, Javascript-running browsers are the only thing that can get my pages. </li>
<li><strong>Compatibility:</strong> Static HTML makes very few assumptions about the environment it&#8217;s in. It just tells the client of the information it wants to pass along, and lets the client figure out how it wants to render that. This makes it the lowest common denominator for the Web. Javascript, on the other hand, makes a lot of assumptions. Any scripting will only work well in the environment it was written for, while static HTML has a much greater reach.</li>
<li><strong>Transparency:</strong> Static HTML is the closest thing to the true model of the web, while scripting is a higher level layer over it. Focusing primarily on scripting makes it that much easier to miss the right way to do things under the web model, especially for someone for the people that don&#8217;t know what they&#8217;re doing.</li>
<li><strong>Purpose:</strong> Javascript is designed to <em>manipulate bits of document</em>. The fact that it grew into into a full blown UI framework is a mind boggling technological abomination. If you realy want to make a rich, web-based application, why not use something <em>designed</em> for rich UIs, like Flash or Silverlight?</li>
<li><strong>Performance:</strong> Despite all its recent advances, browser scripting performance still doesn&#8217;t hold a candle to desktop applications in terms of speed and responsiveness. Static HTML is still <em>what browsers were designed for</em>, and the features that it supports will always have the best performance. While a static HTML interface might not be as feature rich as a scripted one, its endurance shows that it&#8217;s good enough to be efficient. Being used to the efficiency of static interfaces, the added weight of all of the &#8220;rich&#8221; interfaces makes for an uncomfortably noticeable break in flow.</li>
</ul>
<p>But despite all that, scripting does help address the very real, and always increasing need for rich interfaces on the web. If used right, scripting can have great results for a lot of people.</p>
<p>The <em>real</em> reason why I don&#8217;t like client side scripting is because Javascript, and the way it&#8217;s designed, <strong>doesn&#8217;t make it easy to do anything worthwhile</strong>. Take the fact that it&#8217;s modeled as a low level interface for document manipulation, add the problems that come from browser inconsistencies, top it off with poor debugging and IDE support, and you got yourself a clusterfuck that can be only beaten by the current state of CSS. Every time I pick up Javascript, it&#8217;s a productivity struggle of monumental proportions.</p>
<p>Javascript is like the C++ of web programming: very flexible, but too low level to be adequately productive. So the solution is not to use it at its lowest level, just like I don&#8217;t use Win32 in my apps when I want to get things done. It turns out that there are tons of great libraries that already implement all of those things that you would have to do over and over again in Javascript.</p>
<p>I suppose I should have thought of it before, that maybe a million people have already done this a million times before, and maybe some of those people put it together in a way that takes away the need for me to do for the millionth-first time. I guess I just never saw Javascript as a serious enough language to make &#8220;libraries&#8221; for. Back when I started, Javascript &#8220;libraries&#8221; were the things you copypaste from Javascripts.com to make gay rainbows on your text.</p>
<p>The problem is, every time I tried to research Javascript or AJAX, I always find tons of resources, merrily spewing forth explanations on how to use <code>document.getElementById()</code>, make <code>XMLHttpRequests</code>, or animate things using <code>setTimeout</code> and <code>setInterval</code>, and enumerating the myriads of caveats and their workarounds between browsers. Not once I&#8217;ve seen a site stop, and tell me &#8220;Hey, you! You&#8217;re doing stuff that&#8217;s already been done a million times! Why not just use a library that handles all of this for you?&#8221;</p>
<p>Point in case, I was recently asked to do a small widget that cycles images, <em>&#8220;like the thing on <a href="http://movies.yahoo.com/">Yahoo Movies</a>&#8220;</em>. After several hours of browsing sites that explained in great detail all the pages of code I would have to do, and tons of custom implementations of said code that did almost kinda what I wanted, I came across <a href="http://jquery.com/">JQuery</a>. And it felt like God almighty came down in an angelic choir, and slapped the Truth into my face with a tire iron. I was enlightened.</p>
<p>JQuery delivered an <em>excelent</em> first impression. Having had no previous experience with it whatsoever, it took me 10 minutes, and a grand total of two lines of code to make my animated scroller. It already had everything done for me, starting from a CSS-like element finder syntax, to automatic tweening of any value. I don&#8217;t usually enjoy adding non-standard, external libraries to my code, but this one of those things that really<em> should</em> be standard, and only isn&#8217;t because all the other JS toolkits would cry their eyes out.</p>
<p>It seems Javascript coders suffer a lot from the &#8220;<a href="http://en.wikipedia.org/wiki/Not_Invented_Here">Not Invented Here</a>&#8221; syndrome. Maybe it&#8217;s because you don&#8217;t need anything but a browser to write Javascript. Maybe watching your page come to life after all of that hard work is very satisfying. Maybe they&#8217;re afraid that if someone looks at their code and sees them use a <em>library</em>, they won&#8217;t seem as hardcore. Or maybe someone just needs to clean up the internet of all of the feces that the last generation of Javascripters left behind.</p>
<p>I, however, don&#8217;t have the patience for it. From now on, I&#8217;ll just be dropping JQuery into all of my projects.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sunstormlabs.net/blog/2008/04/29/i-hate-javascript-but-i-love-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
