<?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>chriskarcher.net</title>
	<atom:link href="http://www.chriskarcher.net/feed" rel="self" type="application/rss+xml" />
	<link>http://www.chriskarcher.net</link>
	<description>Test Tagline</description>
	<lastBuildDate>Sat, 22 Oct 2011 20:28:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Trading Faces v1.0 Released</title>
		<link>http://www.chriskarcher.net/2009/05/21/trading-faces-v10-released</link>
		<comments>http://www.chriskarcher.net/2009/05/21/trading-faces-v10-released#comments</comments>
		<pubDate>Fri, 22 May 2009 03:58:56 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.chriskarcher.net/?p=363</guid>
		<description><![CDATA[After dabbling with the iPhone SDK for a few months, I&#8217;ve released my first app &#8211; Trading Faces.  It&#8217;s a simple app that lets you take two faces and mix the different features (e.g. eyes, nose, mouth) together.  Pretty silly, but I bet it&#8217;ll make you laugh! Click this link to check it out in [...]]]></description>
			<content:encoded><![CDATA[<p>After dabbling with the iPhone SDK for a few months, I&#8217;ve released my first app &#8211; <a href="http://www.chriskarcher.net/software/tradingfaces" >Trading Faces</a>.  It&#8217;s a simple app that lets you take two faces and mix the different features (e.g. eyes, nose, mouth) together.  Pretty silly, but I bet it&#8217;ll make you laugh!</p>
<p>Click this link to check it out in the App Store:</p>
<p><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=315396841&amp;mt=8" onclick="javascript:urchinTracker ('/outbound/article/itunes.apple.com');"><img class="alignnone size-full wp-image-350" title="appstore" src="http://www.chriskarcher.net/wp-content/uploads/2009/05/appstore.png" alt="appstore" width="125" height="41" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2009/05/21/trading-faces-v10-released/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>myDesktop v1.3.0 Released</title>
		<link>http://www.chriskarcher.net/2009/04/06/mydesktop-v130-released</link>
		<comments>http://www.chriskarcher.net/2009/04/06/mydesktop-v130-released#comments</comments>
		<pubDate>Tue, 07 Apr 2009 02:38:46 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.chriskarcher.net/2009/04/06/mydesktop-v130-released</guid>
		<description><![CDATA[myDesktop Online v1.3.0 is available for download. Get it here! This update includes many frequently asked for features and a UI refresh. Changelog: Updated required runtime to .NET 2.0 Updated FTP library to v1.3 Many UI updates Added option to keep FTP connection alive or close it after each capture Added option to not upload [...]]]></description>
			<content:encoded><![CDATA[<p>myDesktop Online v1.3.0 is available for download. <a href="http://www.chriskarcher.net/mydesktop" > Get it here!</a> This update includes many frequently asked for features and a UI refresh.</p>
<p>Changelog:</p>
<ul>
<li> Updated required runtime to .NET 2.0</li>
<li> Updated FTP library to v1.3</li>
<li> Many UI updates</li>
<li> Added option to keep FTP connection alive or close it after each capture</li>
<li> Added option to not upload captures (just capture locally)</li>
<li> Added option to archive captures, both locally and remotely on server</li>
<li> Added &#8220;-capture_and_quit&#8221; command line parameter, takes a single capture and then terminates program. Useful for scripting.</li>
<li> Added license</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2009/04/06/mydesktop-v130-released/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to Find the Application Name of a PocketPC CAB Installer</title>
		<link>http://www.chriskarcher.net/2008/07/16/installed-application-name-of-a-compiled-cab</link>
		<comments>http://www.chriskarcher.net/2008/07/16/installed-application-name-of-a-compiled-cab#comments</comments>
		<pubDate>Thu, 17 Jul 2008 03:35:47 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.chriskarcher.net/2008/07/16/installed-application-name-of-a-compiled-cab</guid>
		<description><![CDATA[A while back, I needed to write a program that could manage the installation and uninstallation of programs on the PocketPC\Windows Mobile platform. The program needed to install CAB file X from location Y, note what it had installed from location Y, and then later uninstall it. It had to do this all programatically with [...]]]></description>
			<content:encoded><![CDATA[<p>A while back, I needed to write a program that could manage the installation and uninstallation of programs on the PocketPC\Windows Mobile platform. The program needed to install CAB file X from location Y, note what it had installed from location Y, and then later uninstall it. It had to do this all programatically with no user intervention.</p>
<p><span id="more-317"></span></p>
<p>Installing the program is easy, you simply call <a href="http://msdn.microsoft.com/en-us/library/ms933760.aspx" onclick="javascript:urchinTracker ('/outbound/article/msdn.microsoft.com');">wceload.exe</a> and pass the CAB file path as a command line parameter. Uninstalling is also easy, call unload.exe on PocketPC 2003 or <a href="http://msdn.microsoft.com/en-us/library/aa455977.aspx" onclick="javascript:urchinTracker ('/outbound/article/msdn.microsoft.com');">invoke the Uninstall CSP on Windows Mobile 5</a> with the <strong><em>installed application name </em></strong>(i.e. what shows up under &#8220;Remove Programs&#8221; on the device). However, getting the application&#8217;s name isn&#8217;t trivial and is the point of this article.</p>
<p>On PocketPC 2003, you can find the application&#8217;s name by doing the following:</p>
<ol>
<li>
<div>Install the app via wceload</div>
</li>
<li>
<div>Iterate over the registry keys in &#8220;HKLM\Software\Apps&#8221;</div>
</li>
<li>
<div>Find the key where the CabFile value matches the path you passed to wceload</div>
</li>
<li>
<div>Once you find the key, the application&#8217;s name is the name of the key</div>
</li>
</ol>
<p>However, things aren&#8217;t so easy on Windows Mobile 5. For whatever reason (and I can&#8217;t complain because none of this is documented), the CabFile value is no longer set when the application is installed and the above approach won&#8217;t work. After some digging, I came across the CAB format spec at:</p>
<p><a href="http://support.microsoft.com/kb/310618" onclick="javascript:urchinTracker ('/outbound/article/support.microsoft.com');">http://support.microsoft.com/kb/310618</a></p>
<p>Using that spec, I came up with the following code to dig into the compiled CAB and find the application name. <a href="#download">Jump straight to the example program download if you&#8217;d like.</a></p>
<p>First, declare some variables we&#8217;ll need and open a file stream:</p>
<pre name="code" class="c-sharp">private string GetAppName(string file)
{
	Int16 iFlags;
	Int16 iVersion;
	byte cbCFData;
	Int32 iDataBlockOffset;
	Int16 iProviderLength;
	Int16 iProviderOffset;
	Int16 iAppNameLength;
	Int16 iAppNameOffset;
	byte[] buffer;      

	string strAppName, strProvider;      

	// open the file and create a stream reader
	FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
	BinaryReader br = new BinaryReader(fs);</pre>
<p>The first four bytes of the file should be &#8216;MSCF&#8217;:</p>
<pre name="code" class="c-sharp">
	// make sure this is a CAB
	if (!(fs.ReadByte() == 'M'
		&amp;&amp; fs.ReadByte() == 'S'
		&amp;&amp; fs.ReadByte() == 'C'
		&amp;&amp; fs.ReadByte() == 'F'))
		throw new ArgumentException("File does not have appropriate signature");</pre>
<p>Verify the CAB version is 1.3:</p>
<pre name="code" class="c-sharp">
	// jump to offset 24 to read the format version
	fs.Seek(24, SeekOrigin.Begin);
	iVersion = br.ReadInt16();
	if (iVersion != 0x0103)
		throw new ArgumentException("Invalid CAB format");</pre>
<p>Read the header flags and make sure it&#8217;s a header we can interpret. Depending on the version of CabWiz that was used to create the CAB, the flags will be 0 or 4(cfhdrRESERVE_PRESENT). If the reserve information is present then the cbCFHeader, cbCFFolder, and cbCFData fields are present in the header and we&#8217;ll need to skip them:</p>
<pre name="code" class="c-sharp">
	// jump to offset 30 to read the header flags
	fs.Seek(30, SeekOrigin.Begin);
	iFlags = br.ReadInt16();      

	// we only understand flags 0x0 and 0x4
	if (iFlags == 0)
	{
		// no optional information in this header.
		// jump 4 bytes forward to the beginning of
		// the first CFFOLDER entry
		fs.Seek(4, SeekOrigin.Current);
	}
	else if (iFlags == 4)
	{
		// cbCFHeader, cbCFFolder, and cbCFData fields
		// are present.  We only need to verify that
		// cbCFData is 0, so jump forward 7 bytes and test
		fs.Seek(7, SeekOrigin.Current);      

		cbCFData = (byte)fs.ReadByte();      

		if (cbCFData != 0)
			throw new ArgumentException("Invalid cbCFData");
	}
	else
		throw new ArgumentException("Unsupported header flags");</pre>
<p>After reading the header, we should positioned at the beginning of the first CFFOLDER, where the first field is the offset of the CFDATA block (the .000 file). Read the offset and skip the 8 byte CFDATA header:</p>
<pre name="code" class="c-sharp">
	// we're now pointing to the start of the first
	// CFFOLDER entry.  Read the position of the CFDATA block, skipping past
	// its 8 byte header.
	iDataBlockOffset = br.ReadInt32() + 8;      

	// jump to the data block
	fs.Seek(iDataBlockOffset, SeekOrigin.Begin);</pre>
<p>According to an explanation of the .000 file (<a href="http://www.cabextract.org.uk/wince_cab_format/#000_format" onclick="javascript:urchinTracker ('/outbound/article/www.cabextract.org.uk');">http://www.cabextract.org.uk/wince_cab_format/#000_format</a>), the first 4 bytes of the .000 file should be &#8216;MSCE&#8217;:</p>
<pre name="code" class="c-sharp">
	// we should now be pointing at the ".000" file, whose
	// signature is "MSCE"
	if (!(br.ReadByte() == 'M'
		&amp;&amp; br.ReadByte() == 'S'
		&amp;&amp; br.ReadByte() == 'C'
		&amp;&amp; br.ReadByte() == 'E'))
		throw new ArgumentException("Invalid .000 format");</pre>
<p>84 bytes into the .000 header, we&#8217;ll find the application name length and offset and the provider name length and offset:</p>
<pre name="code" class="c-sharp">
 	// we're looking at a valid .000 file.  We need to look up the
	// AppName and Provider Length/Offsets.  These values start at
	// position 84 in the .000 header, so jump 80 bytes (we're already
	// 4 bytes into the header).
	fs.Seek(80, SeekOrigin.Current);      

	iAppNameOffset = br.ReadInt16();      

	iAppNameLength = br.ReadInt16();      

	iProviderOffset = br.ReadInt16();      

	iProviderLength = br.ReadInt16();</pre>
<p>The final step is to jump to the offsets and read the values:</p>
<pre name="code" class="c-sharp">
	// now jump to the AppName offset and read it
	fs.Seek(iDataBlockOffset + iAppNameOffset, SeekOrigin.Begin);
	// convert from ASCII and don't include the null terminator
	strAppName = ASCIIEncoding.ASCII.GetString(br.ReadBytes(iAppNameLength - 1));      

	// jump and read the Provider string
	fs.Seek(iDataBlockOffset + iProviderOffset, SeekOrigin.Begin);
	// convert from ASCII and don't include the null terminator
	strProvider = ASCIIEncoding.ASCII.GetString(br.ReadBytes(iProviderLength - 1));      

	br.Close();
	fs.Close();      

	return strProvider + " " + strAppName;
}</pre>
<p><a href="http://www.chriskarcher.net/files/GetCabAppName.zip"class="dlimg"  title="Download GetCabAppName.zip" ><img src="http://www.chriskarcher.net/wp-content/plugins/wp-downloadMonitor/img/download.png" alt="Download GetCabAppName.zip" /></a>
				<p class="dlstat">Downloaded a total of 117 times</p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2008/07/16/installed-application-name-of-a-compiled-cab/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>IE7 CSS Bug: Adding &#8216;padding-top&#8217; Value Twice</title>
		<link>http://www.chriskarcher.net/2008/04/02/ie7-css-bug-adding-padding-top-value-twice</link>
		<comments>http://www.chriskarcher.net/2008/04/02/ie7-css-bug-adding-padding-top-value-twice#comments</comments>
		<pubDate>Wed, 02 Apr 2008 14:09:24 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.chriskarcher.net/2008/04/02/ie7-css-bug-adding-padding-top-value-twice</guid>
		<description><![CDATA[I&#8217;ve spent some time at work trying to figure out why a &#60;div&#62; after our menu (where the menu is &#8220;float: left&#8220;) was showing up with more top padding than we were specifying. The extra padding only showed up in Internet Explorer 7: Here is the CSS and HTML that will exhibit the behavior in [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spent some time at work trying to figure out why a <font face="courier new,courier">&lt;div&gt;</font> after our menu (where the menu is &#8220;<font face="courier new,courier">float: left</font>&#8220;) was showing up with more top padding than we were specifying.  The extra padding only showed up in Internet Explorer 7:</p>
<p><img src="http://www.chriskarcher.net/wp-content/uploads/2008/04/padding-screenshot.png" alt="padding-screenshot.png" /></p>
<p><span id="more-314"></span> Here is the CSS and HTML that will exhibit the behavior in IE7:</p>
<p>CSS:</p>
<pre name="code" class="css">body
{
 font-family: Arial, Verdana, Sans-Serif;
 font-size: 100%;
 color: #000;
 background-color: #fff;
}

.bodycontainer
{
 width: 100%;
 font-size: 0.8em;
}

.menu
{
 width: 100%;
 background: #404040;
 float: left;
}

.menu ul
{
 margin: 0;
 padding: 0;
 list-style-type: none;
}

.menu li
{
 margin: 0px;
 padding: 0.25% .5%;
 float: left;
 background: #404040;
 border-style: solid;
 border-width: 0px 1px 0px 0px;
 border-color: #fff;
}

.menu a
{
 font-weight: bold;
 color: #fff;
}

div.clsBreadCrumbTrail
{
 clear:both;
 padding: 10px 5px;
 border-bottom: solid 1px #999;
 border-top: solid 1px #999;
 font-family: Tahoma;
 font-weight: normal;
 text-align: left;
 background-color: #eaeaea;
 color: #000;
}</pre>
<p>HTML:</p>
<pre name="code" class="html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;link rel="stylesheet" type="text/css" href="style.css" /&gt;
&lt;/head&gt;
&lt;body&gt;
 &lt;div id="someid" class="bodycontainer"&gt;
 	&lt;div id="NavMenuPage" class="menu"&gt;
 		&lt;ul id="menuitems"&gt;
 			&lt;li&gt;&lt;a id="foo" href="somelink"&gt;Some Menu Item&lt;/a&gt;&lt;/li&gt;
 		&lt;/ul&gt;
 	&lt;/div&gt;
 	&lt;div id="bct" class="clsBreadCrumbTrail"&gt;
 			&lt;a href="somelnk"&gt;Home&lt;/a&gt; &gt; &lt;span class="clsCurrentPage"&gt;Job Board&lt;/span&gt;
 	&lt;/div&gt;
 &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>It turns out that Internet Explorer 7 has a bug where a <a href="http://www.brunildo.org/test/IEClearPadding.html" onclick="javascript:urchinTracker ('/outbound/article/www.brunildo.org');">float followed by a <font face="courier new,courier">clear</font> that has a <font face="courier new,courier">background</font> specified causes IE7 to add the padding-top value twice</a>.  IE6, Firefox, and Safari all work correctly.</p>
<p>There are several ways to work around this bug and get rid of the extra padding, you&#8217;ll have to see which works best for you:</p>
<ul>
<li>Specify the<font face="courier new,courier"> &lt;div&gt;</font> as<font face="courier new,courier"> &#8220;display: inline-block&#8221; </font>(<a href="http://cafefrenzy.com/css-double-padding-ie7-fix/" onclick="javascript:urchinTracker ('/outbound/article/cafefrenzy.com');">credit</a>)</li>
<li>Nest the <font face="courier new,courier">&lt;div&gt;</font> that specifies a <font face="courier new,courier">background</font> inside a<font face="courier new,courier"> &lt;div&gt;</font> that specifies the <font face="courier new,courier">clear</font></li>
</ul>
<p>I went with the second work-around because although the first worked in IE7, it caused the background to be cut off in Firefox.  You could also use <a href="http://www.google.com/search?source=ig&amp;hl=en&amp;rlz=&amp;q=conditional+comments&amp;btnG=Google+Search" onclick="javascript:urchinTracker ('/outbound/article/www.google.com');">conditional comments</a> to give specific CSS to Internet Explorer 7, but it&#8217;s best to avoid that whenever possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2008/04/02/ie7-css-bug-adding-padding-top-value-twice/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OS X 10.5 Display Sleeper Widget</title>
		<link>http://www.chriskarcher.net/2008/03/26/os-x-105-display-sleeper-widget</link>
		<comments>http://www.chriskarcher.net/2008/03/26/os-x-105-display-sleeper-widget#comments</comments>
		<pubDate>Thu, 27 Mar 2008 05:12:26 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.chriskarcher.net/2008/03/26/os-x-105-display-sleeper-widget</guid>
		<description><![CDATA[Back when I was using Tiger (10.4), I used the Sleep Display widget by Line Street Widgetry to instantly turn off my iMac&#8217;s display, but not sleep the entire machine.  This was a necessity because the iMac doesn&#8217;t have a button to simply turn off the display, and it&#8217;s really annoying to wait for a [...]]]></description>
			<content:encoded><![CDATA[<p>Back when I was using Tiger (10.4), I used the <a href="http://linestreet.googlepages.com/sleepdisplaywidget" onclick="javascript:urchinTracker ('/outbound/article/linestreet.googlepages.com');">Sleep Display widget by Line Street Widgetry</a> to instantly turn off my iMac&#8217;s display, but not sleep the entire machine.  This was a necessity because the iMac doesn&#8217;t have a button to simply turn off the display, and it&#8217;s really annoying to wait for a 10 minute idle timeout when you&#8217;re trying to go to sleep.</p>
<p>Then, I upgraded to Leopard and found that this particular Sleep Display widget no longer worked.  This was a bummer.  I Googled around and found an <a href="http://www.imalc.com/Site/SleepDisplay.html" onclick="javascript:urchinTracker ('/outbound/article/www.imalc.com');">application that did what I wanted</a>, but I really wanted a dashboard widget and this was a great excuse to play with both <a href="http://developer.apple.com/tools/xcode/" onclick="javascript:urchinTracker ('/outbound/article/developer.apple.com');">Xcode</a> and <a href="http://developer.apple.com/tools/dashcode/" onclick="javascript:urchinTracker ('/outbound/article/developer.apple.com');">Dashcode</a> and make it myself.</p>
<p>You can get the new widget at <a href="http://www.chriskarcher.net/software/displaysleeper" >http://www.chriskarcher.net/software/displaysleeper</a>.</p>
<p>p.s. After writing and publishing the widget, I found that you can easily sleep the display in Leopard by pressing Ctrl-Shift-Eject</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2008/03/26/os-x-105-display-sleeper-widget/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hiding the Progress Bar of a .NET 2.0 CF WebBrowser</title>
		<link>http://www.chriskarcher.net/2008/01/26/hiding-the-progress-bar-of-a-net-20-cf-webbrowser</link>
		<comments>http://www.chriskarcher.net/2008/01/26/hiding-the-progress-bar-of-a-net-20-cf-webbrowser#comments</comments>
		<pubDate>Sat, 26 Jan 2008 20:17:15 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[webbrowser]]></category>
		<category><![CDATA[windows mobile]]></category>

		<guid isPermaLink="false">http://www.chriskarcher.net/2008/01/26/hiding-the-progress-bar-of-a-net-20-cf-webbrowser</guid>
		<description><![CDATA[One of the nice additions to the .NET 2.0 Compact Framework is the WebBrowser control. This control has always been present in the full framework, but to implement a web browser on the PocketPC you would have had to either write your own managed wrapper or use an existing one such as OpenNETCF&#8217;s HTMLViewer. But [...]]]></description>
			<content:encoded><![CDATA[<p>One of the nice additions to the .NET 2.0 Compact Framework is the WebBrowser control. This control has <a href="http://msdn2.microsoft.com/en-us/library/system.windows.forms.webbrowser.aspx" onclick="javascript:urchinTracker ('/outbound/article/msdn2.microsoft.com');">always been present in the full framework</a>, but to implement a web browser on the PocketPC you would have had to either write your own managed wrapper or use an existing one such as OpenNETCF&#8217;s HTMLViewer. But now that it&#8217;s included in the CF, we should give it a try. Many developers, myself included, use an embedded browser control to display rich, custom formatted content in their .NET apps. You can do this with the WebBrowser class by generating the HTML and setting the DocumentText property on the control. However, the new managed WebBrowser has a major drawback: Everytime you set the DocumentText property it shows a progress bar while loading the content into the browser. As far as I can tell, this behavior is only on Windows Mobile 5 devices, not on PocketPC 2003. Read on to figure out how to disable this behavior.</p>
<p><span id="more-302"></span></p>
<p>So, here&#8217;s what it looks like:</p>
<p><img src="http://www.chriskarcher.net/wp-content/uploads/2008/01/progressbar.png" alt="progressbar.png" /></p>
<p>At first glance, it doesn&#8217;t look intrusive. But when you start updating the HTML regularly and the progress bar pops up <em>every</em> time, it starts to look out of place. It would be nice if MS just exposed an option to disable it, but they don&#8217;t. We&#8217;re going to have to do some work ourselves to get rid of it.</p>
<p>First, some background. In my application, I created a UserControl named WebBrowserPanel. WebBrowserPanel has a single WebBrowser child control which is anchored Top, Right, Bottom, and Left. It has the following constuctor to make it use all the available space:</p>
<pre name="code" class="c-sharp">
public WebBrowserPanel()
{
    InitializeComponent();       

    WebBrowser.Width = this.Width - 2;
    WebBrowser.Height = this.Height;
}</pre>
<p>Putting the WebBrowser inside a user control lets us give it a border and, as you&#8217;ll see later, will be crucial for this fix to work.</p>
<p>Using the Remote Spy tool that ships with VS 2005, we can examine the window structure of the application on the Windows Mobile 5 emulator:</p>
<p><img src="http://www.chriskarcher.net/wp-content/uploads/2008/01/handles.png" alt="handles.png" /></p>
<p>The &#8220;MSPIE Status&#8221; window, a child of the &#8220;IExplore&#8221; window, looks interesting. Inspecting its properties shows us that it&#8217;s 23 pixels tall, and likely the progress bar we&#8217;re looking to hide. If we can get our hands on its window handle we can try to move, resize, or manipulate it in some other way to hide it. To get its window handle, I wrote the following function:</p>
<pre name="code" class="c-sharp">
public static IntPtr FindHwndByClass(string strClass, IntPtr parentHwnd)
{
    StringBuilder sbClass = new StringBuilder(256);
    if (0 != GetClassName(parentHwnd, sbClass, sbClass.Capacity) &amp;&amp; sbClass.ToString() == strClass)
        return parentHwnd;       

    IntPtr hwndChild = GetWindow(parentHwnd, (int)GetWindowFlags.GW_CHILD);
    while (hwndChild != IntPtr.Zero)
    {
        IntPtr result = FindHwndByClass(strClass, hwndChild);
        if (result != IntPtr.Zero)
            return result;       

        hwndChild = GetWindow(hwndChild, (int)GetWindowFlags.GW_HWNDNEXT);
    }       

    return IntPtr.Zero;
}</pre>
<p>We can pass in &#8220;MSPIE Status&#8221; as the class name and look for it as a child of the WebBrowser.</p>
<p>Now that we have the handle, we can try to hide it. My initial attempts to hide the progress bar included using <a href="http://msdn2.microsoft.com/en-us/library/ms633545.aspx" onclick="javascript:urchinTracker ('/outbound/article/msdn2.microsoft.com');">SetWindowPos</a> to move the bar off the screen, resize it to one pixel high, and a number of other hacks that didn&#8217;t work. As a last resort, I tried the ultimate: <a href="http://msdn2.microsoft.com/en-us/library/ms632682.aspx" onclick="javascript:urchinTracker ('/outbound/article/msdn2.microsoft.com');">DestroyWindow</a>. After initializing the WebBrowser in WebBrowserPanel&#8217;s constructor, I would find the status bar window and destroy it. This seemed to work, kind of. As you can see below, there are about 20 pixels of whitespace at the bottom of the browser, noticeable when you have enough content to need scrollbars:</p>
<p><img src="http://www.chriskarcher.net/wp-content/uploads/2008/01/whitespace.png" alt="whitespace.png" /></p>
<p>Not good, but easy enough to work around. After we get the progress bar handle we can get its window height. After we destroy the window, we can resize the WebBrowser to be this much taller than its parent panel, thus clipping off this whitespace.  WebBrowserPanel&#8217;s constructor now looks like:</p>
<pre name="code" class="c-sharp">
public WebBrowserPanel()
{
    InitializeComponent();

    WebBrowser.Width = this.Width - 2;
    WebBrowser.Height = this.Height;

    IntPtr hwndStatus = FindHwndByClass("MSPIE Status", WebBrowser.Handle);
    if (hwndStatus != IntPtr.Zero)
    {
        RECT rectStatus = new RECT();
        GetClientRect(hwndStatus, out rectStatus);

        DestroyWindow(hwndStatus);

        WebBrowser.Height += rectStatus.Height;
    }
}</pre>
<p>And we end up with:</p>
<p><img src="http://www.chriskarcher.net/wp-content/uploads/2008/01/final.png" alt="final.png" /></p>
<p>Success! You can now set the DocumentText any number of times without the progress bar showing up.</p>
<p>The code presented above makes use of the following PInvokes and enums:</p>
<pre name="code" class="c-sharp">
[DllImport("coredll.dll")]
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

[DllImport("coredll.dll")]
public static extern IntPtr GetWindow(IntPtr hwnd, int cmd);

public enum GetWindowFlags : int
{
    GW_HWNDFIRST = 0,
    GW_HWNDLAST = 1,
    GW_HWNDNEXT = 2,
    GW_HWNDPREV = 3,
    GW_OWNER = 4,
    GW_CHILD = 5,
    GW_MAX = 5
}

[DllImport("coredll.dll")]
public static extern bool DestroyWindow(IntPtr hwnd);

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int X;
    public int Y;
    public int Width;
    public int Height;
}

[DllImport("coredll.dll")]
static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);</pre>
<p><a href="http://www.chriskarcher.net/files/WebBrowserDemo.zip"class="dlimg"  title="Download Web Browser Demo" ><img src="http://www.chriskarcher.net/wp-content/plugins/wp-downloadMonitor/img/download.png" alt="Download Web Browser Demo" /></a>
				<p class="dlstat">Downloaded a total of 525 times</p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2008/01/26/hiding-the-progress-bar-of-a-net-20-cf-webbrowser/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>The Last Day</title>
		<link>http://www.chriskarcher.net/2006/12/22/the-last-day</link>
		<comments>http://www.chriskarcher.net/2006/12/22/the-last-day#comments</comments>
		<pubDate>Fri, 22 Dec 2006 11:12:18 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://development.chriskarcher.net/?p=147</guid>
		<description><![CDATA[Our last day is over. Today was the Sex and the City tour, then some shopping, then Beauty and the Beast Broadway show. We&#8217;ve got to get up awful early tomorrow morning to make our flight, so I&#8217;m just going to say the day was fun and leave it at that. A lot of the [...]]]></description>
			<content:encoded><![CDATA[<p>Our last day is over.  Today was the Sex and the City tour, then some shopping, then Beauty and the Beast Broadway show.  We&#8217;ve got to get up awful early tomorrow morning to make our flight, so I&#8217;m just going to say the day was fun and leave it at that.</p>
<p>A lot of the pictures from today are Sex and the City filming locations.  Don&#8217;t be surprised if you don&#8217;t recognize any of them  <img style="border: none;" alt="smile" src="http://www.chriskarcher.net/cutenews/data/emoticons/smile.gif" />.</p>
<p><a href="http://www.chriskarcher.net/photos/thumbnails.php?album=6" >http://www.chriskarcher.net/photos/thumbnails.php?album=6</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2006/12/22/the-last-day/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Day 3</title>
		<link>http://www.chriskarcher.net/2006/12/21/day-3</link>
		<comments>http://www.chriskarcher.net/2006/12/21/day-3#comments</comments>
		<pubDate>Thu, 21 Dec 2006 11:57:29 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://development.chriskarcher.net/?p=148</guid>
		<description><![CDATA[Wow. I just lost an entire post about today thanks to my ignorance of Mac OS X keyboard shortcuts. Here&#8217;s the abbreviated version: Ellis Island/Statue of Liberty:Very cool. Got some good pictures but Denicia&#8217;s battery started dying so we had to slow down on the picture taking. Ground Zero: If you&#8217;re ever in New York, [...]]]></description>
			<content:encoded><![CDATA[<p>Wow.  I just lost an entire post about today thanks to my ignorance of Mac OS X keyboard shortcuts.  Here&#8217;s the abbreviated version:</p>
<p><span style="text-decoration: underline;">Ellis Island/Statue of Liberty:</span><br />Very cool.  Got some good pictures but Denicia&#8217;s battery started dying so we had to slow down on the picture taking.</p>
<p><span style="text-decoration: underline;">Ground Zero:</span> <br />If you&#8217;re ever in New York, it would be a crime not to visit here.</p>
<p> <span style="text-decoration: underline;">Daily Show:</span><br />Didn&#8217;t actually end up waiting in line for this.  We made it all the way to the studio but got the impression that waiting in the &#8220;standby&#8221; line would be a waste of our time.  Instead, we decided to go see a broadway show. <img style="border: none;" alt="wassat" src="http://www.chriskarcher.net/cutenews/data/emoticons/wassat.gif" /></p>
<p><span style="text-decoration: underline;">Letterman Show:</span> <br />Saved! Fate intervened and on our way to buy Broadway tickets we heard a Letterman show employee advertising free tickets.  I had tried to get these earlier online but knew they were near impossible to get.  I guessed on the trivia question they use for screening and actually got it right!  Some higher power really wanted us to see Letterman instead of Broadway.  The guests on the show weren&#8217;t that great (Rene Zelwegger, some toy lady, and Taking Back Sunday), but the experience was once in a lifetime.</p>
<p>Pictures at <a href="http://chriskarcher.net/photos/thumbnails.php?album=5" >http://chriskarcher.net/photos/thumbnails.php?album=5</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2006/12/21/day-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Day 2</title>
		<link>http://www.chriskarcher.net/2006/12/20/day-2</link>
		<comments>http://www.chriskarcher.net/2006/12/20/day-2#comments</comments>
		<pubDate>Wed, 20 Dec 2006 11:55:55 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://development.chriskarcher.net/?p=149</guid>
		<description><![CDATA[Another exhausting day but several more things checked off our TODO list. We woke up this morning and had breakfast at a hole-in-the-wall place named Olympic Diner, where we enjoyed a greasy NY chicken panini with some cheese sticks. Not your typical healthy breakfast but hey, we&#8217;re on vacation!. After that we toured Central Park, [...]]]></description>
			<content:encoded><![CDATA[<p>Another exhausting day but several more things checked off our TODO list.  We woke up this morning and had breakfast at a hole-in-the-wall place named Olympic Diner, where we enjoyed a greasy NY chicken panini with some cheese sticks.  Not your typical healthy breakfast but hey, we&#8217;re on vacation!.  After that we toured Central Park, browsed through the Metropolitan Museum of Art, saw Blue Man Group, and then topped it off with a trip to the Empire State Building.  Quite a busy day!  </p>
<p>Tomorrow we planning to hoof it out to Ellis Island and then try to get in on the taping of the Daily Show.  It&#8217;s very likely we won&#8217;t get into the Daily Show taping, so we&#8217;ve got Broadway planned as a backup.  (All prayers for us to get into the Daily Show are greatly appreciated).</p>
<p>We took a lot of pictures today and they&#8217;re going to take a decent time to upload, so I&#8217;ve kicked off the process and will finish adding them to an album in the morning.</p>
<p> <strong>UPDATE:</strong> Pictures available at: <a href="http://chriskarcher.net/photos/thumbnails.php?album=4" >http://chriskarcher.net/photos/thumbnails.php?album=4</a></p>
<p>Notable Central Park pictures include the fountain from the opening scenes in Friends, Celine Dion&#8217;s Loft, and the building that houses Jerry Seinfeld&#8217;s Porsche collection of 60 some-odd Porsches.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2006/12/20/day-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Day 1!!!</title>
		<link>http://www.chriskarcher.net/2006/12/19/day-1</link>
		<comments>http://www.chriskarcher.net/2006/12/19/day-1#comments</comments>
		<pubDate>Tue, 19 Dec 2006 12:38:39 +0000</pubDate>
		<dc:creator>chris</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://development.chriskarcher.net/?p=150</guid>
		<description><![CDATA[We&#8217;re exhausted, so this will be short and sweet . We traveled all day, arrived around 4PM, and then hit NY hard. Once we got checked in at our hotel we went exploring and saw all sorts of neat stuff. Just like Las Vegas, New York is as cool as it look on TV. We [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re exhausted, so this will be short and sweet  <img style="border: none;" alt="smile" src="http://www.chriskarcher.net/cutenews/data/emoticons/smile.gif" />.</p>
<p>We traveled all day, arrived around 4PM, and then hit NY hard.  Once we got checked in at our hotel we went exploring and saw all sorts of neat stuff.  Just like Las Vegas, New York is as cool as it look on TV.  We got pictures of billboards, tall buildings, and even a live newscast.  Our first major location stop was Rockefeller Center because it&#8217;s only a 5 minute walk from our hotel.  The Christmas tree was amazing!  We walked around for a bit and then went ice skating after eating some authentic NY pizza.  Funny thing, while we were waiting in line to skate we met 6 different people all from Austin.  Either it&#8217;s a small world, or a lot of Texans want to get somewhere cold for Christmas.</p>
<p>Tomorrow, we&#8217;re going to hit up Central Park during the day and Blue Man Group at night.  If we have time, we might go check out the Empire State Building as well.</p>
<p>As promised, here are some pictures:<br /><a href="http://www.chriskarcher.net/photos/thumbnails.php?album=3" >http://www.chriskarcher.net/photos/thumbnails.php?album=3</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chriskarcher.net/2006/12/19/day-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

