tag:blogger.com,1999:blog-55723679301549474312024-03-12T23:09:21.319+00:00while ( this.deadHorse ) { flog( ); }Random stuff about PLC's, automation, programming, tech, geeky stuff...Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.comBlogger30125tag:blogger.com,1999:blog-5572367930154947431.post-10102035876649918882010-07-15T18:43:00.000+01:002010-07-15T18:43:23.413+01:00.NET SerialPort Woes - Zach Saw's Blog<a href="http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html">.NET SerialPort Woes - Zach Saw's Blog</a><div>
</div><div>
</div><div>Very interesting post regarding a potential bug in .NET serial port implementation.</div>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-74910863392071097332010-04-12T19:21:00.000+01:002010-04-12T19:21:06.830+01:00Get name of current Windows userThis function returns a string of the currently logged in user on Windows. An empty string is returned if a valid name cannot be obtained.<br />
<br />
<div class="csharpcode"><pre class="alt"><span class="lnum"> 1: </span><span class="rem">/// <summary></span></pre><pre><span class="lnum"> 2: </span><span class="rem">/// Returns the name of the currently logged on Windows user.</span></pre><pre class="alt"><span class="lnum"> 3: </span><span class="rem">/// </summary></span></pre><pre><span class="lnum"> 4: </span><span class="rem">/// <returns></span></pre><pre class="alt"><span class="lnum"> 5: </span><span class="rem">/// Current user logon name string. Returns an empty string if a valid name cannot be obtained.</returns></span></pre><pre><span class="lnum"> 6: </span><span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">string</span> GetWindowsUserName()</pre><pre class="alt"><span class="lnum"> 7: </span>{</pre><pre><span class="lnum"> 8: </span> System.Security.Principal.WindowsIdentity win_id = <span class="kwrd">null</span>;</pre><pre class="alt"><span class="lnum"> 9: </span> <span class="kwrd">string</span> userName = String.Empty;</pre><pre><span class="lnum"> 10: </span> </pre><pre class="alt"><span class="lnum"> 11: </span> <span class="kwrd">try</span></pre><pre><span class="lnum"> 12: </span> {</pre><pre class="alt"><span class="lnum"> 13: </span> <span class="rem">// Get an object with details about the currently logged on Windows user.</span></pre><pre><span class="lnum"> 14: </span> win_id = System.Security.Principal.WindowsIdentity.GetCurrent();</pre><pre class="alt"><span class="lnum"> 15: </span> </pre><pre><span class="lnum"> 16: </span> <span class="rem">// Get current user domain name and logon name strings.</span></pre><pre class="alt"><span class="lnum"> 17: </span> <span class="rem">// [0] = Domain name.</span></pre><pre><span class="lnum"> 18: </span> <span class="rem">// [1] = Logon name.</span></pre><pre class="alt"><span class="lnum"> 19: </span> <span class="kwrd">string</span>[] names = win_id.Name.Split(<span class="kwrd">new</span> Char[] { '\\' }); <span class="rem">// win_id.Name returns "Domain\Logon"</span></pre><pre><span class="lnum"> 20: </span> </pre><pre class="alt"><span class="lnum"> 21: </span> <span class="kwrd">if</span> (names.Length == 2) { userName = (names[1]); }</pre><pre><span class="lnum"> 22: </span> }</pre><pre class="alt"><span class="lnum"> 23: </span> <span class="kwrd">catch</span> (System.Security.SecurityException)</pre><pre><span class="lnum"> 24: </span> {</pre><pre class="alt"><span class="lnum"> 25: </span> <span class="rem">// Retrieving Windows user details failed so ensure returned name is an empty string.</span></pre><pre><span class="lnum"> 26: </span> userName = String.Empty;</pre><pre class="alt"><span class="lnum"> 27: </span> }</pre><pre><span class="lnum"> 28: </span> <span class="kwrd">finally</span></pre><pre class="alt"><span class="lnum"> 29: </span> {</pre><pre><span class="lnum"> 30: </span> <span class="rem">// Dispose of windows identity object.</span></pre><pre class="alt"><span class="lnum"> 31: </span> <span class="kwrd">if</span> (win_id != <span class="kwrd">null</span>) { win_id.Dispose(); }</pre><pre><span class="lnum"> 32: </span> }</pre><pre class="alt"><span class="lnum"> 33: </span> </pre><pre><span class="lnum"> 34: </span> <span class="kwrd">return</span> userName;</pre><pre class="alt"><span class="lnum"> 35: </span>}</pre></div>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-8492301886609936982010-03-07T18:50:00.000+00:002010-03-07T18:50:29.360+00:00Google Reader - Too USA obsessed.<div class="separator" style="clear: both; text-align: left;">I have been using Google's Reader application for a while now and have had no problems. It's very easy to use, it does all I need it to do and everything is ok in general. One thing bothers me though, and that is the recommendations feature. As I understand it, this should present selections that it think may be of interest based upon things that you select as 'Like' and possibly your browsing activity. Maybe other criteria too, I don't know.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Despite this, almost everything that is presented to me in 'Recommendations' is American based. American news, American sports, American TV, American bloody Idol, yada, yada, yada.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Now I don't have anything against Americans, but there <b>IS</b> a world outside the good ol' US of A.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdMRusslbBnBAB3j_7l6L_8mNi366e8rLqPhPXgw42DGVvLXdEzA12p3LDWimQ0ev5Z0YxnOogB-6NA8UK9TnK0ttZ5TSbYK9n1tcXsaBYjHDRoERdIfX1sOpILKTOHADJTHtWeHjunto/s1600-h/google-reader-logo2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdMRusslbBnBAB3j_7l6L_8mNi366e8rLqPhPXgw42DGVvLXdEzA12p3LDWimQ0ev5Z0YxnOogB-6NA8UK9TnK0ttZ5TSbYK9n1tcXsaBYjHDRoERdIfX1sOpILKTOHADJTHtWeHjunto/s400/google-reader-logo2.png" width="400" /></a></div>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-26272087995693508662010-02-22T19:12:00.008+00:002010-03-28T13:00:36.661+01:00ASUS Eee PC 1201N netbook. Why are we waiting?<div class="separator" style="clear: both; text-align: left;">The potentially mould-breaking <a href="http://uk.asus.com/product.aspx?P_ID=sZ0sI6WqjnCHGFta">ASUS Eee PC 1201N netbook</a> was released in the US during November (or possibly even October) which allowed a lucky few living on the other side of the pond to find one under the Christmas tree.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Fine, ASUS have to roll out their shipments and as I assume that the US is the largest market, it is only natural that they come first. As for the UK, an initial availability date was set for January. Indeed, <a href="http://www.amazon.co.uk/Asus-12-inch-Netbook-battery-Bluetooth/dp/B00336EN88/ref=pd_cp_ce_1">Amazon UK</a> listed this netbook on the 6th January with an initial delivery estimate of '1 to 3 months'.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Yet here we are on the brink of March and they are still as rare as rocking horse s**t, with Amazon <b>STILL</b> quoting '1 to 3 months' estimated delivery. Quite why the estimate cannot be any more accurate than that escapes me.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Come on ASUS, pull your finger out. Why does it take <b>FOUR MONTHS</b> (at least) longer to release it over here?</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">UPDATE 01/03/2010:</div><div class="separator" style="clear: both; text-align: left;">Well, the first of March is here, and still no sign of this netbook appearing in the UK. In fact, a review of various online sellers show that shipping dates are slipping even further, and yup, Amazon still shows '1 to 3 months'. Unbelievable.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">UPDATE 26/03/2010:</div><div class="separator" style="clear: both; text-align: left;">Finally, FINALLY got this delivered after much shenanigans with Amazon UK's delivery agent <a href="http://www.hdnl.co.uk/">HDNL</a> (Home Delivery Network Limited.) Tales of woe include '<i>unable to find address</i>', '<i>delivery van breakdown</i>' and '<i>unable to contact driver</i>'. I was almost too scared to open the box in case I found something else entirely within it. However, it is all present and correct.</div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipHL_Z9iv2FBFqnL76P8fYXyqGZlu0BSz3GBF4qGQW0DOq_GjAlqX0IIoaA-ARSwjWfQyHTt47veIGNosebv4U8oXSmjgjDEQcvrTFarPEp458Gs2fOUg1C0w6w4379pyyzmf2J7Cbz2E/s1600-h/Asus+1201N.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="365" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipHL_Z9iv2FBFqnL76P8fYXyqGZlu0BSz3GBF4qGQW0DOq_GjAlqX0IIoaA-ARSwjWfQyHTt47veIGNosebv4U8oXSmjgjDEQcvrTFarPEp458Gs2fOUg1C0w6w4379pyyzmf2J7Cbz2E/s400/Asus+1201N.jpg" width="400" /></a></div>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-77512924877240112822008-11-17T18:11:00.005+00:002008-11-17T18:29:01.405+00:00BCD to Binary conversionI needed to convert some numbers received from a PLC from their original packed BCD format to binary (hex) format. The numbers to convert are split into two 16-bit halves, and need to be converted into one 32-bit number.
<br />
<br />
(Packed BCD values contain two digits for every byte.)
<br />
<br />
There is a method that exists that will convert numbers from BCD into a true hex number, by using string formatting, but this is relatively expensive in terms of performance and I required the best performance possible.
<br />
<br />
So, I came up with this function:
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="rem">/// <summary></span></pre>
<pre><span class="lnum"> 2: </span><span class="rem">/// Convert two PLC words in BCD format (forming 8 digit number) into single binary integer.</span></pre>
<pre class="alt"><span class="lnum"> 3: </span><span class="rem">/// e.g. If Lower = 0x5678 and Upper = 0x1234, then Return is 12345678 decimal, or 0xbc614e.</span></pre>
<pre><span class="lnum"> 4: </span><span class="rem">/// </summary></span></pre>
<pre class="alt"><span class="lnum"> 5: </span><span class="rem">/// <param name="lower">Least significant 16 bits.</param></span></pre>
<pre><span class="lnum"> 6: </span><span class="rem">/// <param name="upper">Most significant 16 bits.</param></span></pre>
<pre class="alt"><span class="lnum"> 7: </span><span class="rem">/// <returns>32 bit unsigned integer.</returns></span></pre>
<pre><span class="lnum"> 8: </span><span class="rem">/// <remarks>If the parameters supplied are invalid, returns zero.</remarks></span></pre>
<pre class="alt"><span class="lnum"> 9: </span><span class="kwrd">private</span> <span class="kwrd">uint</span> BCD2ToBin(<span class="kwrd">uint</span> lower, <span class="kwrd">uint</span> upper)</pre>
<pre><span class="lnum"> 10: </span>{</pre>
<pre class="alt"><span class="lnum"> 11: </span> <span class="kwrd">uint</span> binVal = 0;</pre>
<pre><span class="lnum"> 12: </span> </pre>
<pre class="alt"><span class="lnum"> 13: </span> <span class="kwrd">if</span> ((lower | upper) != 0)</pre>
<pre><span class="lnum"> 14: </span> {</pre>
<pre class="alt"><span class="lnum"> 15: </span> <span class="kwrd">int</span> shift = 0;</pre>
<pre><span class="lnum"> 16: </span> <span class="kwrd">uint</span> multiplier = 1;</pre>
<pre class="alt"><span class="lnum"> 17: </span> <span class="kwrd">uint</span> bcdVal = (upper << 16) | lower;</pre>
<pre><span class="lnum"> 18: </span> </pre>
<pre class="alt"><span class="lnum"> 19: </span> <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i < 8; i++)</pre>
<pre><span class="lnum"> 20: </span> {</pre>
<pre class="alt"><span class="lnum"> 21: </span> <span class="kwrd">uint</span> digit = (bcdVal >> shift) & 0xf;</pre>
<pre><span class="lnum"> 22: </span> </pre>
<pre class="alt"><span class="lnum"> 23: </span> <span class="kwrd">if</span> (digit > 9)</pre>
<pre><span class="lnum"> 24: </span> {</pre>
<pre class="alt"><span class="lnum"> 25: </span> binVal = 0;</pre>
<pre><span class="lnum"> 26: </span> <span class="kwrd">break</span>;</pre>
<pre class="alt"><span class="lnum"> 27: </span> }</pre>
<pre><span class="lnum"> 28: </span> <span class="kwrd">else</span></pre>
<pre class="alt"><span class="lnum"> 29: </span> {</pre>
<pre><span class="lnum"> 30: </span> binVal += digit * multiplier;</pre>
<pre class="alt"><span class="lnum"> 31: </span> shift += 4;</pre>
<pre><span class="lnum"> 32: </span> multiplier *= 10;</pre>
<pre class="alt"><span class="lnum"> 33: </span> }</pre>
<pre><span class="lnum"> 34: </span> }</pre>
<pre class="alt"><span class="lnum"> 35: </span> }</pre>
<pre><span class="lnum"> 36: </span> </pre>
<pre class="alt"><span class="lnum"> 37: </span> <span class="kwrd">return</span> binVal;</pre>
<pre><span class="lnum"> 38: </span>}</pre>
</div>
<br />
<br />
The function takes in two unsigned itegers that hold each of the 16-bit weighted BCD values, and returns a 32-bit unsigned integer.
<br />
<br />
It is important to note that the return is an unsigned integer, as this allows BCD values up to 0x99999999 to be converted correctly.
<br />
<br />
I have also taken the approach of returning zero if any of the values supplied are incorrect, i.e. contain an invalid digit. (BCD values can only contain digits ranging between 0 and 9, and not A to F.)
<br />
<br />
Of course, it may be desirable to return a different value, or to throw an exception if the parameters supplied are invalid, but for my purposes, returning a zero was sufficient.
<br />
<br />
This method proved to be around four to five times quicker than by using the string format method.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-67218872522704527242008-10-24T18:18:00.003+01:002008-10-24T18:28:27.825+01:00Using RowPrePaint event of a DataGridView controlTo draw a row in a DataGridView control in a different style depending on a certain condition, you can use the RowPrePaint event to interrupt the painting of the rows in the grid.
<br />
<br />
You then have a choice of which parts of the row to be painted automatically and which parts to paint yourself via the PaintParts event property.
<br />
<br />
In the code below, I paint a row with a custom brush, depending on the value of a column that is named 'Error'.
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre><span class="lnum"> 1: </span><span class="rem">/// <summary></span></pre>
<pre><span class="lnum"> 2: </span><span class="rem">/// Handles the drawing of each DataGridView row depending on set log error state.</span></pre>
<pre><span class="lnum"> 3: </span><span class="rem">/// </summary></span></pre>
<pre><span class="lnum"> 4: </span><span class="rem">/// <param name="sender"></param></span></pre>
<pre><span class="lnum"> 5: </span><span class="rem">/// <param name="e"></param></span></pre>
<pre><span class="lnum"> 6: </span><span class="kwrd">private</span> <span class="kwrd">void</span> setLogDataGridView_RowPrePaint(<span class="kwrd">object</span> sender, DataGridViewRowPrePaintEventArgs e)</pre>
<pre><span class="lnum"> 7: </span>{</pre>
<pre><span class="lnum"> 8: </span> <span class="rem">// Paint all parts of row except SelectionBackground and the Focus box.</span></pre>
<pre><span class="lnum"> 9: </span> e.PaintParts = DataGridViewPaintParts.All & ~(DataGridViewPaintParts.SelectionBackground | DataGridViewPaintParts.Focus);</pre>
<pre><span class="lnum"> 10: </span> </pre>
<pre><span class="lnum"> 11: </span> <span class="rem">// Get the value of the error column of the current row</span></pre>
<pre><span class="lnum"> 12: </span> <span class="kwrd">string</span> val = <span class="kwrd">this</span>.setLogDataGridView.Rows[e.RowIndex].Cells[<span class="str">"Error"</span>].Value.ToString();</pre>
<pre><span class="lnum"> 13: </span> </pre>
<pre><span class="lnum"> 14: </span> <span class="kwrd">if</span> (val != <span class="str">"0"</span>)</pre>
<pre><span class="lnum"> 15: </span> {</pre>
<pre><span class="lnum"> 16: </span> <span class="rem">// Get rectangle of area to paint with custom brush.</span></pre>
<pre><span class="lnum"> 17: </span> Rectangle rowBounds = <span class="kwrd">new</span> Rectangle(</pre>
<pre><span class="lnum"> 18: </span> <span class="kwrd">this</span>.setLogDataGridView.RowHeadersWidth, e.RowBounds.Top,</pre>
<pre><span class="lnum"> 19: </span> <span class="kwrd">this</span>.setLogDataGridView.Columns.GetColumnsWidth(</pre>
<pre><span class="lnum"> 20: </span> DataGridViewElementStates.Visible) -</pre>
<pre><span class="lnum"> 21: </span> <span class="kwrd">this</span>.setLogDataGridView.HorizontalScrollingOffset + 1,</pre>
<pre><span class="lnum"> 22: </span> e.RowBounds.Height);</pre>
<pre><span class="lnum"> 23: </span> </pre>
<pre><span class="lnum"> 24: </span> <span class="rem">// Disable normal painting of backgrounds.</span></pre>
<pre><span class="lnum"> 25: </span> e.PaintParts &= ~(DataGridViewPaintParts.Background | DataGridViewPaintParts.ContentBackground);</pre>
<pre><span class="lnum"> 26: </span> </pre>
<pre><span class="lnum"> 27: </span> e.PaintHeader(<span class="kwrd">false</span>);</pre>
<pre><span class="lnum"> 28: </span> </pre>
<pre><span class="lnum"> 29: </span> <span class="rem">// Paint the custom background.</span></pre>
<pre><span class="lnum"> 30: </span> <span class="kwrd">using</span> (Brush lgb = <span class="kwrd">new</span> LinearGradientBrush(rowBounds, Color.Red,</pre>
<pre><span class="lnum"> 31: </span> Color.DarkRed, LinearGradientMode.Vertical))</pre>
<pre><span class="lnum"> 32: </span> {</pre>
<pre><span class="lnum"> 33: </span> e.Graphics.FillRectangle(lgb, rowBounds);</pre>
<pre><span class="lnum"> 34: </span> }</pre>
<pre><span class="lnum"> 35: </span> </pre>
<pre><span class="lnum"> 36: </span> <span class="rem">// Set the text colour.</span></pre>
<pre><span class="lnum"> 37: </span> <span class="kwrd">this</span>.setLogDataGridView.Rows[e.RowIndex].DefaultCellStyle.ForeColor = Color.Yellow;</pre>
<pre><span class="lnum"> 38: </span> <span class="kwrd">this</span>.setLogDataGridView.Rows[e.RowIndex].DefaultCellStyle.SelectionForeColor = Color.Yellow;</pre>
<pre><span class="lnum"> 39: </span> }</pre>
<pre><span class="lnum"> 40: </span>}</pre>
</div>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-64203975235084677162008-10-24T18:10:00.002+01:002008-10-24T18:15:22.372+01:00Create a User business objectTo create a business object that represents a 'User' of my Datalog application, I have used the code shown below, and it works well for my purposes. I decided to make it a Struct instead of a Class as it is a small and lightweight object. If any readers think that it should preferably be a Class, then please leave a comment. I'm still learning this stuff, so any tips welcome!
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre><span class="lnum"> 1: </span><span class="kwrd">using</span> System;</pre>
<pre><span class="lnum"> 2: </span> </pre>
<pre><span class="lnum"> 3: </span><span class="kwrd">namespace</span> KAS.Datalog</pre>
<pre><span class="lnum"> 4: </span>{</pre>
<pre><span class="lnum"> 5: </span> <span class="rem">/// <summary></span></pre>
<pre><span class="lnum"> 6: </span> <span class="rem">/// Represents a user of the application.</span></pre>
<pre><span class="lnum"> 7: </span> <span class="rem">/// </summary></span></pre>
<pre><span class="lnum"> 8: </span> <span class="kwrd">public</span> <span class="kwrd">struct</span> User</pre>
<pre><span class="lnum"> 9: </span> {</pre>
<pre><span class="lnum"> 10: </span> <span class="preproc">#region</span> Fields</pre>
<pre><span class="lnum"> 11: </span> </pre>
<pre><span class="lnum"> 12: </span> <span class="kwrd">private</span> <span class="kwrd">string</span> _strName;</pre>
<pre><span class="lnum"> 13: </span> <span class="kwrd">private</span> UserLevel _userLevel;</pre>
<pre><span class="lnum"> 14: </span> </pre>
<pre><span class="lnum"> 15: </span> <span class="preproc">#endregion</span></pre>
<pre><span class="lnum"> 16: </span> </pre>
<pre><span class="lnum"> 17: </span> <span class="preproc">#region</span> Properties</pre>
<pre><span class="lnum"> 18: </span> </pre>
<pre><span class="lnum"> 19: </span> <span class="rem">/// <summary></span></pre>
<pre><span class="lnum"> 20: </span> <span class="rem">/// Gets or sets the user name.</span></pre>
<pre><span class="lnum"> 21: </span> <span class="rem">/// </summary></span></pre>
<pre><span class="lnum"> 22: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> Name</pre>
<pre><span class="lnum"> 23: </span> {</pre>
<pre><span class="lnum"> 24: </span> get { <span class="kwrd">return</span> <span class="kwrd">this</span>._strName; }</pre>
<pre><span class="lnum"> 25: </span> set { <span class="kwrd">this</span>._strName = <span class="kwrd">value</span>; }</pre>
<pre><span class="lnum"> 26: </span> }</pre>
<pre><span class="lnum"> 27: </span> </pre>
<pre><span class="lnum"> 28: </span> <span class="rem">/// <summary></span></pre>
<pre><span class="lnum"> 29: </span> <span class="rem">/// Gets or sets the user level.</span></pre>
<pre><span class="lnum"> 30: </span> <span class="rem">/// </summary></span></pre>
<pre><span class="lnum"> 31: </span> <span class="kwrd">public</span> UserLevel Level</pre>
<pre><span class="lnum"> 32: </span> {</pre>
<pre><span class="lnum"> 33: </span> get { <span class="kwrd">return</span> <span class="kwrd">this</span>._userLevel; }</pre>
<pre><span class="lnum"> 34: </span> set { <span class="kwrd">this</span>._userLevel = <span class="kwrd">value</span>; }</pre>
<pre><span class="lnum"> 35: </span> }</pre>
<pre><span class="lnum"> 36: </span> </pre>
<pre><span class="lnum"> 37: </span> <span class="preproc">#endregion</span></pre>
<pre><span class="lnum"> 38: </span> </pre>
<pre><span class="lnum"> 39: </span> <span class="preproc">#region</span> Constructor</pre>
<pre><span class="lnum"> 40: </span> </pre>
<pre><span class="lnum"> 41: </span> <span class="rem">/// <summary></span></pre>
<pre><span class="lnum"> 42: </span> <span class="rem">/// Constructor</span></pre>
<pre><span class="lnum"> 43: </span> <span class="rem">/// </summary></span></pre>
<pre><span class="lnum"> 44: </span> <span class="rem">/// <param name="name">Name of the user</param></span></pre>
<pre><span class="lnum"> 45: </span> <span class="rem">/// <param name="level">Secutirty level</param></span></pre>
<pre><span class="lnum"> 46: </span> <span class="kwrd">public</span> User(<span class="kwrd">string</span> name, UserLevel level)</pre>
<pre><span class="lnum"> 47: </span> {</pre>
<pre><span class="lnum"> 48: </span> <span class="kwrd">if</span> (name != <span class="str">""</span>) { <span class="kwrd">this</span>._strName = name; }</pre>
<pre><span class="lnum"> 49: </span> <span class="kwrd">else</span> { <span class="kwrd">this</span>._strName = <span class="str">"Unknown"</span>; }</pre>
<pre><span class="lnum"> 50: </span> </pre>
<pre><span class="lnum"> 51: </span> <span class="kwrd">this</span>._userLevel = level;</pre>
<pre><span class="lnum"> 52: </span> }</pre>
<pre><span class="lnum"> 53: </span> </pre>
<pre><span class="lnum"> 54: </span> <span class="preproc">#endregion</span></pre>
<pre><span class="lnum"> 55: </span> </pre>
<pre><span class="lnum"> 56: </span> <span class="preproc">#region</span> Overridden methods</pre>
<pre><span class="lnum"> 57: </span> </pre>
<pre><span class="lnum"> 58: </span> <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">string</span> ToString()</pre>
<pre><span class="lnum"> 59: </span> {</pre>
<pre><span class="lnum"> 60: </span> <span class="kwrd">return</span> <span class="kwrd">this</span>._strName + <span class="str">","</span> + <span class="kwrd">this</span>._userLevel.ToString();</pre>
<pre><span class="lnum"> 61: </span> }</pre>
<pre><span class="lnum"> 62: </span> </pre>
<pre><span class="lnum"> 63: </span> <span class="preproc">#endregion</span></pre>
<pre><span class="lnum"> 64: </span> }</pre>
<pre><span class="lnum"> 65: </span>}</pre>
</div>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-91339166215328093742008-07-25T19:45:00.014+01:002008-07-25T22:39:28.601+01:00Toshiba InvertersI am currently using inverters from <a href="http://www3.toshiba.co.jp/sic/english/ind_sys/inverter/index.htm">Toshiba</a>, namely the VF-nC1S and VF-S11 models.
<br />
<br />
Petty normal inverters when all is said and done, but with a couple of big advantages for the applications I am working with:
<br />
<br />
<span style="font-weight: bold;">1. 110V single phase input models.</span>
<br />
This is a big plus, since they still provide 220V three phase motor control and it allows use on U.S supplies (and others) that use 110V 1-ph. It also means that all machine units can be built and wired with a standard motor, with only the inverter needing to be changed depending on the shipping location. No 110V to 220V step-up transformers!
<br />
<br />
<span style="font-weight: bold;">2. Three speed control inputs.</span>
<br />
Three inputs as standard on the VF-S11, and by configuring a multi-use input on the VF-nC1S allows for eight distinct binary selected frequency selections. Sixteen can be selected by configuring a fourth input.
<br />
<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF3e_elp6iqsmqRGurdQUd7TmJZJfO9L5L52M-o-WVyGpJ4Mpf-rjOia5pZX__H0aUxsWV_jC006_gJYM1mvlfh81A4vvVX_dmpHwtkOM6diuI8B_2PI0qZDGU03CXe2eqB5g8-pfImnQ/s1600-h/VF-NC1.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF3e_elp6iqsmqRGurdQUd7TmJZJfO9L5L52M-o-WVyGpJ4Mpf-rjOia5pZX__H0aUxsWV_jC006_gJYM1mvlfh81A4vvVX_dmpHwtkOM6diuI8B_2PI0qZDGU03CXe2eqB5g8-pfImnQ/s400/VF-NC1.jpg" alt="" id="BLOGGER_PHOTO_ID_5227025172756439538" border="0" /></a>
<br />
<br />
The VF-S11 models are slightly higher spec in that they have more functions and control I/O at your disposal.
<br />
<br />
A drawback of the 110V models is the lack of a built-in EMC filter, so an external one is required.
<br />
<br />
Also, the particular VF-nC1S model I am currently using - the 0.4kW model - has a relatively high earth leakage current. This is stated as 11mA in the specs, and measured at around 6-10mA depending on load. This can prove a problem if multiple units are powered from the same supply due to nuisance ELCB tripping, and the requiremnet to use a much more stringent earthing policy depending on the arrangement of units.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-22690280590504577812008-07-22T20:53:00.006+01:002008-07-22T21:18:29.635+01:00Omron PLC Dummy I/OUsing dummy IO modules on an Omron PLC with a 'virtual backplane' (i.e. a CJ1M for example) is a good way to keep addresses used for varying projects the same, and adding extra I/O when needed for extra functions, without upsetting the existing addressing structure.
<br />
<br />
For example, suppose you have a machine process that requires three 16 way input cards, and three 16 way output cards. These could of course occupy address space 000, 001, 002, 003, 004 and 005 without problem. But then suppose their is a need for a similar process with some limited functionality that only required two input and output modules. Once again, these could occupy addresses 000, 001, 002 and 003, but these now conflict with the earlier allocation and could cause confusion when wiring and producing documentation, because where 'Solenoid 1' connected to output 003.00 previously, it now connects to output 002.00.
<br />
<br />
A solution to this is to insert some 'dummy' I/O modules into the I/O table to act as placeholders and to allow the addressing to remain consistent between the two processes. ('Dummy' I/O modules are not actual physical modules, but rather they are virtual.)
<br />
<br />
The picture below show an I/O table with some dummy modules inserted:
<br />
<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrvoKMQa_81zIDqlkRUEjJjBUNRlQEE-4qI_T1bAQr_q6GPl5cH14S4u8GS6mAcrQbc-K7Ao1fDhZvtcIOdKv580qgLINSQXb-mm-5zIgjksdloSTMCCUl46PhXjmnYwmvzl77lSUhTd0/s1600-h/DummyIO.bmp"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrvoKMQa_81zIDqlkRUEjJjBUNRlQEE-4qI_T1bAQr_q6GPl5cH14S4u8GS6mAcrQbc-K7Ao1fDhZvtcIOdKv580qgLINSQXb-mm-5zIgjksdloSTMCCUl46PhXjmnYwmvzl77lSUhTd0/s400/DummyIO.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5225929208604466034" /></a>
<br />
<br />
Dummy I/O modules of varying sizes can be added by selecting them from the Basic IO menu of the 'Add unit' dropdown menu.
<br />
<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5xm3U1jEXN-x5LNMv3tBkWzKEnP5x6y_-hu-DcT4XWDrhOTN4ksPmT2og6NicMDCN391N6GSaBzyp7KmK4dEXxbz3mXidM8XeA_6Jn-Jnok-XIdl7NB9wlgu9j7UUYG3r0vIx7Mt0Rn4/s1600-h/SelectUnit.bmp"><img style="display:block; margin:0px auto 10px; cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5xm3U1jEXN-x5LNMv3tBkWzKEnP5x6y_-hu-DcT4XWDrhOTN4ksPmT2og6NicMDCN391N6GSaBzyp7KmK4dEXxbz3mXidM8XeA_6Jn-Jnok-XIdl7NB9wlgu9j7UUYG3r0vIx7Mt0Rn4/s400/SelectUnit.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5225934316410529042" /></a><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDHd231XxSSS6hbOU243wzmga6zTTLPXkgaYBGzLV-zDxsPfXxDZOpDQtGw_e0uFetDj_AAz_70v_ZhhqsnO0Vpq5paxbkwYerpKj8vMAB8PrSHIwtnRwQGoeJ3XlwLpZnOG34fGbTl7A/s1600-h/DummyUnitSelect.bmp"><img style="display:block; margin:0px auto 10px; cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDHd231XxSSS6hbOU243wzmga6zTTLPXkgaYBGzLV-zDxsPfXxDZOpDQtGw_e0uFetDj_AAz_70v_ZhhqsnO0Vpq5paxbkwYerpKj8vMAB8PrSHIwtnRwQGoeJ3XlwLpZnOG34fGbTl7A/s400/DummyUnitSelect.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5225934953595760338" /></a>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com2tag:blogger.com,1999:blog-5572367930154947431.post-15234905297454925922008-07-20T13:53:00.006+01:002008-07-20T14:05:13.215+01:00The Moeller Wiring ManualThe <a href="http://www.wiringmanual.com/">Moeller Wiring Manual</a> is an <span style="font-style:italic;">excellent</span> resource for any electrical controls engineer.
<br />
<br />
Especially useful for the 'Specifications, Formulae, Tables' section.
<br />
<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyYUavNEDx1QcqH_0RCc6I6Tvu4N5CNBrDycIitV4ytjiMR2gHLswXitrX_3SZkNq24xZPKuK5bjV_hwZOSZJAv4kmeYopPKScYeFvPb1D7F6u-hCEmneduJk_W8mbiTk9Naods3MLRCE/s1600-h/Moeller+manual.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyYUavNEDx1QcqH_0RCc6I6Tvu4N5CNBrDycIitV4ytjiMR2gHLswXitrX_3SZkNq24xZPKuK5bjV_hwZOSZJAv4kmeYopPKScYeFvPb1D7F6u-hCEmneduJk_W8mbiTk9Naods3MLRCE/s400/Moeller+manual.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5225078672600733234" /></a>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-584852441981193602008-07-20T10:36:00.005+01:002008-07-20T10:51:54.556+01:00Omron CJ2 PLCOmron have announced the release of a new PLC, namely the CJ2. See <a href="http://www.omron.com/media/press/2008/06/i0620.html">this</a> link for more info.
<br />
<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhT3nskYcM2O5yhqEkV0uk2s2xLqrF4Ed1SvCanLxV8XhrlmB7Kx6LARn2iRR7ANn2hjZ7Zs4poxaII8cVzOF_0y9_xOKGkkedmS3tpRVUqCbDC8bGECN4JEgSkukef8z14b9aC-pWLBzg/s1600-h/CJ2+PLC.bmp"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhT3nskYcM2O5yhqEkV0uk2s2xLqrF4Ed1SvCanLxV8XhrlmB7Kx6LARn2iRR7ANn2hjZ7Zs4poxaII8cVzOF_0y9_xOKGkkedmS3tpRVUqCbDC8bGECN4JEgSkukef8z14b9aC-pWLBzg/s400/CJ2+PLC.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5225029174125838306" /></a>
<br />
<br />
<span style="font-weight:bold;">SYSMAC CJ2 CPU Units</span>
<br />
<br />
1. Greatly increased program capacity and data memory capacity. The largest-capacity CPU unit, the CJ2H-CPU68-EIP, has a program capacity of 400K steps (1.6 times the capacity) and a data memory capacity of 832K words (twice the capacity of previous OMRON products).Higher system throughput speed for I/O and faster immediate refreshing for basic I/O in addition to faster basic and special instructions. (Execution time is 20 times faster than previous OMRON models, e.g., reduced from 20 µs to 1 µs for the LD instruction.)
<br />
<br />
2. A multifunctional Ethernet port compatible with EtherNet/IP is built in and can be used simultaneously for FTP communications, data links, and Support Software connections.
<br />
<br />
3. Errors reduced when modifying designs because tags are used for actual I/O and internal I/O, eliminating the need for address allocation. Also, PLC programming and PT display screens can be developed in parallel.
<br />
<br />
<br />
<br />
Of the points listed above, I find no.3 to be interesting. It sounds to me that it will make programming a PLC similar to writing a C# or Visual Basic program for example, where variables are named and used without the underlying address being important. Very interesting, and I hope that I may have the chance to give it a try.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com1tag:blogger.com,1999:blog-5572367930154947431.post-18611677704535400412008-07-18T20:47:00.005+01:002008-07-18T21:11:09.919+01:00Create a custom label controlCode for a custom label control. This creates a control that inherits from the standard System.Windows.Forms.Label control, and adds the facility to make the background a colour gradient fill.
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">using</span> System;</pre>
<pre><span class="lnum"> 2: </span><span class="kwrd">using</span> System.Drawing;</pre>
<pre class="alt"><span class="lnum"> 3: </span><span class="kwrd">using</span> System.Drawing.Drawing2D;</pre>
<pre><span class="lnum"> 4: </span><span class="kwrd">using</span> System.Windows.Forms;</pre>
<pre class="alt"><span class="lnum"> 5: </span> </pre>
<pre><span class="lnum"> 6: </span><span class="kwrd">namespace</span> MyNamespace</pre>
<pre class="alt"><span class="lnum"> 7: </span>{</pre>
<pre><span class="lnum"> 8: </span> <span class="kwrd">public</span> <span class="kwrd">class</span> CustomLabel : Label</pre>
<pre class="alt"><span class="lnum"> 9: </span> {</pre>
<pre><span class="lnum"> 10: </span> # region Fields</pre>
<pre class="alt"><span class="lnum"> 11: </span> </pre>
<pre><span class="lnum"> 12: </span> <span class="kwrd">private</span> Color _col1;</pre>
<pre class="alt"><span class="lnum"> 13: </span> <span class="kwrd">private</span> Color _col2;</pre>
<pre><span class="lnum"> 14: </span> <span class="kwrd">private</span> Color _col3;</pre>
<pre class="alt"><span class="lnum"> 15: </span> <span class="kwrd">private</span> Color _col4;</pre>
<pre><span class="lnum"> 16: </span> <span class="kwrd">private</span> LinearGradientMode _grad;</pre>
<pre class="alt"><span class="lnum"> 17: </span> </pre>
<pre><span class="lnum"> 18: </span> # endregion</pre>
<pre class="alt"><span class="lnum"> 19: </span> </pre>
<pre><span class="lnum"> 20: </span> # region Properties</pre>
<pre class="alt"><span class="lnum"> 21: </span> </pre>
<pre><span class="lnum"> 22: </span> <span class="kwrd">public</span> Color Colour1</pre>
<pre class="alt"><span class="lnum"> 23: </span> {</pre>
<pre><span class="lnum"> 24: </span> get { <span class="kwrd">return</span> <span class="kwrd">this</span>._col1; }</pre>
<pre class="alt"><span class="lnum"> 25: </span> set</pre>
<pre><span class="lnum"> 26: </span> {</pre>
<pre class="alt"><span class="lnum"> 27: </span> <span class="kwrd">this</span>._col1 = <span class="kwrd">value</span>;</pre>
<pre><span class="lnum"> 28: </span> <span class="kwrd">this</span>.Invalidate();</pre>
<pre class="alt"><span class="lnum"> 29: </span> }</pre>
<pre><span class="lnum"> 30: </span> }</pre>
<pre class="alt"><span class="lnum"> 31: </span> </pre>
<pre><span class="lnum"> 32: </span> <span class="kwrd">public</span> Color Colour2</pre>
<pre class="alt"><span class="lnum"> 33: </span> {</pre>
<pre><span class="lnum"> 34: </span> get { <span class="kwrd">return</span> <span class="kwrd">this</span>._col2; }</pre>
<pre class="alt"><span class="lnum"> 35: </span> set</pre>
<pre><span class="lnum"> 36: </span> {</pre>
<pre class="alt"><span class="lnum"> 37: </span> <span class="kwrd">this</span>._col2 = <span class="kwrd">value</span>;</pre>
<pre><span class="lnum"> 38: </span> <span class="kwrd">this</span>.Invalidate();</pre>
<pre class="alt"><span class="lnum"> 39: </span> }</pre>
<pre><span class="lnum"> 40: </span> }</pre>
<pre class="alt"><span class="lnum"> 41: </span> </pre>
<pre><span class="lnum"> 42: </span> <span class="kwrd">public</span> LinearGradientMode Gradient</pre>
<pre class="alt"><span class="lnum"> 43: </span> {</pre>
<pre><span class="lnum"> 44: </span> get { <span class="kwrd">return</span> <span class="kwrd">this</span>._grad; }</pre>
<pre class="alt"><span class="lnum"> 45: </span> set</pre>
<pre><span class="lnum"> 46: </span> {</pre>
<pre class="alt"><span class="lnum"> 47: </span> <span class="kwrd">this</span>._grad = <span class="kwrd">value</span>;</pre>
<pre><span class="lnum"> 48: </span> <span class="kwrd">this</span>.Invalidate();</pre>
<pre class="alt"><span class="lnum"> 49: </span> }</pre>
<pre><span class="lnum"> 50: </span> }</pre>
<pre class="alt"><span class="lnum"> 51: </span> </pre>
<pre><span class="lnum"> 52: </span> <span class="kwrd">protected</span> <span class="kwrd">override</span> Size DefaultSize</pre>
<pre class="alt"><span class="lnum"> 53: </span> {</pre>
<pre><span class="lnum"> 54: </span> get { <span class="kwrd">return</span> <span class="kwrd">new</span> Size(64, 16); }</pre>
<pre class="alt"><span class="lnum"> 55: </span> }</pre>
<pre><span class="lnum"> 56: </span> </pre>
<pre class="alt"><span class="lnum"> 57: </span> # endregion</pre>
<pre><span class="lnum"> 58: </span> </pre>
<pre class="alt"><span class="lnum"> 59: </span> # region Constructors</pre>
<pre><span class="lnum"> 60: </span> </pre>
<pre class="alt"><span class="lnum"> 61: </span> <span class="kwrd">public</span> CustomLabel()</pre>
<pre><span class="lnum"> 62: </span> : <span class="kwrd">base</span>()</pre>
<pre class="alt"><span class="lnum"> 63: </span> {</pre>
<pre><span class="lnum"> 64: </span> <span class="kwrd">this</span>._col1 = Color.White;</pre>
<pre class="alt"><span class="lnum"> 65: </span> <span class="kwrd">this</span>._col2 = Color.Blue;</pre>
<pre><span class="lnum"> 66: </span> <span class="kwrd">this</span>._col3 = _col1;</pre>
<pre class="alt"><span class="lnum"> 67: </span> <span class="kwrd">this</span>._col4 = _col2;</pre>
<pre><span class="lnum"> 68: </span> <span class="kwrd">this</span>._grad = LinearGradientMode.Vertical;</pre>
<pre class="alt"><span class="lnum"> 69: </span> <span class="kwrd">this</span>.DoubleBuffered = <span class="kwrd">true</span>;</pre>
<pre><span class="lnum"> 70: </span> }</pre>
<pre class="alt"><span class="lnum"> 71: </span> </pre>
<pre><span class="lnum"> 72: </span> <span class="kwrd">public</span> CustomLabel(Color c1, Color c2, LinearGradientMode grad)</pre>
<pre class="alt"><span class="lnum"> 73: </span> : <span class="kwrd">base</span>()</pre>
<pre><span class="lnum"> 74: </span> {</pre>
<pre class="alt"><span class="lnum"> 75: </span> <span class="kwrd">this</span>._col1 = c1;</pre>
<pre><span class="lnum"> 76: </span> <span class="kwrd">this</span>._col2 = c2;</pre>
<pre class="alt"><span class="lnum"> 77: </span> <span class="kwrd">this</span>._col3 = _col1;</pre>
<pre><span class="lnum"> 78: </span> <span class="kwrd">this</span>._col4 = _col2;</pre>
<pre class="alt"><span class="lnum"> 79: </span> <span class="kwrd">this</span>._grad = grad;</pre>
<pre><span class="lnum"> 80: </span> <span class="kwrd">this</span>.DoubleBuffered = <span class="kwrd">true</span>;</pre>
<pre class="alt"><span class="lnum"> 81: </span> }</pre>
<pre><span class="lnum"> 82: </span> </pre>
<pre class="alt"><span class="lnum"> 83: </span> # endregion</pre>
<pre><span class="lnum"> 84: </span> </pre>
<pre class="alt"><span class="lnum"> 85: </span> # region Overrides</pre>
<pre><span class="lnum"> 86: </span> </pre>
<pre class="alt"><span class="lnum"> 87: </span> <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnPaintBackground(PaintEventArgs pevent)</pre>
<pre><span class="lnum"> 88: </span> {</pre>
<pre class="alt"><span class="lnum"> 89: </span> <span class="rem">//base.OnPaintBackground(pevent);</span></pre>
<pre><span class="lnum"> 90: </span> </pre>
<pre class="alt"><span class="lnum"> 91: </span> LinearGradientBrush lgb = <span class="kwrd">new</span> LinearGradientBrush</pre>
<pre><span class="lnum"> 92: </span> (<span class="kwrd">this</span>.ClientRectangle, <span class="kwrd">this</span>._col1, <span class="kwrd">this</span>._col2, <span class="kwrd">this</span>._grad);</pre>
<pre class="alt"><span class="lnum"> 93: </span> pevent.Graphics.FillRectangle(lgb, <span class="kwrd">this</span>.ClientRectangle);</pre>
<pre><span class="lnum"> 94: </span> lgb.Dispose();</pre>
<pre class="alt"><span class="lnum"> 95: </span> }</pre>
<pre><span class="lnum"> 96: </span> </pre>
<pre class="alt"><span class="lnum"> 97: </span> <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnEnabledChanged(EventArgs e)</pre>
<pre><span class="lnum"> 98: </span> {</pre>
<pre class="alt"><span class="lnum"> 99: </span> <span class="kwrd">base</span>.OnEnabledChanged(e);</pre>
<pre><span class="lnum"> 100: </span> </pre>
<pre class="alt"><span class="lnum"> 101: </span> <span class="kwrd">if</span> (<span class="kwrd">this</span>.Enabled)</pre>
<pre><span class="lnum"> 102: </span> {</pre>
<pre class="alt"><span class="lnum"> 103: </span> <span class="kwrd">this</span>._col1 = <span class="kwrd">this</span>._col3;</pre>
<pre><span class="lnum"> 104: </span> <span class="kwrd">this</span>._col2 = <span class="kwrd">this</span>._col4;</pre>
<pre class="alt"><span class="lnum"> 105: </span> }</pre>
<pre><span class="lnum"> 106: </span> <span class="kwrd">else</span></pre>
<pre class="alt"><span class="lnum"> 107: </span> {</pre>
<pre><span class="lnum"> 108: </span> <span class="kwrd">this</span>._col1 = Color.LightGray;</pre>
<pre class="alt"><span class="lnum"> 109: </span> <span class="kwrd">this</span>._col2 = Color.White;</pre>
<pre><span class="lnum"> 110: </span> }</pre>
<pre class="alt"><span class="lnum"> 111: </span> </pre>
<pre><span class="lnum"> 112: </span> <span class="kwrd">this</span>.Invalidate();</pre>
<pre class="alt"><span class="lnum"> 113: </span> }</pre>
<pre><span class="lnum"> 114: </span> </pre>
<pre class="alt"><span class="lnum"> 115: </span> # endregion</pre>
<pre><span class="lnum"> 116: </span> }</pre>
<pre class="alt"><span class="lnum"> 117: </span>}</pre>
</div>
<br />
<br />
When this code is created, the CustomLabel control will be available to add to forms from the control toolbox. Simply add it as per any other forms control.
<br />
<br />
<span style="font-weight: bold;">Notes:</span>
<br />
<br />
<span style="font-weight: bold;">Colour1 & Colour2 properties:</span> These are the properties that specify which colours to use for the gradient fill.
<br />
<br />
<span style="font-weight: bold;">Gradient:</span> This property specifies the type of gradient to use.
<br />
<br />
<span style="font-weight: bold;">Constructors:</span> The default constructor makes the gradient coloured from white to blue, whereas the parameterized constructor colours the label with the user specified colours.
<br />
<br />
<span style="font-weight: bold;">OnPaintBackground:</span> This method is the override for the method called when the background paint event is fired. Note that the call to the base method is inhibited, (i.e. commented out!) because it is not necessary as a new background is being painted.
<br />
<br />
<span style="font-weight: bold;">OnEnabledChanged:</span> When the .Enabled property of the control is changed, an event is fired which executes this method. Notice this time that the base method is called. The colour of the control is changed to light grey through white gradient when the control is disabled to give the appearance of being 'greyed out'.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-10298206729022048962008-07-06T20:51:00.012+01:002008-07-09T18:15:14.498+01:00Filling a DataGridView from a list of structsAn easy way I have found of filling a DataGridView with data, is when you configure the data source to be a list. As part of my Datalog project, I have a struct that represents a tracked machine set. Each new tracked set is added to a List<>. When the job run is complete, it is this List<> that I make the data source.
<br />
<br />
First, the code for the struct:
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="rem">/// <summary></span></pre>
<pre><span class="lnum"> 2: </span><span class="rem">/// Structure representing a tracked machine set.</span></pre>
<pre class="alt"><span class="lnum"> 3: </span><span class="rem">/// </summary></span></pre>
<pre><span class="lnum"> 4: </span><span class="kwrd">public</span> <span class="kwrd">struct</span> TrackedSet</pre>
<pre class="alt"><span class="lnum"> 5: </span>{</pre>
<pre><span class="lnum"> 6: </span> <span class="preproc">#region</span> Fields</pre>
<pre class="alt"><span class="lnum"> 7: </span> </pre>
<pre><span class="lnum"> 8: </span> <span class="kwrd">private</span> <span class="kwrd">int</span> _id;</pre>
<pre class="alt"><span class="lnum"> 9: </span> <span class="kwrd">private</span> <span class="kwrd">string</span> _date;</pre>
<pre><span class="lnum"> 10: </span> <span class="kwrd">private</span> <span class="kwrd">string</span> _time;</pre>
<pre class="alt"><span class="lnum"> 11: </span> <span class="kwrd">private</span> <span class="kwrd">string</span> _customer;</pre>
<pre><span class="lnum"> 12: </span> <span class="kwrd">private</span> <span class="kwrd">int</span> _sheets;</pre>
<pre class="alt"><span class="lnum"> 13: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert1;</pre>
<pre><span class="lnum"> 14: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert2;</pre>
<pre class="alt"><span class="lnum"> 15: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert3;</pre>
<pre><span class="lnum"> 16: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert4;</pre>
<pre class="alt"><span class="lnum"> 17: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert5;</pre>
<pre><span class="lnum"> 18: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert6;</pre>
<pre class="alt"><span class="lnum"> 19: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert7;</pre>
<pre><span class="lnum"> 20: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert8;</pre>
<pre class="alt"><span class="lnum"> 21: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert9;</pre>
<pre><span class="lnum"> 22: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _insert10;</pre>
<pre class="alt"><span class="lnum"> 23: </span> <span class="kwrd">private</span> <span class="kwrd">char</span> _sysCtrl;</pre>
<pre><span class="lnum"> 24: </span> <span class="kwrd">private</span> <span class="kwrd">int</span> _weight;</pre>
<pre class="alt"><span class="lnum"> 25: </span> <span class="kwrd">private</span> <span class="kwrd">string</span> _error;</pre>
<pre><span class="lnum"> 26: </span> </pre>
<pre class="alt"><span class="lnum"> 27: </span> <span class="preproc">#endregion</span></pre>
<pre><span class="lnum"> 28: </span> </pre>
<pre class="alt"><span class="lnum"> 29: </span> <span class="preproc">#region</span> Properties</pre>
<pre><span class="lnum"> 30: </span> </pre>
<pre class="alt"><span class="lnum"> 31: </span> <span class="rem">// The order that the properties are defined determines the order</span></pre>
<pre><span class="lnum"> 32: </span> <span class="rem">// of columns created in the DataGridView.</span></pre>
<pre class="alt"><span class="lnum"> 33: </span> <span class="rem">// The column names will be taken from the property name, unless overwritten.</span></pre>
<pre><span class="lnum"> 34: </span> </pre>
<pre class="alt"><span class="lnum"> 35: </span> <span class="kwrd">public</span> <span class="kwrd">int</span> ID</pre>
<pre><span class="lnum"> 36: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._id; } }</pre>
<pre class="alt"><span class="lnum"> 37: </span> </pre>
<pre><span class="lnum"> 38: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> Date</pre>
<pre class="alt"><span class="lnum"> 39: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._date; } }</pre>
<pre><span class="lnum"> 40: </span> </pre>
<pre class="alt"><span class="lnum"> 41: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> Time</pre>
<pre><span class="lnum"> 42: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._time; } }</pre>
<pre class="alt"><span class="lnum"> 43: </span> </pre>
<pre><span class="lnum"> 44: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> Customer</pre>
<pre class="alt"><span class="lnum"> 45: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._customer; } }</pre>
<pre><span class="lnum"> 46: </span> </pre>
<pre class="alt"><span class="lnum"> 47: </span> <span class="kwrd">public</span> <span class="kwrd">int</span> Sheets</pre>
<pre><span class="lnum"> 48: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._sheets; } }</pre>
<pre class="alt"><span class="lnum"> 49: </span> </pre>
<pre><span class="lnum"> 50: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert1</pre>
<pre class="alt"><span class="lnum"> 51: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert1; } }</pre>
<pre><span class="lnum"> 52: </span> </pre>
<pre class="alt"><span class="lnum"> 53: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert2</pre>
<pre><span class="lnum"> 54: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert2; } }</pre>
<pre class="alt"><span class="lnum"> 55: </span> </pre>
<pre><span class="lnum"> 56: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert3</pre>
<pre class="alt"><span class="lnum"> 57: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert3; } }</pre>
<pre><span class="lnum"> 58: </span> </pre>
<pre class="alt"><span class="lnum"> 59: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert4</pre>
<pre><span class="lnum"> 60: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert4; } }</pre>
<pre class="alt"><span class="lnum"> 61: </span> </pre>
<pre><span class="lnum"> 62: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert5</pre>
<pre class="alt"><span class="lnum"> 63: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert5; } }</pre>
<pre><span class="lnum"> 64: </span> </pre>
<pre class="alt"><span class="lnum"> 65: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert6</pre>
<pre><span class="lnum"> 66: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert6; } }</pre>
<pre class="alt"><span class="lnum"> 67: </span> </pre>
<pre><span class="lnum"> 68: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert7</pre>
<pre class="alt"><span class="lnum"> 69: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert7; } }</pre>
<pre><span class="lnum"> 70: </span> </pre>
<pre class="alt"><span class="lnum"> 71: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert8</pre>
<pre><span class="lnum"> 72: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert8; } }</pre>
<pre class="alt"><span class="lnum"> 73: </span> </pre>
<pre><span class="lnum"> 74: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert9</pre>
<pre class="alt"><span class="lnum"> 75: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert9; } }</pre>
<pre><span class="lnum"> 76: </span> </pre>
<pre class="alt"><span class="lnum"> 77: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> Insert10</pre>
<pre><span class="lnum"> 78: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._insert10; } }</pre>
<pre class="alt"><span class="lnum"> 79: </span> </pre>
<pre><span class="lnum"> 80: </span> <span class="kwrd">public</span> <span class="kwrd">char</span> SysCtrl</pre>
<pre class="alt"><span class="lnum"> 81: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._sysCtrl; } }</pre>
<pre><span class="lnum"> 82: </span> </pre>
<pre class="alt"><span class="lnum"> 83: </span> <span class="kwrd">public</span> <span class="kwrd">int</span> Weight</pre>
<pre><span class="lnum"> 84: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._weight; } }</pre>
<pre class="alt"><span class="lnum"> 85: </span> </pre>
<pre><span class="lnum"> 86: </span> <span class="kwrd">public</span> <span class="kwrd">string</span> Error</pre>
<pre class="alt"><span class="lnum"> 87: </span> { get { <span class="kwrd">return</span> <span class="kwrd">this</span>._error; } }</pre>
<pre><span class="lnum"> 88: </span> </pre>
<pre class="alt"><span class="lnum"> 89: </span> <span class="preproc">#endregion</span></pre>
<pre><span class="lnum"> 90: </span> </pre>
<pre class="alt"><span class="lnum"> 91: </span> <span class="preproc">#region</span> Constructor</pre>
<pre><span class="lnum"> 92: </span> </pre>
<pre class="alt"><span class="lnum"> 93: </span> <span class="rem">/// <summary></span></pre>
<pre><span class="lnum"> 94: </span> <span class="rem">/// TrackedSet constructor.</span></pre>
<pre class="alt"><span class="lnum"> 95: </span> <span class="rem">/// </summary></span></pre>
<pre><span class="lnum"> 96: </span> <span class="rem">/// <param name="id">The ID code for the tracked set</param></span></pre>
<pre class="alt"><span class="lnum"> 97: </span> <span class="rem">/// <param name="msg">The serial link message string decoded from job data block</param></span></pre>
<pre><span class="lnum"> 98: </span> <span class="rem">/// <param name="created">The creation time of the tracked set</param></span></pre>
<pre class="alt"><span class="lnum"> 99: </span> <span class="rem">/// <param name="weight">The post weight of the tracked set.</param></span></pre>
<pre><span class="lnum"> 100: </span> <span class="rem">/// <param name="error">The error code of the tracked set</param></span></pre>
<pre class="alt"><span class="lnum"> 101: </span> <span class="kwrd">public</span> TrackedSet(<span class="kwrd">int</span> id, DateTime created, <span class="kwrd">string</span> msg, <span class="kwrd">int</span> weight, <span class="kwrd">string</span> error)</pre>
<pre><span class="lnum"> 102: </span> {</pre>
<pre class="alt"><span class="lnum"> 103: </span> <span class="rem">// Get ID.</span></pre>
<pre><span class="lnum"> 104: </span> <span class="kwrd">this</span>._id = id;</pre>
<pre class="alt"><span class="lnum"> 105: </span> </pre>
<pre><span class="lnum"> 106: </span> <span class="rem">// Get created date.</span></pre>
<pre class="alt"><span class="lnum"> 107: </span> <span class="kwrd">this</span>._date = created.ToShortDateString();</pre>
<pre><span class="lnum"> 108: </span> </pre>
<pre class="alt"><span class="lnum"> 109: </span> <span class="rem">// Get created time.</span></pre>
<pre><span class="lnum"> 110: </span> <span class="kwrd">this</span>._time = created.ToLongTimeString();</pre>
<pre class="alt"><span class="lnum"> 111: </span> </pre>
<pre><span class="lnum"> 112: </span> <span class="rem">// Get serial link message. Correct format : 12345678901,123,abcdefghij</span></pre>
<pre class="alt"><span class="lnum"> 113: </span> </pre>
<pre><span class="lnum"> 114: </span> <span class="kwrd">string</span>[] str = msg.Split(<span class="str">','</span>);</pre>
<pre class="alt"><span class="lnum"> 115: </span> </pre>
<pre><span class="lnum"> 116: </span> <span class="rem">// Get insert requests and system control characters.</span></pre>
<pre class="alt"><span class="lnum"> 117: </span> <span class="kwrd">char</span>[] c = str[0].ToCharArray();</pre>
<pre><span class="lnum"> 118: </span> </pre>
<pre class="alt"><span class="lnum"> 119: </span> <span class="kwrd">this</span>._insert1 = c[0];</pre>
<pre><span class="lnum"> 120: </span> <span class="kwrd">this</span>._insert2 = c[1];</pre>
<pre class="alt"><span class="lnum"> 121: </span> <span class="kwrd">this</span>._insert3 = c[2];</pre>
<pre><span class="lnum"> 122: </span> <span class="kwrd">this</span>._insert4 = c[3];</pre>
<pre class="alt"><span class="lnum"> 123: </span> <span class="kwrd">this</span>._insert5 = c[4];</pre>
<pre><span class="lnum"> 124: </span> <span class="kwrd">this</span>._insert6 = c[5];</pre>
<pre class="alt"><span class="lnum"> 125: </span> <span class="kwrd">this</span>._insert7 = c[6];</pre>
<pre><span class="lnum"> 126: </span> <span class="kwrd">this</span>._insert8 = c[7];</pre>
<pre class="alt"><span class="lnum"> 127: </span> <span class="kwrd">this</span>._insert9 = c[8];</pre>
<pre><span class="lnum"> 128: </span> <span class="kwrd">this</span>._insert10 = c[9];</pre>
<pre class="alt"><span class="lnum"> 129: </span> <span class="kwrd">this</span>._sysCtrl = c[10];</pre>
<pre><span class="lnum"> 130: </span> </pre>
<pre class="alt"><span class="lnum"> 131: </span> <span class="rem">// Get sheet count.</span></pre>
<pre><span class="lnum"> 132: </span> <span class="kwrd">bool</span> result = <span class="kwrd">int</span>.TryParse(str[1], <span class="kwrd">out</span> <span class="kwrd">this</span>._sheets);</pre>
<pre class="alt"><span class="lnum"> 133: </span> </pre>
<pre><span class="lnum"> 134: </span> <span class="rem">// Get customer code.</span></pre>
<pre class="alt"><span class="lnum"> 135: </span> <span class="kwrd">this</span>._customer = str[2];</pre>
<pre><span class="lnum"> 136: </span> </pre>
<pre class="alt"><span class="lnum"> 137: </span> <span class="rem">// Get post weight.</span></pre>
<pre><span class="lnum"> 138: </span> <span class="kwrd">this</span>._weight = weight;</pre>
<pre class="alt"><span class="lnum"> 139: </span> </pre>
<pre><span class="lnum"> 140: </span> <span class="rem">// Get error code.</span></pre>
<pre class="alt"><span class="lnum"> 141: </span> <span class="kwrd">this</span>._error = error;</pre>
<pre><span class="lnum"> 142: </span> }</pre>
<pre class="alt"><span class="lnum"> 143: </span>}</pre>
</div>
<br />
<br />
The list is defined as...
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span>List<TrackedSet> _trackedSetList;</pre>
</div>
<br />
<br />
...and created as...
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">this</span>._trackedSetList = <span class="kwrd">new</span> List<TrackedSet>();</pre>
</div>
<br />
<br />
Add new TrackedSets during a job run in this way:
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="rem">// Add a new TrackedSet to the list.</span></pre>
<pre><span class="lnum"> 2: </span><span class="kwrd">this</span>._trackedSetList.Add(<span class="kwrd">new</span> TrackedSet(<span class="kwrd">this</span>._rowCounter, </pre>
<pre class="alt"><span class="lnum"> 3: </span> DateTime.Now, </pre>
<pre><span class="lnum"> 4: </span> <span class="kwrd">this</span>._serialLinkMessage, </pre>
<pre class="alt"><span class="lnum"> 5: </span> <span class="kwrd">this</span>._postWeightValue, </pre>
<pre><span class="lnum"> 6: </span> <span class="kwrd">this</span>._errorCode));</pre>
</div>
<br />
<br />
Then it is simply a matter of setting the .DataSource property of the DataGridView to the list to enable it to be displayed:
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">this</span>.dataGridView1.DataSource = <span class="kwrd">this</span>._trackedSetList;</pre>
</div>
<br />
<br />
<P ALIGN="CENTER">This produces an output display similar to:</P>
<br />
<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMxQOaUIoijtgktF9Wkvx-m2fzbopb4qh5FjZ1YNY_dbaGpMK970FitI09ZSMYIzwePmg7gg9eR9HvvMglEZCh0YDeSn2YqZFZVRYoiu9ZE20si6gTuutOm-le-tUKbYpnYJJSRugFQUk/s1600-h/DataGridView.bmp"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMxQOaUIoijtgktF9Wkvx-m2fzbopb4qh5FjZ1YNY_dbaGpMK970FitI09ZSMYIzwePmg7gg9eR9HvvMglEZCh0YDeSn2YqZFZVRYoiu9ZE20si6gTuutOm-le-tUKbYpnYJJSRugFQUk/s320/DataGridView.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5219999487479747890" /></a>
<P ALIGN="CENTER">Click the image to see a larger view.</P>
<br />
<br />
It is important to note thate the order that columns are created and displayed in the DataGridView is directly related to the order in which the struct properties as listed.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com2tag:blogger.com,1999:blog-5572367930154947431.post-69760063471498091022008-07-04T21:17:00.008+01:002008-07-09T18:15:44.064+01:00Omron CX-Programmer SFC EditorWhile using the CX-Programmer V7.2 package from Omron, I wanted to have a play around with the SFC style of programming with a CJ1M PLC. Well, not so easy as it didn't work!
<br />
<br />
When adding a program section of the SFC type, CX-Programmer completely hung up.
<br />
<br />
After much digging, it appears that CX-Programmer (or the SFC editor alone, I'm not sure) is built upon the .NET framwork V1.1. Somehow, when the program was run, it was targetting version 2.0 of the framework, and consequently crashing.
<br />
<br />
The fix I came up with was to force the CX-P.exe program to target the correct framework version.
<br />
<br />
I should point out that the following was in no way suggested by Omron, or anyone else, and so should be taken at your own risk. OK, that's the disclaimer stuff out of the way...
<br />
<br />
Using info from this <a href="http://msdn2.microsoft.com/en-us/library/9w519wzk.aspx">MSDN</a> link...
<br />
<br />
...I created a file called 'CX-P.exe.config' and placed it into the CX-Programmer directory, ie. "C:\Program Files\Omron\CX-One\CX-Programmer".
<br />
<br />
Running CX-Programmer now, adding a SFC task to a CJ1M PLC for example, results in the SFC editor springing into life.
<br />
<br />
The file in question is nothing more than an XML file, the contents being:
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd"><</span><span class="html">configuration</span><span class="kwrd">></span></pre>
<pre><span class="lnum"> 2: </span> <span class="kwrd"><</span><span class="html">startup</span><span class="kwrd">></span></pre>
<pre class="alt"><span class="lnum"> 3: </span> <span class="kwrd"><</span><span class="html">supportedRuntime</span> <span class="attr">version</span><span class="kwrd">="v1.1.4322"</span><span class="kwrd">/></span></pre>
<pre><span class="lnum"> 4: </span> <span class="kwrd"><</span><span class="html">requiredRuntime</span> <span class="attr">version</span><span class="kwrd">="v1.1.4322"</span><span class="kwrd">/></span></pre>
<pre class="alt"><span class="lnum"> 5: </span> <span class="kwrd"></</span><span class="html">startup</span><span class="kwrd">></span></pre>
<pre><span class="lnum"> 6: </span><span class="kwrd"></</span><span class="html">configuration</span><span class="kwrd">></span></pre>
</div>
<br />
This file forces CX-Programmer to use V1.1 of the .Net framework, and not the one it is (wrongly) using for reasons unknown. So far it appears to be working ok. Like I say, try at your own risk!
<br />
<br />
It may be that future update fixes this issue, so this is nothing more than a bit of interesting info.</startup></configuration>
<br />
<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0HuqMkNYCethvlkEcUd6-2qU_Y9UaluFF4IEyL6eBYTExUbCsROO_gcb5kQc-iE_GHdTs9UpwPmuDld1gAIDT1qDGCZz-XRWAZZ_UsEViwAq1PPWZvkGw_ViRBbxzGFnEuCInk4_jTKI/s1600-h/CX-Programmer+V7.2.bmp"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0HuqMkNYCethvlkEcUd6-2qU_Y9UaluFF4IEyL6eBYTExUbCsROO_gcb5kQc-iE_GHdTs9UpwPmuDld1gAIDT1qDGCZz-XRWAZZ_UsEViwAq1PPWZvkGw_ViRBbxzGFnEuCInk4_jTKI/s400/CX-Programmer+V7.2.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5219275080386763442" /></a>
<br />
<br />
I originally posted this a a thread on the MrPLC forum <a href="http://forums.mrplc.com/index.php?showtopic=13409">here</a>.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-13216152162913372792008-07-03T19:00:00.006+01:002008-07-09T18:15:44.064+01:00Implementing IDisposableIn general, while using C# (or any .NET language for that matter), you do not need to worry about resource disposal and memory management. The main exception, however, is when you are using an unmanaged resource – like a database connection or file – or any other resource, except for memory. The .NET framework provides the IDisposable interface for this purpose. Since there is no way to guarantee that the Dispose() method gets called, it is considered a best practice to wrap a call to the Dispose() method in an objects' finalizer (destructor).
<br />
<br />
When the garbage collector runs, all objects with a finalizer are left in memory and have their finalizers executed. Objects without finalizers are simply deleted from memory – which is where memory and resource leaks can potentially happen.
<br />
<br />
The IDisposable interface is defined as follows:
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">interface</span> IDisposable</pre>
<pre><span class="lnum"> 2: </span>{</pre>
<pre class="alt"><span class="lnum"> 3: </span> <span class="kwrd">void</span> Dispose();</pre>
<pre><span class="lnum"> 4: </span>}</pre>
</div>
<br />
It contains nothing more than a single method called Dispose().
<br />
<br />
The following class declaration show how to implement the interface:
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">class</span> MyClass : IDisposable</pre>
<pre><span class="lnum"> 2: </span>{</pre>
<pre class="alt"><span class="lnum"> 3: </span> <span class="kwrd">private</span> <span class="kwrd">bool</span> _isDisposed = <span class="kwrd">false</span>;</pre>
<pre><span class="lnum"> 4: </span> </pre>
<pre class="alt"><span class="lnum"> 5: </span> ~MyClass()</pre>
<pre><span class="lnum"> 6: </span> {</pre>
<pre class="alt"><span class="lnum"> 7: </span> Dispose(<span class="kwrd">false</span>);</pre>
<pre><span class="lnum"> 8: </span> }</pre>
<pre class="alt"><span class="lnum"> 9: </span> </pre>
<pre><span class="lnum"> 10: </span> <span class="kwrd">public</span> <span class="kwrd">void</span> Dispose()</pre>
<pre class="alt"><span class="lnum"> 11: </span> {</pre>
<pre><span class="lnum"> 12: </span> Dispose(<span class="kwrd">true</span>);</pre>
<pre class="alt"><span class="lnum"> 13: </span> GC.SuppressFinalize(<span class="kwrd">true</span>);</pre>
<pre><span class="lnum"> 14: </span> }</pre>
<pre class="alt"><span class="lnum"> 15: </span> </pre>
<pre><span class="lnum"> 16: </span> <span class="kwrd">protected</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> Dispose(<span class="kwrd">bool</span> isDisposing)</pre>
<pre class="alt"><span class="lnum"> 17: </span> {</pre>
<pre><span class="lnum"> 18: </span> <span class="kwrd">if</span> (_isDisposed)</pre>
<pre class="alt"><span class="lnum"> 19: </span> <span class="kwrd">return</span>;</pre>
<pre><span class="lnum"> 20: </span> <span class="kwrd">if</span> (isDisposing)</pre>
<pre class="alt"><span class="lnum"> 21: </span> {</pre>
<pre><span class="lnum"> 22: </span> <span class="rem">// Free managed resources</span></pre>
<pre class="alt"><span class="lnum"> 23: </span> }</pre>
<pre><span class="lnum"> 24: </span> </pre>
<pre class="alt"><span class="lnum"> 25: </span> <span class="rem">// Free unmanaged resources here</span></pre>
<pre><span class="lnum"> 26: </span> _isDisposed = <span class="kwrd">true</span>;</pre>
<pre class="alt"><span class="lnum"> 27: </span> }</pre>
<pre><span class="lnum"> 28: </span>}</pre>
</div>
<br />
<br />
The overloaded virtual Dispose() method in the code above is used when the class is used as a base class, and allows for any derived classes to call the base class disposal method, thus making sure that all resources are properly released.
<br />
<br />
The most important thing to remember when implementing disposal is that you should only be freeing resources in the Dispose() method. Do not call any object methods or create references to the current object or do anything else that could effectively resurrect that object. Remember, you never know in what order objects will be disposed, so you may end up working on an object that is already disposed or finalized. Doing that puts the object in question back into a global list of objects, but the garbage collector will not know to dispose of it again because it’s already been done!
<br />
<br />
In general, I think it is best practice to call an objects' Dispose() method, (or similar - i.e. Close()) when the object is no longer required to allow resources to be returned to the system. Often an object with a Close() method for example will call Dispose() from 'behind the scenes'.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-49326553814550044012008-07-01T22:04:00.002+01:002008-07-09T18:15:44.065+01:00C# and VB.NET differences<a href="http://www.harding.edu/fmccown/vbnet_csharp_comparison.html">This</a> is a nice page that shows some key differences between C# and VB.NET.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-12298970774360769892008-06-28T22:58:00.017+01:002008-07-09T18:15:44.065+01:00Array declaration in C# v VB.NET<div xmlns="http://www.w3.org/1999/xhtml">One particular small thing that I prefer in C# over VB.NET is the way arrays are declared. In C# you declare the size of the array with the total number of elements, instead of the upper bound.
<br />
<br />
i.e. To declare an array of 10 integers in C#:
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">int</span>[] myArray = <span class="kwrd">new</span> <span class="kwrd">int</span>[10];</pre>
</div>
<br />
<br />
To declare an array of 10 integers in VB:
<br />
<br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">Private</span> myArray(9) <span class="kwrd">As</span> Integer</pre>
</div>
<br />
<br />
Other obvious differences are the use of square brackets for C# instead of the parentheses used with VB. Also, th array brackets are part of the type description, instead of the variable name.
<br />
<br />
In my opinion, the C# declaration seems more correct to me, and it has meant I am using less of the 'Array.Length - 1' syntax when using loops etc.</div>
<br />
<br />
This is a good article in <a href="http://www.c-sharpcorner.com/UploadFile/mahesh/WorkingWithArrays11232005064036AM/WorkingWithArrays.aspx">C# Corner</a> that explains the use of arrays.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-24574983680768500002008-06-26T20:38:00.024+01:002008-07-09T18:15:44.065+01:00Gradient border around a formSometimes it is nice to have a bit of extra eye candy to look at, and a good place to have some of this is on a splash screen. One effect that is very simple to achieve is a custom border around the form with a bit of colour and maybe a gradient fill, which is what this post is about.<br /><br />
First of all, set a few of the form properties as follows:<br /><br />
FormBorderstyle - None.<br />
ControlBox - False.<br />
MaximizeBox - False.<br />
MinimizeBox - False.<br />
<br />
The FormBorderStyle property is set to false because the intention is to draw a custom border of our own.<br />
The code required to actually draw the gradient border goes in the form's Paint event. This event is fired at any time the form needs to be redrawn, or in other words - Painted.<br /><br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">private</span> <span class="kwrd">void</span> SplashForm_Paint(<span class="kwrd">object</span> sender, PaintEventArgs e)</pre>
<pre><span class="lnum"> 2: </span>{</pre>
<pre class="alt"><span class="lnum"> 3: </span> <span class="rem">// Get the form bounding rectangle</span></pre>
<pre><span class="lnum"> 4: </span> Rectangle rect = <span class="kwrd">new</span> Rectangle(0, 0, <span class="kwrd">this</span>.Width, <span class="kwrd">this</span>.Height);</pre>
<pre class="alt"><span class="lnum"> 5: </span> </pre>
<pre><span class="lnum"> 6: </span> <span class="rem">// Create the brush used to paint the border</span></pre>
<pre class="alt"><span class="lnum"> 7: </span> LinearGradientBrush lgb = <span class="kwrd">new</span> LinearGradientBrush(</pre>
<pre><span class="lnum"> 8: </span> rect,</pre>
<pre class="alt"><span class="lnum"> 9: </span> Color.DarkBlue,</pre>
<pre><span class="lnum"> 10: </span> Color.Blue,</pre>
<pre class="alt"><span class="lnum"> 11: </span> LinearGradientMode.ForwardDiagonal);</pre>
<pre><span class="lnum"> 12: </span> </pre>
<pre class="alt"><span class="lnum"> 13: </span> <span class="rem">// Draw the border with a width of 10</span></pre>
<pre><span class="lnum"> 14: </span> e.Graphics.DrawRectangle(<span class="kwrd">new</span> Pen(lgb, 10), rect);</pre>
<pre class="alt"><span class="lnum"> 15: </span> </pre>
<pre><span class="lnum"> 16: </span> <span class="rem">// Dispose of the brush</span></pre>
<pre class="alt"><span class="lnum"> 17: </span> lgb.Dispose();</pre>
<pre><span class="lnum"> 18: </span>}</pre>
</div>
<br /><br />
This produces the subtle gradient around the splash screen to my Datalog application:<br /><br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWLLgC1l8ISBaUrbPlwjTb5nJdQSrOEgm5GesJ5vteI1QGnOeAZlriUfXgeZM0sZIRtGV8ANESaXBFvE9F5h12g2LFzayED0ocw5X9ytBQPy-WFoYwNmyQYHxeOuTXjUAc8wMy8-UTGxg/s1600-h/Logo.bmp"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWLLgC1l8ISBaUrbPlwjTb5nJdQSrOEgm5GesJ5vteI1QGnOeAZlriUfXgeZM0sZIRtGV8ANESaXBFvE9F5h12g2LFzayED0ocw5X9ytBQPy-WFoYwNmyQYHxeOuTXjUAc8wMy8-UTGxg/s400/Logo.bmp" alt="" id="BLOGGER_PHOTO_ID_5216282995217767586" border="0" /></a>
<br /><br />
I hope it can be seen that is easy to change the colours, change the gradient and the size of the border that is drawn. Pretty straightforward and only four lines of code.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-72696860484117198092008-06-15T11:34:00.011+01:002008-07-09T18:15:44.065+01:00Watchdog timerI had a need for a simple watchdog timer, to tick only when the time had elapsed, and also to be able to continuously restart it, to stop the timer from ticking.
<br /><br />
This was an excuse to use some inheritance, as I took a standard System.Timers.Timer and subclassed it to create my own WatchdogTimer.
<br /><br />
The code for this is below:
<br /><br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">using</span> System;</pre>
<pre><span class="lnum"> 2: </span><span class="kwrd">using</span> System.Timers;</pre>
<pre class="alt"><span class="lnum"> 3: </span> </pre>
<pre><span class="lnum"> 4: </span><span class="kwrd">namespace</span> MyNamespace</pre>
<pre class="alt"><span class="lnum"> 5: </span>{</pre>
<pre><span class="lnum"> 6: </span> <span class="kwrd">public</span> <span class="kwrd">class</span> WatchdogTimer : Timer</pre>
<pre class="alt"><span class="lnum"> 7: </span> {</pre>
<pre><span class="lnum"> 8: </span> <span class="kwrd">private</span> <span class="kwrd">double</span> _timeout;</pre>
<pre class="alt"><span class="lnum"> 9: </span> </pre>
<pre><span class="lnum"> 10: </span> <span class="kwrd">public</span> WatchdogTimer()</pre>
<pre class="alt"><span class="lnum"> 11: </span> : <span class="kwrd">base</span>()</pre>
<pre><span class="lnum"> 12: </span> {</pre>
<pre class="alt"><span class="lnum"> 13: </span> }</pre>
<pre><span class="lnum"> 14: </span> </pre>
<pre class="alt"><span class="lnum"> 15: </span> <span class="kwrd">public</span> WatchdogTimer(<span class="kwrd">double</span> interval)</pre>
<pre><span class="lnum"> 16: </span> : <span class="kwrd">base</span>(interval)</pre>
<pre class="alt"><span class="lnum"> 17: </span> {</pre>
<pre><span class="lnum"> 18: </span> <span class="kwrd">this</span>._timeout = interval;</pre>
<pre class="alt"><span class="lnum"> 19: </span> }</pre>
<pre><span class="lnum"> 20: </span> </pre>
<pre class="alt"><span class="lnum"> 21: </span> <span class="rem">// Reset and restart the timer.</span></pre>
<pre><span class="lnum"> 22: </span> <span class="kwrd">public</span> <span class="kwrd">void</span> Restart()</pre>
<pre class="alt"><span class="lnum"> 23: </span> {</pre>
<pre><span class="lnum"> 24: </span> <span class="rem">// Resetting the interval property</span></pre>
<pre class="alt"><span class="lnum"> 25: </span> <span class="rem">// forces the timer to restart.</span></pre>
<pre><span class="lnum"> 26: </span> <span class="kwrd">this</span>.Interval = <span class="kwrd">this</span>._timeout;</pre>
<pre class="alt"><span class="lnum"> 27: </span> }</pre>
<pre><span class="lnum"> 28: </span> }</pre>
<pre class="alt"><span class="lnum"> 29: </span>}</pre>
</div>
<br /><br />
It works once the timer has been started by conventional means (i.e. timer.Start();), then it is simply a matter of calling restart every time you need to. In my case it was because I am performing some serial or TCP communications functions, and needed a timeout should they fail.
<br /><br />
Each time I sent a comms response, I expected to receive a response within an allotted period of time. If the response was received, then I called Restart() on the WatchdogTimer. If the response is not received, then the timer will timeout and 'Tick', allowing any code necessary to handle failed comms to run.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-28834387185499479012008-06-14T19:17:00.018+01:002008-07-09T18:15:44.065+01:00InvokeRequiredOne thing that initially confused me when beginning to learn C# with Visual C# 2008 Express, was the complaints made by the debugger when a cross-thread operation was carried out while trying to modify a GUI Control object.
<br /><br />
Doing this is a big no-no as it screws up the message pump operation used by Windows to service all GUI objects running on the user interface thread.
<br /><br />
The solution to this is to use the .InvokeRequired property of the Control you are trying to access, as in the following code snippet:
<br /><br />
<!-- code formatted by http://manoli.net/csharpformat/ -->
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">private</span> <span class="kwrd">void</span> SetText(String txt)</pre>
<pre><span class="lnum"> 2: </span>{</pre>
<pre class="alt"><span class="lnum"> 3: </span> <span class="kwrd">if</span> (<span class="kwrd">this</span>.InvokeRequired)</pre>
<pre><span class="lnum"> 4: </span> {</pre>
<pre class="alt"><span class="lnum"> 5: </span> BeginInvoke(<span class="kwrd">new</span> MethodInvoker(<span class="kwrd">delegate</span>() { <span class="kwrd">this</span>.SetText(txt); }));</pre>
<pre><span class="lnum"> 6: </span> }</pre>
<pre class="alt"><span class="lnum"> 7: </span> <span class="kwrd">else</span></pre>
<pre><span class="lnum"> 8: </span> {</pre>
<pre class="alt"><span class="lnum"> 9: </span> <span class="rem">// Update the text</span></pre>
<pre><span class="lnum"> 10: </span> <span class="kwrd">this</span>.Text = txt;</pre>
<pre class="alt"><span class="lnum"> 11: </span> }</pre>
<pre><span class="lnum"> 12: </span>}</pre>
</div>
<br /><br />
In this example, I want to change the title text of the form. To do this, the method SetText is called, and the InvokeRequired property is checked. If the calling thread is the same as the UI thread, InvokeRequired will be false, and the text can be modified with no problem.
<br /><br />
However, if the calling thread is NOT the same as the UI, then InvokeRequired will be true, and as such the method is called again via the delegate call. This will ensure the SetText method is called from the UI thread and the text can be adjusted without any complaints form the debugger.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-87582070781208113752008-06-14T19:01:00.004+01:002008-07-09T18:15:44.066+01:00Visual C# 2008 ExpressHaving tried a bit of VB.NET, I have decided to have a go at learning some C#. To that end, I am using Visual C# 2008 Express from Microsoft. Not least because it is free!
<br /><br />
The experience I gained with visual Basic has helped a lot with the initial learning curve of C#, as a lot of the statements are very similar. Some only require the addition of a semi-colon to convert it for example.
<br /><br />
The C# language itself is very clean, compared to relative verbosity of Visual Basic, and I am picking it up well (at a beginner level at least.)
<br /><br />
Biggest hurdle so far has been understanding Delegates and creating events. the methodology for this is far different than Visual Basic, in part because VB hides away most of the machinery for this, and so are not exposed to it as readily. C# however, requires you to do this stuff explicitly, which is hard at first.
<br /><br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj586AuCr3mIV66yX9wjzBNZWOADncS7_6Ddf16Z2Lly1F0eGm9JPkdXu_z0TE5ozffyC1hmCyQ0mkfk1RhSIEScYNahARDF1D7ABx7i0YpiLZ8ZqLM47E-FBLmm52lhQu5nfHsugbsv6k/s1600-h/CSharp2008Express.bmp"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj586AuCr3mIV66yX9wjzBNZWOADncS7_6Ddf16Z2Lly1F0eGm9JPkdXu_z0TE5ozffyC1hmCyQ0mkfk1RhSIEScYNahARDF1D7ABx7i0YpiLZ8ZqLM47E-FBLmm52lhQu5nfHsugbsv6k/s400/CSharp2008Express.bmp" alt="" id="BLOGGER_PHOTO_ID_5211799263097963042" border="0" /></a>
<br /><br />
As for the Express application, I am extremely impressed. It has all the functionality I could wish for as a single user at the beginner level. There is only one caveat to that, and that is the lack of a Setup and Install project template. Only ClickOnce technology is implemented, and to be honest, I find that inappropriate for my needs. I will investigate creating an installer for any apps using third party tools, such as Inno for example. I'm sure that will the subject of a future blog entry when the time comes.Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-55059409756228910712008-04-06T10:15:00.003+01:002008-06-15T21:57:36.998+01:00The Great Escape - Alternative. 'To The end'<object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/GU_U0rn_nGE&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/GU_U0rn_nGE&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-26146303478570129052008-03-30T11:41:00.002+01:002008-06-15T21:57:36.998+01:00The Great Escape...<object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/j79Bo0fdd2k&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/j79Bo0fdd2k&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-22286802555873359302007-11-28T18:55:00.002+00:002008-06-28T17:17:16.251+01:00All of My Heart...To all Hatter's fans in the world, THIS is why I love my club...
<br /><br />
<object height="355" width="425"><param name="movie" value="http://www.youtube.com/v/p-JywUvFFtE&rel=1"><param name="wmode" value="transparent"><embed src="http://www.youtube.com/v/p-JywUvFFtE&rel=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0tag:blogger.com,1999:blog-5572367930154947431.post-29414335312211828152007-04-29T18:58:00.000+01:002007-04-29T19:06:17.094+01:00Datalog 3.0.0.0 releaseDemo of Datalog 3.0.0.0 went well, with no last minute hitches. Only need to include a license file and it's done.
I can already think of improvements to make, such as encapsulating more code into classes, and also more improvements that need to be made, such as better comms control, and reduction of the processor overhead.
But for now, it has the green light to ship!Andyhttp://www.blogger.com/profile/09454214445317470668noreply@blogger.com0