<?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>WinSoft.se &#187; Microsoft .NET</title>
	<atom:link href="http://www.winsoft.se/category/dotnet/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.winsoft.se</link>
	<description>Development with focus on Visual Basic .NET</description>
	<lastBuildDate>Thu, 26 Jan 2012 19:28:40 +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>The easiest way to get started with Basic</title>
		<link>http://www.winsoft.se/2012/01/the-easiest-way-to-get-started-with-basic/</link>
		<comments>http://www.winsoft.se/2012/01/the-easiest-way-to-get-started-with-basic/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 10:39:50 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[Microsoft .NET]]></category>
		<category><![CDATA[Small Basic]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1831</guid>
		<description><![CDATA[Let&#8217;s say that you&#8217;re not really a programmer, but perhaps an old Sinclair-user or Commodore user. What is the easiest way to get started with programming on a modern PC? Install Microsoft Small Basic from here (it&#8217;s completely free). Click Download Small Basic, and just follow the instructions. When the installation is complete, you will [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say that you&#8217;re not really a programmer, but perhaps an old Sinclair-user or Commodore user. What is the easiest way to get started with programming on a modern PC?</p>
<p>Install Microsoft Small Basic from <a href="http://msdn.microsoft.com/sv-se/beginner/ff384126(en-us).aspx" target="_blank">here</a> (it&#8217;s completely free). Click Download Small Basic, and just follow the instructions. When the installation is complete, you will have a start menu item that looks like this:</p>
<p><a href="http://www.winsoft.se/wp-content/uploads/small1.jpg"><img src="http://www.winsoft.se/wp-content/uploads/small1.jpg" alt="" title="Small Basic" width="246" height="36" class="alignnone size-full wp-image-1832" /></a></p>
<p>Now, things are really easy. A document is a program. Write your code and hit F5 to run it. Here I have written a Hello world program, started it, and the result is this:</p>
<p><a href="http://www.winsoft.se/wp-content/uploads/small2.jpg"><img src="http://www.winsoft.se/wp-content/uploads/small2.jpg" alt="" title="Small Basic - Hello world" width="380" height="222" class="alignnone size-full wp-image-1834" /></a></p>
<p>Press any key to continue editing.</p>
<p>Context help is always displayed to the right in the main windows of Small Basic, so that you will always know what the code you write actually does. And if you don&#8217;t know what to write at all, an easy tutorial can be found <a href="http://msdn.microsoft.com/sv-se/beginner/gg749839(en-us).aspx" target="_blank">here</a>.</p>
<p>Are you looking for a random number generator, try Math.GetRandomNumber. Specify the largest number you want. This code will display 100 numbers between 1 and 10.</p>
<pre>For I=1 To 100
  TextWindow.WriteLine(Math.GetRandomNumber(10))
EndFor</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2012/01/the-easiest-way-to-get-started-with-basic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calling methods on uninitiated variables</title>
		<link>http://www.winsoft.se/2012/01/calling-methods-on-uninitiated-variables/</link>
		<comments>http://www.winsoft.se/2012/01/calling-methods-on-uninitiated-variables/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 00:07:04 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[Visual Studio 11]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1828</guid>
		<description><![CDATA[If you don&#8217;t assign a value to an object variable, it will have the value Nothing (equivalent to null in C#). These two lines of code will therefore effectively do exactly the same thing, even though the second version will produce slightly more assembly: Dim MyString As String &#8230;and&#8230; Dim MyString As String = Nothing [...]]]></description>
			<content:encoded><![CDATA[<p>If you don&#8217;t assign a value to an object variable, it will have the value <strong>Nothing</strong> (equivalent to <strong>null</strong> in C#). These two lines of code will therefore effectively do exactly the same thing, even though the second version will produce slightly more assembly:</p>
<pre>Dim MyString As String</pre>
<p>&#8230;and&#8230;</p>
<pre>Dim MyString As String = Nothing</pre>
<p>If you create an <a href="http://www.winsoft.se/2011/06/extension-methods-in-visual-basic/">extension method</a> on the <strong>String</strong> class, and you write it in such fashion that it can handle uninitialized variables, it will be able to do so. The extension is done to the type, not to the object. This is an example of a function that checks if a string is empty:</p>
<pre>&lt;System.Runtime.CompilerServices.Extension()&gt; _
Public Function IsEmpty(ByVal S As String) As Boolean
   If S Is Nothing Then
      Return True
   Else
      Return (S = "")
   End If
End Function</pre>
<p>When the above extension is present, the following piece of code&#8230;</p>
<pre>Dim MyString As String = Nothing
Console.WriteLine(MyString.IsEmpty())</pre>
<p>&#8230;displays the word <strong>True</strong> in your console window!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2012/01/calling-methods-on-uninitiated-variables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reading out SQL Data with named columns</title>
		<link>http://www.winsoft.se/2011/12/reading-out-sql-data-with-named-columns/</link>
		<comments>http://www.winsoft.se/2011/12/reading-out-sql-data-with-named-columns/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 16:39:13 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1794</guid>
		<description><![CDATA[This code reads out names from the Employees table of the Northwind database. You must correct the Data Source property in the connection string for it to run. #Create a connection object and open it. [String]$cns="Data Source=XXX;Initial Catalog=Northwind; Integrated Security=True" [System.Data.SqlClient.SqlConnection]$connection=New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $cns $connection.Open() #Create a command and execute it. [String]$query="SELECT FirstName, LastName [...]]]></description>
			<content:encoded><![CDATA[<p>This code reads out names from the Employees table of the Northwind database. You must correct the Data Source property in the connection string for it to run.</p>
<pre class="csharpcode">
#Create a connection <span class="kwrd">object</span> and open it.
[String]$cns=<span class="str">"Data Source=XXX;Initial Catalog=Northwind;
   Integrated Security=True"</span>
[System.Data.SqlClient.SqlConnection]$connection=New-Object
   -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $cns
$connection.Open()

#Create a command and execute it.
[String]$query=<span class="str">"SELECT FirstName, LastName
   FROM dbo.Employees ORDER BY LastName, FirstName"</span>
[System.Data.SqlClient.SqlCommand]$command=New-Object
   -TypeName System.Data.SqlClient.SqlCommand
$command.Connection=$connection
$command.CommandText=$query
$r=$command.ExecuteReader()

#Iterate the result.
<span class="kwrd">while</span>($r.Read()) {

    #Read <span class="kwrd">out</span> first name.
    [String]$firstname=<span class="str">""</span>
    <span class="kwrd">if</span>( -not $r.IsDBNull(0)) {
        $firstname=$r.GetString(0)
    }

    #Read <span class="kwrd">out</span> last name.
    [String]$lastname=<span class="str">""</span>
    <span class="kwrd">if</span>( -not $r.IsDBNull(1)) {
        $lastname=$r.GetString(1)
    }

    #Display.
    Write-Output ($firstname + <span class="str">" "</span> + $lastname)
}

#Close the reader.
$r.Close()

$connection.Close()
$connection.Dispose()</pre>
<p>Here I use column indexes when referring to columns. A change in the SQL query will produce errors in the code that reads out the result. The solution is to call the GetOrdinal function of the reader to get the indexes of the columns, like this:</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<pre class="csharpcode">
#Create a connection <span class="kwrd">object</span> and open it.
[String]$cns=<span class="str">"Data Source=XXX;Initial Catalog=Northwind;
   Integrated Security=True"</span>
[System.Data.SqlClient.SqlConnection]$connection=New-Object
   -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $cns
$connection.Open()

#Create a command and execute it.
[String]$query=<span class="str">"SELECT FirstName, LastName
   FROM dbo.Employees ORDER BY LastName, FirstName"</span>
[System.Data.SqlClient.SqlCommand]$command=New-Object
   -TypeName System.Data.SqlClient.SqlCommand
$command.Connection=$connection
$command.CommandText=$query
$r=$command.ExecuteReader()

#Get use named columns.
[<span class="kwrd">int</span>]$Index_FirstName=$r.GetOrdinal(<span class="str">"FirstName"</span>)
[<span class="kwrd">int</span>]$Index_LastName=$r.GetOrdinal(<span class="str">"LastName"</span>)

#Iterate the result.
<span class="kwrd">while</span>($r.Read()) {

    #Read <span class="kwrd">out</span> first name.
    [String]$firstname=<span class="str">""</span>
    <span class="kwrd">if</span>( -not $r.IsDBNull($Index_FirstName)) {
        $firstname=$r.GetString($Index_FirstName)
    }

    #Read <span class="kwrd">out</span> last name.
    [String]$lastname=<span class="str">""</span>
    <span class="kwrd">if</span>( -not $r.IsDBNull($Index_LastName)) {
        $lastname=$r.GetString($Index_LastName)
    }

    #Display.
    Write-Output ($firstname + <span class="str">" "</span> + $lastname)
}

#Close the reader.
$r.Close()

$connection.Close()
$connection.Dispose()
</pre>
<p>Now, if you change the the query, the reader will still find the desired columns.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2011/12/reading-out-sql-data-with-named-columns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Five reasons to choose Windows before Mac</title>
		<link>http://www.winsoft.se/2011/11/five-reasons-to-choose-windows-before-mac/</link>
		<comments>http://www.winsoft.se/2011/11/five-reasons-to-choose-windows-before-mac/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 20:52:38 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[Microsoft .NET]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1786</guid>
		<description><![CDATA[5. Design. There are a huge number of computers to choose from. The only constant is change. The few Mac machines on the market are OK, but you can find lots and lots of machines running Windows, including masterpieces Mac users only can dream of. 4. Software. The &#8220;killer software&#8221; that makes a Mac worth [...]]]></description>
			<content:encoded><![CDATA[<p><strong>5. Design.</strong> There are a huge number of computers to choose from. The only constant is change. The few Mac machines on the market are OK, but you can find lots and lots of machines running Windows, including <a href="http://www.dell.com/us/p/inspiron-n411z/pd" target="_blank">masterpieces</a> Mac users only can dream of.</p>
<p><strong>4. Software.</strong> The &#8220;killer software&#8221; that makes a Mac worth owning (Safari, Cubase, Photoshop, Propellerheads Reason, Firefox) is perfectly available on Windows. Also, for each Mac specific application you can find, there are at least ten Windows specific alternatives.</p>
<p><strong>3. Memory cost.</strong> A larger number of vendors and in some cases larger vendors, provides <a href="http://www.pcworld.com/article/161668/mac_vs_windows_what_does_1k_get_you.html" target="_blank">customer value</a>.</p>
<p><strong>2. Ease of use.</strong> Windows is well documented, logically constructed. To install an application on Windows, you download it and confirm that you want to install it. You don&#8217;t have to know what drag and drop operations that you expect to perform, and therefore, you don&#8217;t need any experience to get by. Experience gives you advantages, but is not required.</p>
<p><strong>1. Customisation and extensibility.</strong> The smallest edition of the extremely powerful <a href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/express" target="_blank">code editor</a> is free to use for any purpose, and just about any Microsoft application comes with a well documented programming interface. And if you want to start from scratch, the .NET Framework is without competition. In both cases, no matter what programming language you know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2011/11/five-reasons-to-choose-windows-before-mac/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Iterators in Visual Basic</title>
		<link>http://www.winsoft.se/2011/09/iterators-in-visual-basic/</link>
		<comments>http://www.winsoft.se/2011/09/iterators-in-visual-basic/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 16:33:24 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[Visual Studio 11]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1764</guid>
		<description><![CDATA[The concept of iterators is well known to C# programmers, but it is new in Visual Basic (available in Visual Studio 11), so this post is probably only interesting for VB programmers. I got some great help from my friend Roger Alsing in explaining what it is that is good about iterators. An iterator is [...]]]></description>
			<content:encoded><![CDATA[<p>The concept of iterators is well known to C# programmers, but it is new in Visual Basic (available in Visual Studio 11), so this post is probably only interesting for VB programmers. I got some great help from my friend <a href="http://rogeralsing.com/" target="_blank">Roger Alsing</a> in explaining what it is that is good about iterators.</p>
<p>An iterator is similar to a function that returns a collection, but an iterator allows the caller to iterate before the collection is populated. The iterator is implemented as a function with the keyword <strong>Iterator</strong>, but it is actually compiled to an object.</p>
<pre>Public Iterator Function Test() As IEnumerable(Of Integer)</pre>
<p>This is an iterator named Test that returns integers. The return type declared must be an <strong>IEnumerable</strong> of the type your iterator contains. This iterator returns <strong>Integer</strong> values, and therefore the return type is set to an <strong>IEnumerable(Of Integer)</strong>. This is a usage example of our iterator:</p>
<pre>For Each I As Integer In Me.Test()
   MessageBox.Show(I.ToString())
Next</pre>
<p>Of course, a bunch of integer values will pop up on screen. But lets check the full implementation of the <strong>Test</strong> iterator.</p>
<pre>Public Iterator Function Test() As IEnumerable(Of Integer)
   Yield 10
   Yield 20
   Yield 30
End Function</pre>
<p>When the <strong>For Each</strong> loop is done iterating, three message boxes have popped up. They first displays 10, the second 20 and the third 30. So why not just return an array of {10, 20, 30}?</p>
<p>Like I mentioned, a function that returns a collection must load the collection before returning it. Imagine that you want to return 10 objects, each object takes one second to load. This gives you a pause of 10 seconds before the iteration starts. Example:</p>
<pre>Public Function ReturnTenThings() As List(Of String)
   Dim Ret As New List(Of String)()
   For I As Integer = 0 To 9
      Threading.Thread.Sleep(1000)
      Ret.Add((I + 1).ToString())
   Next
   Return Ret
End Function</pre>
<p>This iteration will not start until 10 seconds have passed:</p>
<pre>For Each X As String In Me.ReturnTenThings()
   MessageBox.Show(X)
Next</pre>
<p>If we rewrite <strong>ReturnTenThings</strong> to be an iterator, like this&#8230;</p>
<pre>Public Iterator Function ReturnTenThings() As IEnumerable(Of String)
   Dim Ret As New List(Of String)()
   For I As Integer = 0 To 9
      Threading.Thread.Sleep(1000)
      Yield (I + 1).ToString()
   Next
End Function</pre>
<p>&#8230;the same iteration will still take 10 seconds to complete, but it will start after just one second.</p>
<p>Finally, a word of warning. If you need to know before you start your iteration, how many elements it holds, don&#8217;t just read the <strong>Count</strong> property of your iterator, because that will execute your code. If you need to know, copy the elements to a list, and read the <strong>Count</strong> property of that list. This code will take <u>20 seconds</u> to execute, because the iterator runs twice:</p>
<pre>MessageBox.Show(Me.ReturnTenThings().Count.ToString())
For Each X As String In Me.ReturnTenThings()
   MessageBox.Show(X)
Next</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2011/09/iterators-in-visual-basic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stealing keys</title>
		<link>http://www.winsoft.se/2011/08/stealing-keys/</link>
		<comments>http://www.winsoft.se/2011/08/stealing-keys/#comments</comments>
		<pubDate>Thu, 25 Aug 2011 18:37:36 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[Visual Basic 10]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1760</guid>
		<description><![CDATA[Events and everything you might need to develop a user control, will tell you about mouse and keyboard activity so that you can respond the user correctly. If you want to be able to catch arrow keys or tab, you must overload this function: Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) [...]]]></description>
			<content:encoded><![CDATA[<p>Events and everything you might need to develop a user control, will tell you about mouse and keyboard activity so that you can respond the user correctly. If you want to be able to catch arrow keys or tab, you must overload this function:</p>
<pre>Protected Overrides Function ProcessCmdKey(ByRef msg
   As System.Windows.Forms.Message, ByVal keyData
   As System.Windows.Forms.Keys) As Boolean</pre>
<p>This method gets called no matter what key is pressed. Also, if you act on the key, and don&#8217;t want the original functionality, make the function return True. If you want the framework to act on the key press, make the function return False.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2011/08/stealing-keys/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comparing strings: What&#8217;s being compared?</title>
		<link>http://www.winsoft.se/2011/08/comparing-strings-whats-being-compared/</link>
		<comments>http://www.winsoft.se/2011/08/comparing-strings-whats-being-compared/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 18:23:40 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[Microsoft .NET]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1740</guid>
		<description><![CDATA[In a simple loop, I compare ten million short strings with other strings. 1.4 million of them are identical. Depending on how the comparison is done, the execution speed differs. When the compare operator is used, the ten million tests are done in 0.31 seconds on my laptop. If Strings(A1) = Strings(A2) Then When the [...]]]></description>
			<content:encoded><![CDATA[<p>In a simple loop, I compare ten million short strings with other strings. 1.4 million of them are identical. Depending on how the comparison is done, the execution speed differs. When the compare operator is used, the ten million tests are done in 0.31 seconds on my laptop.</p>
<pre>If Strings(A1) = Strings(A2) Then</pre>
<p>When the <strong>String.Compare</strong> function is used, the ten million tests are done in somewhere between 3.35 to 3.39 seconds. For me, case sensitive tests tend to be slightly slower.</p>
<pre>If String.Compare(Strings(A1), Strings(A2)) = 0 Then</pre>
<p>The reason that the equals operator is faster, is because it only compares the addresses where the strings are located, and since strings are unique in .NET, two strings with the same value, are stored in the same address. The <strong>Compare</strong> function looks at the characters in the string, and is therefore slower.</p>
<p>This is the disassembly for the test with the equals operator:</p>
<pre>0000018f  mov         eax,dword ptr [ebp-50h]
00000192  mov         edx,dword ptr [ebp-48h]
00000195  cmp         eax,dword ptr [edx+4]
00000198  jb          0000019F
0000019a  call        67E075C0
0000019f  mov         eax,dword ptr [edx+eax*4+0Ch]
000001a3  mov         dword ptr [ebp+FFFFFF70h],eax
000001a9  mov         eax,dword ptr [ebp-54h]
000001ac  mov         edx,dword ptr [ebp-48h]
000001af  cmp         eax,dword ptr [edx+4]
000001b2  jb          000001B9
000001b4  call        67E075C0
000001b9  mov         eax,dword ptr [edx+eax*4+0Ch]
000001bd  mov         dword ptr [ebp+FFFFFF6Ch],eax
000001c3  push        0
000001c5  mov         ecx,dword ptr [ebp+FFFFFF70h]
000001cb  mov         edx,dword ptr [ebp+FFFFFF6Ch]
000001d1  call        558156C0
000001d6  mov         dword ptr [ebp-74h],eax
000001d9  cmp         dword ptr [ebp-74h],0
000001dd  sete        al
000001e0  movzx       eax,al
000001e3  mov         dword ptr [ebp-64h],eax
000001e6  cmp         dword ptr [ebp-64h],0
000001ea  je          00000201</pre>
<p>This is the disassembly for the test with the <strong>String.Compare</strong> function:</p>
<pre>0000018f  mov         eax,dword ptr [ebp-50h]
00000192  mov         edx,dword ptr [ebp-48h]
00000195  cmp         eax,dword ptr [edx+4]
00000198  jb          0000019F
0000019a  call        67F275C0
0000019f  mov         ecx,dword ptr [edx+eax*4+0Ch]
000001a3  mov         eax,dword ptr [ebp-54h]
000001a6  mov         edx,dword ptr [ebp-48h]
000001a9  cmp         eax,dword ptr [edx+4]
000001ac  jb          000001B3
000001ae  call        67F275C0
000001b3  mov         edx,dword ptr [edx+eax*4+0Ch]
000001b7  call        5E514300
000001bc  mov         dword ptr [ebp-74h],eax
000001bf  cmp         dword ptr [ebp-74h],0
000001c3  sete        al
000001c6  movzx       eax,al
000001c9  mov         dword ptr [ebp-64h],eax
000001cc  cmp         dword ptr [ebp-64h],0
000001d0  je          000001E7</pre>
<p>It looks less, but it does more. The actual comparing is not shown, but it checks character until a mismatch is found. Since the difference is big, it&#8217;s important to pick the right method. If you add the compile option to compare text as text, the equal operator is almost just as slow as the <strong>String.Compare</strong> function, so the impact for this option&#8230;</p>
<pre>Option Compare Text</pre>
<p>&#8230;is huge.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2011/08/comparing-strings-whats-being-compared/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The shortest code you need to draw vector graphics</title>
		<link>http://www.winsoft.se/2011/07/the-shortest-code-you-need-to-draw-vector-graphics/</link>
		<comments>http://www.winsoft.se/2011/07/the-shortest-code-you-need-to-draw-vector-graphics/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 20:42:17 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1715</guid>
		<description><![CDATA[This example shows the shortest code you need to draw vector graphics in PowerShell. However, this code demonstrates a problem rather than a solution. The .NET Framework wants you to inherit a Form class when you describe a picture, because you will need to be able to access protected properties and to respond to events. [...]]]></description>
			<content:encoded><![CDATA[<p>This example shows the shortest code you need to draw vector graphics in PowerShell. However, this code demonstrates a problem rather than a solution. The .NET Framework wants you to inherit a Form class when you describe a picture, because you will need to be able to access protected properties and to respond to events. But since the CreateGraphics function is public, you can still do some hacking with an instance of a Form class. This code creates a window, draws an X on it, and leaves it visible for 5 seconds.</p>
<pre>#Load the Windows Forms library.
[string]$WindowsFormsLibrary =
"System.Windows.Forms,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089"
[System.Reflection.Assembly]::Load($WindowsFormsLibrary)

#Load the Drawing library.
[string]$DrawingLibrary =
"System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
[System.Reflection.Assembly]::Load($DrawingLibrary)

#Create a window, and set its properties.
[System.Windows.Forms.Form]$f = New-Object System.Windows.Forms.Form
$f.Width = 500
$f.Height = 300

#Display the form.
$f.Show()
#Force a complete draw before we add any graphics.
$f.Refresh()

#Acquire the graphics interface.
[System.Drawing.Graphics]$g = $f.CreateGraphics()

#Draw anything you like here using GDI+.
$g.DrawLine([System.Drawing.Pens]::Black, 50, 20, 450, 250)
$g.DrawLine([System.Drawing.Pens]::Black, 450, 20, 50, 250)

#Dispose the graphics interface.
$g.Dispose()

#Wait for 5 seconds before closing it all down.
Start-Sleep -s 5
$f.Close()
$f.Dispose()</pre>
<p>If we take the trouble to create a custom type based on the Form class, we can create form has double buffering enabled by definition, and is of correct size by definition. The size can be set from outside the form as shown above, but the DoubleBuffered property that controls double buffering could not. So by just replacing the predefined Form class with a custom extension, we are slightly closer to our goal.</p>
<pre>#Load the Windows Forms library.
[string]$WindowsFormsLibrary =
"System.Windows.Forms,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089"
[System.Reflection.Assembly]::Load($WindowsFormsLibrary)

#Load the Drawing library.
[string]$DrawingLibrary =
"System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
[System.Reflection.Assembly]::Load($DrawingLibrary)

<b>#Create a custom form with double buffering.
$Refs = @("System.Windows.Forms", "System.Drawing")
Add-Type -ReferencedAssemblies $Refs @'
public class MyGraphicsForm:System.Windows.Forms.Form
{
   private System.ComponentModel.IContainer components = null;

   protected override void Dispose(bool disposing)
   {
      if (disposing &amp;&amp; (components != null))
      {
         components.Dispose();
      }
      base.Dispose(disposing);
   }

   private void InitializeComponent()
   {
      this.SuspendLayout();
      this.ClientSize = new System.Drawing.Size(500, 300);
      this.DoubleBuffered = true;
      this.Text = "My graphics form";
      this.ResumeLayout(false);

   }
}
'@

#Create our custom window.
[System.Windows.Forms.Form]$f = New-Object MyGraphicsForm</b>

#Display the form.
$f.Show()
#Force a complete draw before we add any graphics.
$f.Refresh()

#Acquire the graphics interface.
[System.Drawing.Graphics]$g = $f.CreateGraphics()

#Draw anything you like here using GDI+.
$g.DrawLine([System.Drawing.Pens]::Black, 50, 20, 450, 250)
$g.DrawLine([System.Drawing.Pens]::Black, 450, 20, 50, 250)

#Dispose the graphics interface.
$g.Dispose()

#Wait for 5 seconds before closing it all down.
Start-Sleep -s 5
$f.Close()
$f.Dispose()</pre>
<p>To be continued.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2011/07/the-shortest-code-you-need-to-draw-vector-graphics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Piping objects</title>
		<link>http://www.winsoft.se/2011/06/piping-objects/</link>
		<comments>http://www.winsoft.se/2011/06/piping-objects/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 09:48:26 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1706</guid>
		<description><![CDATA[If you want to create and run a ps1 script, make sure to give yourself the permission to execute scripts. If you are running a newer operating system, you must start PowerShell as an administrator the time that you grant yourself the right to run scripts. When you type DIR, a list of DirectoryInfo and/or [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to create and run a ps1 script, make sure to <a href="http://www.winsoft.se/2008/12/download-powershell-and-activate-scripting/">give yourself the permission to execute scripts</a>. If you are running a newer operating system, you must start PowerShell as an administrator the time that you grant yourself the right to run scripts.</p>
<p>When you type <strong>DIR</strong>, a list of <strong>DirectoryInfo</strong> and/or <strong>FileInfo</strong> objects are created and sent to the script host. Each object, no matter type, are displayed as strings, meaning that the directory name or file name is displayed. How ever, you can use the pipeline to access actual objects. I have some directories and a few files in my C root, so if I pipe the output from the <strong>DIR</strong> command to an iteration that displays the object&#8217;s type name, like so:</p>
<pre>DIR C:\ | ForEach-Object { Write-Host $_.GetType().Name }</pre>
<p>From that I will get the word <strong>DirectoryInfo</strong> for each directory and the word <strong>FileInfo</strong> for each file in my C root. These are the .NET classes that represent directories and files. Since the PowerShell pipeline actually is handling objects, you can use these objects by accessing the properties or calling the functions of each object. A simple task such as displaying the number of files in each directory, is a walk in the park, when the actual object you need to do this, already is in the pipeline.</p>
<pre>DIR C:\ | ForEach-Object {
If ($_.GetType().Name -like "DirectoryInfo")
   {
      Write-Host $_.Name "(" $_.GetDirectories().Length
         " dirs and " $_.GetFiles().Length " files.)"
   }
}</pre>
<p>The output for this, is the name of the directory and the number of child directories and files that it holds. I can see that my Windows folder holds 66 directories and 45 files.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2011/06/piping-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extension methods in Visual Basic</title>
		<link>http://www.winsoft.se/2011/06/extension-methods-in-visual-basic/</link>
		<comments>http://www.winsoft.se/2011/06/extension-methods-in-visual-basic/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 15:56:24 +0000</pubDate>
		<dc:creator>Anders Hesselbom</dc:creator>
				<category><![CDATA[Visual Basic 10]]></category>

		<guid isPermaLink="false">http://www.winsoft.se/?p=1686</guid>
		<description><![CDATA[Extension methods is a well known concept in C#. The idea is that you can add methods to a type without inheritance, as described here. Visual Basic doesn&#8217;t have any linguistic support for extension methods, but it can be done thanks to a method attribute. There are some rules for doing this. You must declare [...]]]></description>
			<content:encoded><![CDATA[<p>Extension methods is a well known concept in C#. The idea is that you can add methods to a type without inheritance, as described <a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" target="_blank">here</a>.</p>
<p>Visual Basic doesn&#8217;t have any linguistic support for extension methods, but it can be done thanks to a method attribute. There are some rules for doing this. You must declare your sub or function in a <strong>standard module</strong>, not a class. You must have at least one parameter, and that parameter is the type you are extending. Any other parameters will be parameters in your function. Finally, your sub or function must have the <strong>System.Runtime.CompilerServices.Extension</strong> attribute.</p>
<p>So if you want to add a function that takes no parameters to the <strong>Integer</strong> type, you will have to define a function that takes one parameter, an <strong>Integer</strong>. If you want to add a function that takes one parameter, you will have to define a function that takes two parameter, the first must be an <strong>Integer</strong> and the second (who will serve as the first parameter in your function) can be of any type you like.</p>
<pre>Public Function DoubleValue(ByVal I As Integer) As Integer
   Return I * 2
End Function</pre>
<p>Remember, the code must be written in a standard module.</p>
<p>The last thing that you have to do, is to add the attribute.</p>
<pre>&lt;System.Runtime.CompilerServices.Extension()&gt;
Public Function DoubleValue(ByVal I As Integer) As Integer
   Return I * 2
End Function</pre>
<p>(The above code is VBx syntax. For older Visual Basic versions, add a blank followed by an underscore to the attribute line.)</p>
<p>Now you can call the <strong>DoubleValue</strong> function from any <strong>Integer</strong>, in this case <strong>5</strong>:</p>
<pre>Console.WriteLine(5.DoubleValue())</pre>
<p>The output will of course be <strong>10</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.winsoft.se/2011/06/extension-methods-in-visual-basic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

