<?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>Sam @ Xnet</title>
	<atom:link href="http://sam.xnet.tk/feed/" rel="self" type="application/rss+xml" />
	<link>http://sam.xnet.tk</link>
	<description></description>
	<lastBuildDate>Thu, 26 Jan 2012 22:41:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Creating a RAID array</title>
		<link>http://sam.xnet.tk/2012/01/creating-a-raid-array/</link>
		<comments>http://sam.xnet.tk/2012/01/creating-a-raid-array/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 22:41:27 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[Servers]]></category>

		<guid isPermaLink="false">http://sam.xnet.tk/?p=104</guid>
		<description><![CDATA[Specifically a soft Raid 1 array on ubuntu 11.10. This guide is not for raiding your boot/main drive, but rather an extra &#8216;data&#8217; array. First thing you will need is a computer/server with 2+ drives (that you don&#8217;t mind loosing the data on), the Raid mirror will end up being … <a href="http://sam.xnet.tk/2012/01/creating-a-raid-array/"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>Specifically a soft Raid 1 array on ubuntu 11.10. This guide is not for raiding your boot/main drive, but rather an extra &#8216;data&#8217; array.</p>
<p>First thing you will need is a computer/server with 2+ drives (that you don&#8217;t mind loosing the data on), the Raid mirror will end up being the smallest of the two. You may use/mix advanced format 4KB drives, but I&#8217;ll get to that later.<br />
<span id="more-104"></span></p>
<p>A note before you begin, initialising a new array will take along time (6 hours for a 2TB array of 2 drives, minimum), so plan to leave your server alone while it does that.</p>
<p>Firstly install mdadm</p>
<pre>sudo aptitude install mdadm</pre>
<p>You will then be able to <code>cat /proc/mdstat</code> to verify its working</p>
<p>Next up is to find and prepare your drives. You can use <code>ls /dev/sd*</code> or <code>lsblk </code>to get the list of current drives. In my case this was <code>/dev/sdb</code> and <code>/dev/sdc</code>.</p>
<h3>Partitioning</h3>
<p><code>mdadm</code> uses partitions of type &#8216;Linux RAID Autodetect&#8217; to build array from, so we now need to create these partitions on our drives. For examples sake we&#8217;ll use fdisk here.</p>
<p><code>sudo fdisk /dev/sdb</code></p>
<p>If you have any existing partitions (use <code>p</code> to list) clear them with <code>o</code>.</p>
<p>Then create the new partition with <code>n</code>, use the defaults to create the maximum size.</p>
<p>Set the type with <code>t</code> and set it to &#8216;fd&#8217; which is &#8216;Linux RAID Autodetect&#8217; (formatting the new partition is not neccessary at this point).</p>
<p>Finally use <code>w</code> to write the changes to disk and <code>q</code> to exit.</p>
<p>Rinse and repeat for the other drive.</p>
<p><strong>Advanced Format: </strong>You can spot advanced format drives by printing the list of partitions a checking the physical sector size, Eg. an AF drive:<br />
<code>Sector size (logical/physical): 512 bytes / 4096 bytes</code><br />
And a non-AF drive:<br />
<code>Sector size (logical/physical): 512 bytes / 512 bytes</code><br />
In the above case fdisk will warn you about the logical sector size not matching the physical size when you run it, but fear not, its fine.</p>
<h3><strong>Creating</strong></h3>
<p>If you are mixing AF drives and non-AF drives put the AF drives first in the list when creating the array, this will cause mdadm to use 4KB sector sizes rather than 512B, in my setup /dev/sdc is the AF drive.</p>
<p>Create the array with</p>
<pre>sudo mdadm --create /dev/md0 --level=1 --raid-disks=2 /dev/sdc /dev/sdb</pre>
<p>You may name it something other than <code>md0</code>, although it is good practice to use <code>mdX</code> where <code>X</code> is a number.</p>
<p>Doing a cat <code>/proc/mdstat</code> will show something like</p>
<pre>Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 sdb1[1] sdc1[0]
      1953512400 blocks super 1.2 [2/2] [UU]
      [&gt;.............] resync = 0.1% (65245/1953512400) finish=612.2min speed=65748K/sec

unused devices: &lt;none&gt;</pre>
<p>Now&#8217;s the best time to leave it overnight to finish setting it up. Since I did notice the speed drop to almost nothing when mounted. You may format the drive now (to check that it doesn&#8217;t throw any warnings, see the next section).</p>
<p>[...Some time later...]</p>
<pre>Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 sdb1[1] sdc1[0]
      1953512400 blocks super 1.2 [2/2] [UU]

unused devices: &lt;none&gt;</pre>
<p>Done and ready to use</p>
<h3>Formatting and using</h3>
<p>We&#8217;ll use ext4 here, but feel free to use your favourite.</p>
<pre>sudo mkfs.ext4 /dev/md0</pre>
<p>That should give no warnings, however if it does complain about the offset you could try and stop the array (<code>mdadm --stop /dev/md0</code>) and create the partitions again but set the display to sectors (with u twice) and create the partitions with the first sector being 2048.</p>
<p>Now for mounting, add the following line to <code>/etc/fstab</code> and create the directory <code>/mnt/data</code> (or use any other location)</p>
<pre>/dev/md0  /mnt/data  ext4  errors=remount-ro  0  2</pre>
<p>And mount</p>
<pre>mount /mnt/data</pre>
<p>Done.</p>
<p>Double-check with <code>df -h</code></p>
<pre>Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/root      228G  6.7G  210G   4% /
udev                  868M  8.0K  868M   1% /dev
tmpfs                 351M  1.2M  350M   1% /run
none                  5.0M     0  5.0M   0% /run/lock
none                  877M     0  877M   0% /run/shm
/dev/sda1             228M   67M  149M  32% /boot
/dev/md0              1.8T  319G  1.4T  19% /mnt/data</pre>
<p>I hope this helps, but let me know if you ran into any problems and if you got around it so I can update this for the next person going Raid.</p>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2012/01/creating-a-raid-array/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New programming slang</title>
		<link>http://sam.xnet.tk/2012/01/new-programming-slang/</link>
		<comments>http://sam.xnet.tk/2012/01/new-programming-slang/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 10:58:00 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://eris.xnet.tk/samxnet/?p=4</guid>
		<description><![CDATA[Source Linky Some of my favourites: Heisenbug It is an error, which disappears or alters when it is attempted to be identified by analogy to Heisenberg uncertainty principle in quantum physics. Reality 101 failure The program (or more likely feature of a program) does exactly what was asked for, but … <a href="http://sam.xnet.tk/2012/01/new-programming-slang/"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p><strong><a href="http://umumble.com/blogs/Programming/321/" target="_new">Source Linky</a></strong></p>
<p>Some of my favourites:</p>
<p><strong>Heisenbug</strong><br />
It is an error, which disappears or alters when it is attempted to be identified by analogy to Heisenberg uncertainty principle in quantum physics.</p>
<p><strong>Reality 101 failure</strong><br />
The program (or more likely feature of a program) does exactly what was asked for, but when it&#8217;s deployed it turns out that the problem was misunderstood and the program is basically useless.</p>
<p><strong>Protoduction</strong><br />
This is a prototype that ends up in production.</p>
<p><strong>Megamoth</strong><br />
MEGA MOnolithic meTHod. Usually, it stretches over two screens in height and often contained inside aGod Object (an object that knows or does too much). Megamoths of greater size than 2k LOC have been sighted. Beware of the megamoth!</p>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2012/01/new-programming-slang/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Htaccess rule creator for new to old urls</title>
		<link>http://sam.xnet.tk/2011/06/htaccess-rule-creator-for-new-to-old-urls/</link>
		<comments>http://sam.xnet.tk/2011/06/htaccess-rule-creator-for-new-to-old-urls/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 17:26:00 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[Servers]]></category>

		<guid isPermaLink="false">http://eris.xnet.tk/samxnet/?p=5</guid>
		<description><![CDATA[Here is a tool to create redirection rules, primarily for rewriting pages based on a query string to a nice seo url. Created because .htaccess files are the easiest way to break an entire site. http://www.xnet.tk/CreateRule.php Example: Old Url: http://www.xnet.tk/index.php?page=123&#38;something=else New Url: http://www.xnet.tk/htaccess/rules/ The generated rule would be: RewriteCond %{QUERY_STRING} … <a href="http://sam.xnet.tk/2011/06/htaccess-rule-creator-for-new-to-old-urls/"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>Here is a tool to create redirection rules, primarily for rewriting pages based on a query string to a nice seo url.<br />
Created because .htaccess files are the easiest way to break an entire site.</p>
<p><a href="http://www.xnet.tk/CreateRule.php" target="_blank">http://www.xnet.tk/CreateRule.php</a></p>
<p>Example:<br />
Old Url: http://www.xnet.tk/index.php?page=123&amp;something=else<br />
New Url: http://www.xnet.tk/htaccess/rules/</p>
<p>The generated rule would be:</p>
<pre>RewriteCond %{QUERY_STRING} ^page=123&amp;something=else$
RewriteRule .*  htaccess/rules/? [R=301,L]</pre>
<p>It can&#8217;t handle crossing domains (yet).</p>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2011/06/htaccess-rule-creator-for-new-to-old-urls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easy php output compression</title>
		<link>http://sam.xnet.tk/2011/06/easy-php-output-compression/</link>
		<comments>http://sam.xnet.tk/2011/06/easy-php-output-compression/#comments</comments>
		<pubDate>Sat, 11 Jun 2011 12:22:00 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://eris.xnet.tk/samxnet/?p=6</guid>
		<description><![CDATA[Below is what I regard as a reliable method of doing gzip output compression. One thing that normally breaks gzip compression is something printing/echoing before the ob_start (usually the result of an error, debug output, errant space somewhere etc&#8230;), this is where the ob_get_length and ob_flush come in. The problem … <a href="http://sam.xnet.tk/2011/06/easy-php-output-compression/"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>Below is what I regard as a reliable method of doing gzip output compression.</p>
<p>One thing that normally breaks gzip compression is something printing/echoing before the ob_start (usually the result of an error, debug output, errant space somewhere etc&#8230;), this is where the ob_get_length and ob_flush come in.</p>
<p>The problem is that headers_sent is not a reliable way to tell if any thing has been output because it may still be in the output buffer, so if we flush it before hand problem solved.</p>
<pre>&lt;?php

function doPage()
{
   echo 'Hello World';
}

if (ob_get_length() &gt; 0)
   @ob_flush();

if (!headers_sent() &amp;&amp; @ob_start("ob_gzhandler"))
{
   doPage();
   ob_end_flush();
   //Probably a good idea to exit here as more output would break it
   exit;
}
else
{
   doPage();
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2011/06/easy-php-output-compression/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Look</title>
		<link>http://sam.xnet.tk/2011/05/new-look/</link>
		<comments>http://sam.xnet.tk/2011/05/new-look/#comments</comments>
		<pubDate>Mon, 02 May 2011 19:17:00 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[Blah]]></category>

		<guid isPermaLink="false">http://eris.xnet.tk/samxnet/?p=7</guid>
		<description><![CDATA[Updated with a more modern feel (although only for non-ie users). Playing around with opacity which seems to work well]]></description>
			<content:encoded><![CDATA[<p>Updated with a more modern feel (although only for non-ie users).</p>
<p>Playing around with opacity which seems to work well <img src='http://cf.sam.xnet.tk/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2011/05/new-look/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>lighttpd, php and clean urls</title>
		<link>http://sam.xnet.tk/2010/11/lighttpd-php-and-clean-urls/</link>
		<comments>http://sam.xnet.tk/2010/11/lighttpd-php-and-clean-urls/#comments</comments>
		<pubDate>Wed, 17 Nov 2010 23:33:00 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[Servers]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://eris.xnet.tk/samxnet/?p=8</guid>
		<description><![CDATA[Here&#8217;s a situation, You have php running on a lighttpd server via fastcgi and you want clean urls (ie. /post/123/postname). The typical way to-do this with lighttpd is to set the error-handler to your script. $HTTP["host"] == "my.com" { server.document-root = "/var/www/my.com" server.error-handler-404 = "/index.php" } We use an error-handler … <a href="http://sam.xnet.tk/2010/11/lighttpd-php-and-clean-urls/"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a situation, You have php running on a <a title="" href="http://www.lighttpd.net/">lighttpd</a> server via <a title="" href="http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModFastCGI#FastCGI-and-Programming-Languages">fastcgi</a> and you want clean urls (ie. /post/123/postname).</p>
<p>The typical way to-do this with lighttpd is to set the error-handler to your script.</p>
<pre>$HTTP["host"] == "my.com" {
    server.document-root = "/var/www/my.com"
    server.error-handler-404 = "/index.php"
}</pre>
<p>We use an error-handler here rather than rewriting the url as with apache because there&#8217;s no way to detect if the url is actually a file (ie. your css/js files).</p>
<p>Problem here is that this will break query strings for anything other than the root url (query strings are what&#8217;s after the ?). ie. when accessing /post/123/postname/?confirm=true the confirm will not appear in the $_GET or $_REQUEST arrays while /?confirm=true will.</p>
<p>So how do we fix this? The method I&#8217;ve used is to manually parse the query string and put its values into the get and request arrays, as below.</p>
<pre>function fix_query_string()
{
    $url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    $query = parse_url($url,PHP_URL_QUERY);
    if ($query == False || empty($query))
        return;
    $_SERVER['QUERY_STRING'] = $query;
    parse_str($query,$query);
    foreach($query as $key=&gt;$value)
    {
        $_GET[$key] = $_REQUEST[$key] = $value;
    }
}
if (stripos($_SERVER['SERVER_SOFTWARE'], 'lighttpd') !== false)
    fix_query_string();</pre>
<p>Hope this helps!</p>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2010/11/lighttpd-php-and-clean-urls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Threaded flicker-free control rendering in c#</title>
		<link>http://sam.xnet.tk/2010/10/threaded-flicker-free-control-rendering-in-c/</link>
		<comments>http://sam.xnet.tk/2010/10/threaded-flicker-free-control-rendering-in-c/#comments</comments>
		<pubDate>Tue, 19 Oct 2010 15:56:00 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://eris.xnet.tk/samxnet/?p=9</guid>
		<description><![CDATA[I recently ran into a problem where a control was rendering slow enough that it caused flickering (as the screen region is cleared and then redrawn). Looking around the &#8216;net I settled on rendering the control to a bitmap and then drawing the bitmap to the screen (fast operation), which … <a href="http://sam.xnet.tk/2010/10/threaded-flicker-free-control-rendering-in-c/"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>I recently ran into a problem where a control was rendering slow enough that it caused flickering (as the screen region is cleared and then redrawn).</p>
<p>Looking around the &#8216;net I settled on rendering the control to a bitmap and then drawing the bitmap to the screen (fast operation), which is called <a title="" href="http://en.wikipedia.org/wiki/Multiple_buffering">double buffering</a>.<br />
<span id="more-9"></span><br />
For example.</p>
<pre>//In the OnPaint function or every time you redraw the control
Bitmap offscreenBitMap = new Bitmap(this.Width, this.Height);
Graphics offscreenGraphics = Graphics.FromImage(offscreenBitMap);
g.Clear(this.BackColor);

//Drawing code with offscreenGraphics

offscreenGraphics.Dispose();

//Draw bitmap to screen
Graphics clientDC = this.CreateGraphics();
clientDC.DrawImage(offscreenBitMap , 0, 0);</pre>
<p>The above should be sufficient for most people, but read on if you redraw the control many times a second.</p>
<p>While this solved the flickering problem another problem promptly appeared (don&#8217;t they always).</p>
<p>Because the control was being redrawn about 10-15 times a second, it was causing the application to &#8220;stutter&#8221;, as in not respond for the milliseconds when the control was being drawn (i.e. dragging the window around wouldn&#8217;t be smooth).</p>
<p>So putting the render code in its own thread seemed like a good idea. Problem now is how to synchronise/communicate the need to re-render the control when needed.</p>
<p>My solution was to use an object lock and <a title="" href="http://msdn.microsoft.com/en-us/library/system.threading.monitor%28VS.71%29.aspx">Monitor</a>.</p>
<p><strong>Method of operation</strong></p>
<ol>
<li>Application thread locks object</li>
<li>Render thread attempts to lock object (waits for application thread to release object)</li>
<li>When redraw is needed, release object</li>
<li>Render thread acquires object lock</li>
<li>Control is drawn to bitmap</li>
<li>Render thread releases object</li>
<li>Application thread is invoked to post the redraw</li>
<li>Goto 1</li>
</ol>
<p>One thing to note is that this threaded model shouldn&#8217;t be used in design mode, as it may cause Visual Studio to hang.</p>
<p>Another is that calls to redraw the control should be ignored if its already rendering from another call.</p>
<p>Download <a title="" href="http://cf.sam.xnet.tk/wp-content/uploads/ThreadedRendererProject.zip">[Project]</a> <a title="" href="http://cf.sam.xnet.tk/wp-content/uploads/ThreadedRendererControl.cs">[Code File]</a></p>
<pre>[..using..]
using System.Threading;

public partial class ThreadedRendererControl : Control
{
    Thread renderThread;
    object renderControl = new object();
    private bool currentlyDrawing = false;
    private object dataLock = new object();

    public ThreadedRendererControl()
    {
        InitializeComponent();

        Monitor.Enter(renderControl);

        if (!DesignMode) //No point threading in design mode (in IDE)
        {
            renderThread = new Thread(new ThreadStart(Renderer));
            Disposed += new EventHandler(ThreadedRendererControl_Disposed);
        }
        Resize += new EventHandler(this.ThreadedRendererControl_Resize);
    }

    void ThreadedRendererControl_Disposed(object sender, EventArgs e)
    {
        renderThread.Abort();
    }
    public void UpdateData()
    {
        lock (dataLock)
        {
            //Update any data here that is used by the renderer
        }
    }
    public void Redraw()
    {
        if (DesignMode)//Just draw component in design mode
        {
            this.Invalidate(); //this will call OnPaint
            return;
        }
        //Only start the render thread on the first redraw
        if (renderThread.ThreadState == ThreadState.Unstarted)
            renderThread.Start();
        //Prevent multiple attempts to draw before current request has finished
        lock (dataLock)
        {
            if (currentlyDrawing == false)
                currentlyDrawing = true;
            else
                return;
        }
        //Allow the render thread to aquire the lock
        Monitor.Exit(renderControl);
    }
    private void Renderer()
    {
        while (true)
        {
            Bitmap bmp;
            Monitor.Enter(renderControl);
            lock (dataLock) //prevent data from being changed during rendering
            {
                bmp = Draw();
            }
            //Release lock
            Monitor.Exit(renderControl);

            //If the form is currently loading (not yet displayed)
            //posting the redraw will crash the app, as there's nothing to draw to
            if (IsHandleCreated)
                //Synchronously invoke the PostRedraw, this will also lock the renderControl object
                this.Invoke(new Action(PostRedraw), new object[] { bmp });
            else
                Thread.Sleep(10); //Wait, and loop again
        }
    }
    private void PostRedraw(Bitmap bmp)
    {
        Monitor.Enter(renderControl);
        lock (dataLock) currentlyDrawing = false;
        //Draw the bitmap
        Graphics clientDC = this.CreateGraphics();
        clientDC.DrawImage(bmp, 0, 0);
    }
    private Bitmap Draw()
    {
        Bitmap offscreenBitMap = new Bitmap(this.Width, this.Height);
        Graphics offscreenGraphics = Graphics.FromImage(offscreenBitMap);
        offscreenGraphics.Clear(this.BackColor);

        Font labelFont = this.Font;

        offscreenGraphics.DrawString("I was drawn in another thread!", labelFont, Brushes.Black, 0, 0);

        offscreenGraphics.Dispose();
        return offscreenBitMap;
    }
    protected override void OnPaint(PaintEventArgs pe)
    {
        if (DesignMode)
        {
            Graphics clientDC = this.CreateGraphics();
            clientDC.DrawImage(Draw(), 0, 0);
        }
        else
            Redraw();
    }

    private void ThreadedRendererControl_Resize(object sender, EventArgs e)
    {
        Redraw();
    }
}</pre>
<p>In hindsight maybe I should of just found a way to draw it faster rather than use threading. Regardless, I hope you found this useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2010/10/threaded-flicker-free-control-rendering-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Text block clock</title>
		<link>http://sam.xnet.tk/2010/05/text-block-clock/</link>
		<comments>http://sam.xnet.tk/2010/05/text-block-clock/#comments</comments>
		<pubDate>Sat, 15 May 2010 16:58:00 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[Blah]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://eris.xnet.tk/samxnet/?p=10</guid>
		<description><![CDATA[This is a clock that tells you the time by highlighting text in a block of text. In this case using a C# Console App. Not exactly original, but I thought I&#8217;d give it a try. The progress bar counts the time until the next 5 minute mark. Download Code … <a href="http://sam.xnet.tk/2010/05/text-block-clock/"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p><img title="" src="http://cf.sam.xnet.tk/wp-content/uploads/window.png" alt="Clock" /></p>
<p>This is a clock that tells you the time by highlighting text in a block of text. In this case using a C# Console App. Not exactly original, but I thought I&#8217;d give it a try.<br />
The progress bar counts the time until the next 5 minute mark.</p>
<p><a title="Code" href="http://cf.sam.xnet.tk/wp-content/uploads/TimeTextSquare.zip">Download Code</a><br />
<a title="EXE" href="http://cf.sam.xnet.tk/wp-content/uploads/TimeTextSquareEXE.zip">Download Executable</a><br />
<span id="more-10"></span><br />
<script type="text/javascript">// <![CDATA[
function showCode() {
$('#code').show();
$('#showLink').hide();
}
function hideCode() {
$('#code').hide();
$('#showLink').show();
}
// ]]&gt;</script></p>
<p><a id="showLink" href="javascript:showCode();">Show code on page</a></p>
<div id="code" style="display: none;"><a href="javascript:hideCode();">Hide code</a></p>
<pre>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace TimeTextSquare
{
    class Program
    {
        static void Main(string[] args)
        {
            TextClock clock = new TextClock()
                {
                    Colour1 = ConsoleColor.Green,
                    Colour2 = ConsoleColor.DarkGray
                };
            Console.CursorVisible = false;
            Console.WindowWidth = 15;
            Console.WindowHeight = 8;
            clock.Time = DateTime.Now;
            while (true)
            {
                Console.Clear();
                clock.Time = DateTime.Now;
                //clock.Time = clock.Time.AddMinutes(5);
                Console.Title = clock.Time.ToLongTimeString();
                clock.WriteTimeSquare();

                System.Threading.Thread.Sleep(new TimeSpan(0, 0, 5));
            }
        }
    }
    class TextClock
    {
        readonly string[] clockText = new string[]
        {
            "ITSMATENQUARTER",
            "TWENTYHALFIVEVE",
            "PASTOMELEVENINE",
            "EIGHTWELVESEVEN",
            "TENTHREEFIVESIX",
            "FOURTWONEOCLOCK",
            "&gt;&gt;|&gt;&gt;|&gt;&gt;|&gt;&gt;|&gt;&gt;|"
        };

        public DateTime Time { get; set; }
        public ConsoleColor Colour1 { get; set; }
        public ConsoleColor Colour2 { get; set; }

        List minuteHighlightStrings = new List();
        List highlightStrings = new List();
        string hourHighlightString;
        bool highlightFirstA = false;

        void SetTimeStrings()
        {
            minuteHighlightStrings.Clear();
            highlightStrings.Clear();
            hourHighlightString = "";

            highlightStrings.Add("ITS");

            if (Time.Minute &lt; 5)
                highlightStrings.Add("OCLOCK");
            else if (Time.Minute &lt; 10)
                minuteHighlightStrings.Add("FIVE");
            else if (Time.Minute &lt; 15)
                minuteHighlightStrings.Add("TEN");
            else if (Time.Minute &lt; 20)
                minuteHighlightStrings.Add("QUARTER");
            else if (Time.Minute &lt; 25)
                minuteHighlightStrings.Add("TWENTY");
            else if (Time.Minute &lt; 30)
            {
                minuteHighlightStrings.Add("TWENTY");
                minuteHighlightStrings.Add("FIVE");
            }
            else if (Time.Minute &lt; 35)
                highlightStrings.Add("HALF");
            else if (Time.Minute &lt; 40)
            {
                minuteHighlightStrings.Add("TWENTY");
                minuteHighlightStrings.Add("FIVE");
            }
            else if (Time.Minute &lt; 45)
                minuteHighlightStrings.Add("TWENTY");
            else if (Time.Minute &lt; 50)
                minuteHighlightStrings.Add("QUARTER");
            else if (Time.Minute &lt; 55)
                minuteHighlightStrings.Add("TEN");
            else if (Time.Minute &lt; 60)
                minuteHighlightStrings.Add("FIVE");

            if (minuteHighlightStrings.Contains("QUARTER"))
                highlightFirstA = true;

            if (Time.Minute &lt; 35 &amp;&amp; Time.Minute &gt;= 5)
                highlightStrings.Add("PAST");
            else if (Time.Minute &gt;= 35)
                highlightStrings.Add("TO");

            int hour = Time.Hour;
            if (Time.Minute &gt;= 35)
                hour++;
            if (hour &gt; 12)
                hour -= 12;
            string[] hourStrings = new string[] { "TWELVE", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "ELEVEN", "TWELVE" };
            hourHighlightString = hourStrings[hour];
        }

        public void WriteTimeSquare()
        {
            SetTimeStrings();
            Console.ForegroundColor = Colour2;

            for (int lineCounter = 0; lineCounter &lt; clockText.Length - 1; lineCounter++)
            {
                string lineText = clockText[lineCounter];
                for (int charCounter = 0; charCounter &lt; lineText.Length; charCounter++)
                {
                    string remainingText = lineText.Substring(charCounter);
                    bool found = false;
                    foreach (string highlightStr in highlightStrings)
                        if (remainingText.StartsWith(highlightStr))
                        {
                            found = true;
                            Console.ForegroundColor = Colour1;
                            Console.Write(highlightStr);
                            Console.ForegroundColor = Colour2;
                            charCounter += highlightStr.Length - 1;
                        }
                    if (lineCounter</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2010/05/text-block-clock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maximizing a print preview dialog in c#</title>
		<link>http://sam.xnet.tk/2010/05/maximizing-a-print-preview-dialog-in-c/</link>
		<comments>http://sam.xnet.tk/2010/05/maximizing-a-print-preview-dialog-in-c/#comments</comments>
		<pubDate>Sat, 15 May 2010 16:03:00 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://eris.xnet.tk/samxnet/?p=11</guid>
		<description><![CDATA[Here&#8217;s a way to get a print preview dialog (or perhaps any resizeable dialog) maximised. dlg.Show(); //Make full screen //cant use WindowState as its not a form //dlg.DesktopBounds = Screen.FromControl(dlg).WorkingArea; ((Form)dlg).WindowState = FormWindowState.Maximized; dlg.BringToFront(); Although some times it disappears behind whatever form had focus last. Update Looks like the dialog … <a href="http://sam.xnet.tk/2010/05/maximizing-a-print-preview-dialog-in-c/"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a way to get a print preview dialog (or perhaps any resizeable dialog) maximised.</p>
<div style="text-decoration: line-through;">
<pre>dlg.Show();
//Make full screen
//cant use WindowState as its not a form
//dlg.DesktopBounds = Screen.FromControl(dlg).WorkingArea;
((Form)dlg).WindowState = FormWindowState.Maximized;
dlg.BringToFront();</pre>
<p>Although some times it disappears behind whatever form had focus last.</p>
</div>
<p><strong>Update</strong></p>
<p>Looks like the dialog can be cast to a form allowing <code>WindowState</code> to be set.</p>
<pre>PrintPreviewDialog dlg = new PrintPreviewDialog();
dlg.Document = doc;
((Form)dlg).WindowState = FormWindowState.Maximized;
dlg.ShowDialog();</pre>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2010/05/maximizing-a-print-preview-dialog-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Detecting drive insertion and removal in C#</title>
		<link>http://sam.xnet.tk/2010/04/detecting-drive-insertion-and-removal-in-c/</link>
		<comments>http://sam.xnet.tk/2010/04/detecting-drive-insertion-and-removal-in-c/#comments</comments>
		<pubDate>Sun, 04 Apr 2010 17:37:00 +0000</pubDate>
		<dc:creator>Sam</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://eris.xnet.tk/samxnet/?p=12</guid>
		<description><![CDATA[Here is some C# code to detect when a logical volume (e.g. USB Memory Stick) is inserted or removed via the WM_DEVICECHANGE message with WndProc. However this doesn&#8217;t tell you what has been inserted/removed, you will have to poll the drives manually to find out. If you need that you … <a href="http://sam.xnet.tk/2010/04/detecting-drive-insertion-and-removal-in-c/"> Continue reading <span class="meta-nav">&#8594; </span></a>]]></description>
			<content:encoded><![CDATA[<p>Here is some C# code to detect when a logical volume (e.g. USB Memory Stick) is inserted or removed via the <a title="MSDN Library" href="http://msdn.microsoft.com/en-us/library/aa363480%28v=VS.85%29.aspx">WM_DEVICECHANGE</a> message with WndProc.</p>
<p>However this doesn&#8217;t tell you what has been inserted/removed, you will have to poll the drives manually to find out.<br />
If you need that you will have to register to receive events from windows which involves P/Invoking <a title="MSDN Library" href="http://msdn.microsoft.com/en-us/library/aa363431%28v=VS.85%29.aspx">RegisterDeviceNotification</a> (<a title="" href="http://www.codeproject.com/KB/system/DriveDetector.aspx">See Drive Detector at Code Project</a>).</p>
<pre>[...]
using System.Runtime.InteropServices;
using System.Security.Permissions;

public class MyForm : Form
{
        const int WM_DEVICECHANGE = 0x0219;
        const int DBT_DEVICEARRIVAL = 0x8000; // system detected a new device
        const int DBT_DEVICEREMOVECOMPLETE = 0x8004; //device was removed
        const int DBT_DEVNODES_CHANGED = 0x0007; //device changed
        const int DBT_DEVTYP_VOLUME = 0x00000002; // logical volume

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_DEVICECHANGE
                &amp;&amp; m.WParam.ToInt32() == DBT_DEVICEARRIVAL
                || m.WParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE
                || m.WParam.ToInt32() == DBT_DEVNODES_CHANGED))
            {
                if (m.WParam.ToInt32() != DBT_DEVNODES_CHANGED)
                {
                    int devType = Marshal.ReadInt32(m.LParam, 4);
                    if (devType == DBT_DEVTYP_VOLUME)
                    {
                        //Poll drives
                    }
                }
                else
                {
                    //Poll drives
                }
            }

            base.WndProc(ref m);
        }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://sam.xnet.tk/2010/04/detecting-drive-insertion-and-removal-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached
Page Caching using memcached
Database Caching using memcached
Object Caching 523/628 objects using memcached
Content Delivery Network via Amazon Web Services: CloudFront: cf.sam.xnet.tk

Served from: sam.xnet.tk @ 2012-02-23 07:22:29 -->
