<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;A0UHRH04fyp7ImA9WxJSFko.&quot;"><id>tag:blogger.com,1999:blog-7163644</id><updated>2009-05-07T14:53:55.337+08:00</updated><title>Apolon's Software Torq</title><subtitle type="html">Just my thoughts on software development.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>151</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/apolon" type="application/atom+xml" /><entry gd:etag="W/&quot;A08EQHw-fyp7ImA9WxRbFE4.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-6338404051654259335</id><published>2008-12-05T09:29:00.010+09:00</published><updated>2008-12-05T10:16:41.257+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-05T10:16:41.257+09:00</app:edited><title>Action Events in .NET</title><content type="html">&lt;p&gt;The Async Pattern used in .NET 1.x and 2.0 code always annoyed me because of the excessive coding noise it introduced. The new support in .NET 3.x in relation to lamdas (convenient delegate or callback syntax) and the generic representation of Actions, Functions and Predicates opens up some possibilities for writing asynchronous oriented code without all that cruft. Check out the IStreamReader class below. It defines a series of events related to the stream reading functionality. Each of these is defined as an event that calls the subscriber back via an Action definition. Each Action type is parameterized based on the needs of the event callback functionality. The beauty of this is that the application code is subsequently much more readable as can be seen by the automated test segment at the end of this blog post.&lt;/p&gt;  &lt;pre class="c#" name="code"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// An object that asynchronously reads bytes from a data stream.&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;public interface IStreamReader&lt;br /&gt;{&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Occurs when a block of bytes has been read by this reader. The data&lt;br /&gt; /// bytes buffer that were just read and the number of bytes placed in&lt;br /&gt; /// that buffer are supplied to the event callbacks.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; event Action&amp;lt;byte [], int&amp;gt; BytesRead;&lt;br /&gt;&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Occurs when progress is made by this reader. The event call back&lt;br /&gt; /// provides the number of bytes read to date and the number of bytes&lt;br /&gt; /// expected to be read in total. If the total number of bytes in the&lt;br /&gt; /// stream is unknown then the total count supplied is -1.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; event Action&amp;lt;int, int&amp;gt; ProgressMade;&lt;br /&gt;&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Occurs when an error stops the read process from proceeding.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; event Action&amp;lt;Exception&amp;gt; ErrorOccurred;&lt;br /&gt;&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Occurs when the read action is complete. This event provides no&lt;br /&gt; /// additional information so is only practically usable when the&lt;br /&gt; /// &amp;lt;see cref="BytesRead"/&amp;gt; event was subscribed to.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; event Action ReadCompleted;&lt;br /&gt;&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Occurs when all data bytes have been read from this stream. The&lt;br /&gt; /// entire data block that was read is supplied to the event callback&lt;br /&gt; /// along with the number of bytes that was read. This event should only&lt;br /&gt; /// be used where the files read can practically fit in memory. If this&lt;br /&gt; /// is not the case, then a combination of the &amp;lt;see cref="BytesRead"/&amp;gt;&lt;br /&gt; /// and &amp;lt;see cref="ReadCompleted"/&amp;gt; events can be used instead to process&lt;br /&gt; /// the large file in manageable chunks.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; event Action&amp;lt;byte [], int&amp;gt; EntireFileRead;&lt;br /&gt;&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Initiates a read of the entire stream.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; void ReadAll();&lt;br /&gt;&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// A convenience method for when this asynchronous oriented class is used&lt;br /&gt; /// in a synchronous manner. This method waits for the read actions to&lt;br /&gt; /// complete or fail before proceeding.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; void WaitForCompletion();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In the following test code segment, an error is not expected to occur so rather than handling the error callback we throw the exception object supplied to fail the test. If the entire file is read successfully a lamda is used to set the text that has been read. In typical applications, the WaitForCompletion method would not be used but it useful in test code and single action applications to wait for the read functionality to complete.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;[ Test ]&lt;br /&gt;public void Disk_Stream_Reads_Entire_File_Successfully()&lt;br /&gt;{&lt;br /&gt; string text = null;&lt;br /&gt; IStreamReader reader = GetTestReader( "MartinLutherSpeech.txt" );&lt;br /&gt; reader.ErrorOccurred += ex =&amp;gt; { throw ex; };&lt;br /&gt; reader.EntireFileRead += ( data, length ) =&amp;gt; text = Encoding.ASCII.GetString( data, 0, length );&lt;br /&gt; reader.ReadAll();&lt;br /&gt; reader.WaitForCompletion();&lt;br /&gt;&lt;br /&gt; Assert.IsNotNull( text );&lt;br /&gt; Assert.AreEqual( 9190, text.Length );&lt;br /&gt; Assert.IsTrue( text.StartsWith( "I am happy to join" ) );&lt;br /&gt; Assert.IsTrue( text.EndsWith( "we are free at last!\"" ) );&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The new functional aspects of the .NET 3.x functionality really changes the way we develop with the .NET framework. Practically speaking its going to take some time to get use to the new ways of thinking and applying them to this multi-core world we find ourselves in.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-6338404051654259335?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/6338404051654259335/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=6338404051654259335" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6338404051654259335?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6338404051654259335?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2008/12/action-events.html" title="Action Events in .NET" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEYGR3ozeSp7ImA9WxRbE0U.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-8655294098078130252</id><published>2008-12-04T18:13:00.002+09:00</published><updated>2008-12-04T18:15:26.481+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-04T18:15:26.481+09:00</app:edited><title>Torq FxCop Setup</title><content type="html">&lt;p&gt;&lt;a class="zem_slink" title="FxCop" href="http://en.wikipedia.org/wiki/FxCop" rel="wikipedia"&gt;FxCop&lt;/a&gt; is a static analysis tool from Microsoft that checks software &lt;a class="zem_slink" title="Source code" href="http://en.wikipedia.org/wiki/Source_code" rel="wikipedia"&gt;source code&lt;/a&gt; for conformance to the &lt;a class="zem_slink" title=".NET Framework" href="http://www.microsoft.com/net/" rel="homepage"&gt;Microsoft .NET framework&lt;/a&gt;’s design guidelines. Static analysis is performed on either the source code files that define the software program or on the compiled software files. It is analysis that is performed before the program is run. This contrasts to dynamic analysis tools which act while the program is running. Both have their place in working towards improving software quality.&lt;/p&gt;  &lt;p&gt;The name FxCop is derived from “Framework Cop”, so it represents a tool that &lt;i&gt;polices&lt;/i&gt; a programmer’s software development so that it meets the .NET framework’s design guidelines. Fortunately the FxCop rule set is configurable so that a software developer can change the static analysis rules to match their internal policies. This is in fact what we are doing with FxCop within our software development processes.&lt;/p&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://torqsoftware.com/blogs/apolon/images/fxcop/FxCopEditor.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;FxCop performs checks on &lt;a class="zem_slink" title=".NET assembly" href="http://en.wikipedia.org/wiki/.NET_assembly" rel="wikipedia"&gt;.NET assemblies&lt;/a&gt; (dll or exe files) and doesn’t work on the source code directly. There are commercial static analysis tools available including those in &lt;a class="zem_slink" title="Visual Studio Team System" href="http://en.wikipedia.org/wiki/Visual_Studio_Team_System" rel="wikipedia" jquery1228377957572="588"&gt;Visual Studio Team System&lt;/a&gt; and other third parties such as NDepend and CodeIt.Right. As we use &lt;a class="zem_slink" title="Microsoft Visual Studio" href="http://msdn.microsoft.com/vstudio/" rel="homepage"&gt;Visual Studio&lt;/a&gt; Professional and FxCop is appropriate for our needs, we’re going the free static analysis tool route. The goal is to increase code quality and in particular highlight obscure and difficult to remember design rules during the development process.&lt;/p&gt;  &lt;p&gt;At the time of writing FxCop isn’t as integrated into Visual Studio as the commercial offerings. Regardless, with some adjustments to our development environment and processes it has been neatly integrated. The approach taken is to add another configuration type to our Visual Studio projects in addition to the defaults of Release and Debug. The additional configuration type has been called Analyse and is intended to be used for any static analysis functionality we choose to add in the future and as such is not limited to FxCop.&lt;/p&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://torqsoftware.com/blogs/apolon/images/fxcop/AnalyseConfiguration.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;The Analyse configuration can be added to a solution in Visual Studio by displaying the Configuration Manager using the “Build-Configuration Manager” menu. Once the Configuration Manager form is displayed, choose the New option in the “Active Solution Configuration” drop down. Once the configuration has been added to the solution, a few more steps are needed as we’re using the Analyse configuration in the same way as the Debug configuration but with additional static analysis actions after every build action.&lt;/p&gt;  &lt;p&gt;To make the Analyse configuration operate in a similar fashion to the Debug configuration we do the following for each project that needs static analysis support:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Set the “Defined DEBUG constant” checkbox in the Build tab for the project.&lt;/li&gt;    &lt;li&gt;Set the Debug Info setting to “Full” in the Advanced Build settings form that is also available from the Build tab for the project.&lt;/li&gt;    &lt;li&gt;Add a call to the AnalyseAssembly batch file to the post build step of the project. A batch file is used to keep the post build step code short and allows us to modify the analysis actions in one location within our development build environment. This then requires the batch file directory to be in the executable path of the development machine.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://torqsoftware.com/blogs/apolon/images/fxcop/BuildDebugConstant.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://torqsoftware.com/blogs/apolon/images/fxcop/AdvancedBuildSettings_DebugInfo.jpg" /&gt; &lt;/p&gt;  &lt;p&gt; &lt;img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://torqsoftware.com/blogs/apolon/images/fxcop/PostBuildStep.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;The AnalyseAssembly batch file is fairly simple, it just runs the command line version of FxCop with the custom dictionary and rule set that we’ve configured.&lt;/p&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://torqsoftware.com/blogs/apolon/images/fxcop/AssemblyAnalyseBatchFile.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;With the Analysis configuration in place, a developer can easily flip to the Analyse configuration option in Visual Studio and compile to see the static analysis results. In addition, the continuous integration system can include the analysis steps in the automated build process. We’ve just recently started using FxCop and are in the process of updating our Visual Studio projects to use the approach documented here. An involved part of this process is choosing which FxCop rules to use and which ones to disable as some of them are certainly too restrictive for our needs. &lt;/p&gt;  &lt;p&gt;&lt;img src="http://torqsoftware.com/blogs/apolon/images/fxcop/AnalysisOutput.jpg" width="750" height="238" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-8655294098078130252?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/8655294098078130252/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=8655294098078130252" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/8655294098078130252?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/8655294098078130252?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2008/12/torq-fxcop-setup.html" title="Torq FxCop Setup" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEMFR3Y4eCp7ImA9WxRRFko.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-4200674958447366543</id><published>2008-09-29T15:10:00.002+08:00</published><updated>2008-09-29T15:13:36.830+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-29T15:13:36.830+08:00</app:edited><title>Modbus Driver and Rewrite Decisions</title><content type="html">&lt;div align="justify"&gt;There’s an informal definition for &lt;a class="zem_slink" title="Legacy system" href="http://en.wikipedia.org/wiki/Legacy_system" rel="wikipedia"&gt;Legacy Software&lt;/a&gt; that comes up time to time that cuts to the core of the matter: &lt;em&gt;Legacy software is software that actually works&lt;/em&gt;. Its been installed, deployed and run against real world situations. As such its a major decision to &lt;a class="zem_slink" title="Rewrite (programming)" href="http://en.wikipedia.org/wiki/Rewrite_%28programming%29" rel="wikipedia"&gt;rewrite&lt;/a&gt; any substantial item of legacy software and should typically be resisted. Regardless, there are many situations where doing a rewrite is the best long term decision to make.&lt;/div&gt;  &lt;div align="justify"&gt;&lt;a href="http://sencom.com.au/"&gt;Sentient Computing&lt;/a&gt; and Torq had to make a rewrite or maintain decision with respect to the mqe driver back in 2004. The mqe driver is an abbreviation for the &lt;a class="zem_slink" title="Modbus" href="http://en.wikipedia.org/wiki/Modbus" rel="wikipedia"&gt;Modbus&lt;/a&gt; Quantum Ethernet driver. It is a &lt;a href="http://sencom.com.au/index.php/productsmenu/macroview/macroview-hmi-scada"&gt;MacroView&lt;/a&gt; communications driver that implements the Modbus Ethernet &lt;a class="zem_slink" title="Transmission Control Protocol" href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol" rel="wikipedia"&gt;TCP&lt;/a&gt; &lt;a class="zem_slink" title="Internet protocol suite" href="http://en.wikipedia.org/wiki/Internet_protocol_suite" rel="wikipedia"&gt;protocol&lt;/a&gt;. We ended up taking the rewrite route and developed the modbusdrv communications driver. This same technology was then used to develop a &lt;a href="http://torqsoftware.com/ProjectDocs/MacroView/ModbusServer/"&gt;Modbus Server&lt;/a&gt; implementation for MacroView and some internal Modbus protocol based utilities.&lt;/div&gt;  &lt;div align="justify"&gt;Many of the &lt;a href="http://sencom.com.au/index.php/productsmenu/macroview/macroview-hmi-scada"&gt;MacroView&lt;/a&gt; installed sites have moved to using the newer modbusdrv communications driver since it was first developed in 2004. Regardless many sites still run the mqe driver which was originally developed in 1996. Recently there was a need to identify the advantages of upgrading to the modbusdrv driver when the mqe had been operating at a site for many years. The question came up because ostensibly there is little functionality difference between the two. From a maintenance perspective, we much prefer the modbusdrv implementation as the source code and internal structure is much cleaner and better organized. So bottom line, the functionality difference is that modbusdrv a better quality communications driver. This translates directly to customer cost savings when any support is needed.&lt;/div&gt;  &lt;div align="justify"&gt;Its interesting that &lt;a class="zem_slink" title="Wikipedia" href="http://www.wikipedia.org/" rel="homepage"&gt;Wikipedia&lt;/a&gt; actually has a dedicated page for the word Rewrite with respect to programming. In that article various web pages are referenced with strong opinions on the subject. Its an emotional issue for developers because the cost of a rewrite is significant. There is a preconception that developers will lean towards rewriting software instead of extending it. It is often attributed to a variation of the &lt;a href="http://en.wikipedia.org/wiki/Not_Invented_Here"&gt;Not Invented Here&lt;/a&gt; syndrome. The Wikipedia article lists the following possible reasons for a software rewrite:&lt;/div&gt;  &lt;ol&gt;   &lt;li&gt;When the &lt;a class="zem_slink" title="Source code" href="http://en.wikipedia.org/wiki/Source_code" rel="wikipedia"&gt;source code&lt;/a&gt; to be able to extend an existing program is not available. &lt;/li&gt;    &lt;li&gt;When the source code is available under an incompatible &lt;a href="http://en.wikipedia.org/wiki/License"&gt;license&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;When the code cannot be adapted to a new target platform. &lt;/li&gt;    &lt;li&gt;&lt;em&gt;When the existing code has become too difficult to handle and extend. &lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;When the task of &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Debugging"&gt;&lt;em&gt;debugging&lt;/em&gt;&lt;/a&gt;&lt;em&gt; the existing code seems too complicated. &lt;/em&gt;&lt;/li&gt;    &lt;li&gt;&lt;em&gt;When the programmer finds it difficult to understand the source code.&lt;/em&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;div align="justify"&gt;The last three were the reasons behind effectively rewriting the mqe driver and developing a new from scratch Modbus TCP driver which we called &lt;a href="http://torqsoftware.com/ProjectDocs/MacroView/Drivers/Modbus/"&gt;modbusdrv&lt;/a&gt;. The approach taken was to implement portions of the mqe functionality as needed on a project by project basis. It was impractical to attempt a total replacement in one go. We added functionality to the modbusdrv implementation over the years such that now they are now on par in terms of functionality. The rewrite was definitely the right decision as the result is that we have a Modbus driver implementation and technology base that is much easier to maintain and extend. Aspects of the modbusdrv implementation and its advantages over the mqe implementation are summarized in the remainder of this blog post. &lt;/div&gt;  &lt;h4&gt;Leveraging Common Libraries&lt;/h4&gt;  &lt;p&gt;The modbusdrv implementation leverages a series of common MacroView libraries that Sentient and Torq have developed since taking over the ongoing MacroView maintenance and development. The mqe driver has its own driver specific Modbus protocol and socket communications code. The advantage of using common libraries include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Issues are resolved for multiple applications when they’re resolved in the common libraries&lt;/li&gt;    &lt;li&gt;Services based on these core libraries can be applied to multiple applications without the need for additional application specific code.&lt;/li&gt;    &lt;li&gt;Developers don’t have to learn how a particular driver implements a particular aspect of its functionality as there is a common mechanism.&lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Serialization Library&lt;/h5&gt;  &lt;p&gt;Newer MacroView drivers and communication utilities leverage the same core &lt;a href="http://en.wikipedia.org/wiki/Serialization"&gt;Serialization&lt;/a&gt; framework. It’s the same serialization library used in drivers such as the Allen Bradley PCCC driver, Simatic 505 driver, Symax ethernet driver, the Modbus server implementation and the MacroView metaserver infrastructure. In all of these implementations, communication messages are modelled as objects. This approach separates out the &lt;a class="zem_slink" title="Data structure" href="http://en.wikipedia.org/wiki/Data_structure" rel="wikipedia"&gt;data structures&lt;/a&gt; from the protocol implementations. It makes it easier to add support for additional packet types and Modbus communication layer variations as needed. Note that the diagram below has only the fields of the classes displayed and excludes the class functions to highlight the data structure.&lt;/p&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://torqsoftware.com/blogs/apolon/images/ModbusLibrary.png" width="738" height="391" /&gt; &lt;/p&gt;  &lt;h5&gt;Modbus Protocol Library&lt;/h5&gt;  &lt;p&gt;A standalone Modbus protocol library was developed and that is used by multiple applications (the driver itself, the Modbus Server application and a general Modbus utility). The protocol library is session type agnostic in its design and currently supports either serial communications or Ethernet TCP scenarios using the same code base.&lt;/p&gt;  &lt;h5&gt;Debug Logging Library&lt;/h5&gt;  &lt;div align="justify"&gt;The debugging and logging options for the modbusdrv driver use a standard MacroView library and leverage the Serialization debugging functionality to provide clear debug logs that show the packet structures in an organized manner. The detailed debug log shows a Modbus request-reply interaction and the associated serialization and deserialization activities. Each structural layer of an object serialization is indented so that the structure of a packet can easily be seen.&lt;/div&gt;  &lt;div align="justify"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto;" src="http://torqsoftware.com/blogs/apolon/images/ModbusDriverDebugLog.jpg" /&gt; &lt;/div&gt;  &lt;h4&gt;Automated Testing&lt;/h4&gt;  &lt;p&gt;The modbusdrv development included automated &lt;a class="zem_slink" title="Unit testing" href="http://en.wikipedia.org/wiki/Unit_testing" rel="wikipedia"&gt;unit tests&lt;/a&gt; and integration tests. The integration tests can be run against either a physical PLC or a Modbus simulator.&lt;/p&gt;  &lt;h5&gt;Unit Testing&lt;/h5&gt;  &lt;p&gt;Within MacroView application programs that we’ve developed, the &lt;a href="http://en.wikipedia.org/wiki/Unit_test"&gt;unit tests&lt;/a&gt; are compiled into the Debug versions of executables and can be run with a –test command line option. It is based a unit testing framework built to work with the MacroView C++ classes but inspired by the &lt;a href="http://en.wikipedia.org/wiki/XUnit"&gt;xUnit&lt;/a&gt; family of unit testing frameworks. The following screen cast shows a run of the modbusdrv unit tests. These are all in-memory tests designed to executable quickly and provide developers with rapid feedback of whether any functionality modifications have adversely affected existing functionality.&lt;/p&gt;  &lt;div align="justify"&gt; &lt;/div&gt;  &lt;div align="center"&gt;&lt;embed name="UnitTestRun" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://torqsoftware.net/video/blog/apolon/ModbusDriverUnitTestRun.swf" type="application/x-shockwave-flash" align="middle" width="538" height="332"&gt;&lt;/embed&gt;&lt;/div&gt;  &lt;div align="left"&gt; &lt;/div&gt;  &lt;h5&gt;Integration Testing&lt;/h5&gt;  &lt;p&gt;The modbusdrv &lt;a href="http://en.wikipedia.org/wiki/Integration_test"&gt;integration tests&lt;/a&gt; are script based and exercises the drivers interaction with a Modbus device through a series of get/set actions with confirmation tests run during the test cycle. Both the unit tests and the integration tests are also run within a &lt;a href="http://en.wikipedia.org/wiki/IBM_Rational_Purify"&gt;Purify&lt;/a&gt; session to identify and resolve any memory issues.&lt;/p&gt;  &lt;div align="center"&gt;&lt;embed name="AutomatedTestRun" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://torqsoftware.net/video/blog/apolon/ModbusDriverAutomatedTestRun.swf" type="application/x-shockwave-flash" align="middle" width="716" height="515"&gt;&lt;/embed&gt;&lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div class="zemanta-pixie"&gt;&lt;img class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=3eca6d4c-c641-4d57-87d4-848a0b2b5285" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-4200674958447366543?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/4200674958447366543/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=4200674958447366543" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4200674958447366543?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4200674958447366543?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2008/09/modbus-driver-and-rewrite-decisions.html" title="Modbus Driver and Rewrite Decisions" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0EMQ3cyeCp7ImA9WxRSGEo.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-7696877588515741384</id><published>2008-09-20T08:46:00.002+08:00</published><updated>2008-09-20T08:48:02.990+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-20T08:48:02.990+08:00</app:edited><title>General versus Special Case Tension</title><content type="html">&lt;p&gt;One of the blogs I subscribe to is by &lt;a href="http://reginald.braythwayt.com/"&gt;Reginald Braithwaite&lt;/a&gt;. He was recently &lt;a href="http://www.infoq.com/interviews/Rewrite-Reginald-Braithwaite"&gt;interviewed on InfoQ&lt;/a&gt; and part of the conversation related to the development process of generalizing in programming:&lt;span style="color:#0000ff;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="color:#0000ff;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;……so again I apologize for digressing, but I found this to be an important point in my own programming, and I don't know if that's a general point but quite often we see something and we are very tempted to say "Oh, this is a special case of a more general thing", and then we solve the general thing. However that is an infinite recursion, it's always the special case of something more general. And if you are always climbing up the tree into the more general thing you will eventually wind up with a PhD in computer science and no code.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;However on the other hand, if we just scrabble around the Earth, and we never sort of poke our head around to see the more general thing. We are constantly resolving the same problems, we are not even recognizing that two different things we solved are both aspects of the same thing. So what I try to do is I always try to recognize what the general case is and then discipline myself not to solve the general case until it's really an imperative, but not to be ignorant of the general case. So coming back to your question, at the moment I am aware that it is a general case, and I am fighting on an almost daily basis not to make it too general&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;This is such a fundamental decision that comes up time and time again in software development. I think Reginald is spot on in his approach of not going down the generalization rabbit hole everytime, but never forgetting that there’s an incredible amount of waste associated with always working on just the specialized case. Sentiments such as &lt;a href="http://en.wikipedia.org/wiki/YAGNI"&gt;YAGNI&lt;/a&gt; are great guiding principles but can be damaging if they preclude doing any generalization work at all.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-7696877588515741384?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/7696877588515741384/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=7696877588515741384" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/7696877588515741384?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/7696877588515741384?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2008/09/general-versus-special-case-tension.html" title="General versus Special Case Tension" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DU4HRHY6cCp7ImA9WxdRF0w.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-5078373817481286244</id><published>2008-06-06T10:04:00.002+08:00</published><updated>2008-06-06T10:05:35.818+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-06T10:05:35.818+08:00</app:edited><title>dynamic_cast and accessible base classes</title><content type="html">&lt;p&gt;We recently upgraded to using Visual Studio 2008 for compiling our MacroView source code on Windows. Previously we had used Visual Studio 2003 so there was a jump over the 2005 compiler version. The same version of IDE is now being used across all of our C, C++ and C# code on Windows. The move went fairly smoothly but one of the porting tasks that I didn’t anticipate was the change in the implementation of dynamic_cast and how it relates to a multiple inheritance hierarchy. A problem occurred where a dynamic_cast failed with a VS2008 compiled executable while it didn’t with the VS2003 compiled version. The inheritance hierarchy of the class in question is shown in the diagram. The diagram is my first use of the C++ class diagram support in VS2008 which is quite nifty. I’m not sure how well it will work with collection relationships in C++, but for quickly creating an inheritance diagram it was very nifty.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="OpcMetaBridgeInheritance" src="http://torqsoftware.com/blogs/apolon/images/OpcMetaBridgeInheritance.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;I suppose some developers will recoil in horror at the use of multiple-inheritance, but it has actually worked well and well across multiple platforms. The multiple inheritance of IMetaMessageProcessor, IConversationMessageSink and IHandleEventProcessor are all in aid of supporting the interface concept in C++. Each of these interface “classes” have all abstract methods and absolutely no data. The DebugTool class is a convenience class which provides a series of logging functions to any class inheriting from it. This is the aspect of the inheritance hierarchy that feels a bit “dirty”. This approach was taken to minimize the amount of typing needed in a class to call a logging function. This could have also been achieved through composition and some macros to reduce the typing footprint. Regardless, this is the design that was chosen and it has worked well. Purists be damned :^)&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Back to the dynamic_cast issue. Testing the VS2008 compiled application showed a dynamic_cast&amp;lt;OpcMetaBridge *&amp;gt;( processor ) where processor is an IMetaMessageProcessor failing. Cracking open the Annotated C++ Reference Manual lead me to the following statement:&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;The result of a dynamic_cast&amp;lt;T&amp;gt;(v) is of type T. The type T must be a pointer or a reference to a defined class or void *.&lt;br /&gt;If T is a pointer type and v is a pointer of a type &lt;strong&gt;for which T is an accessible base class&lt;/strong&gt;, the result is a pointer to a unique sub object of that class.&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;So the dynamic_cast was returning a null pointer because MetaCommsServer inherits from IMetaMessageProcessor with protected inheritance. It worked before because VS2003 and all of the other older Unix C/C++ compilers we’re using weren’t matching the standard. VS2008 improves Microsoft’s compliance with the definition of the C++ language.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-5078373817481286244?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/5078373817481286244/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=5078373817481286244" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/5078373817481286244?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/5078373817481286244?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2008/06/dynamiccast-and-accessible-base-classes.html" title="dynamic_cast and accessible base classes" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CE4DR38zeyp7ImA9WxZWE0o.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-6002283981519475704</id><published>2008-03-13T10:45:00.003+09:00</published><updated>2008-03-13T10:49:36.183+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-13T10:49:36.183+09:00</app:edited><title>DSXP OPC DA 2.0</title><content type="html">&lt;p&gt;Man I hate &lt;a href="http://en.wikipedia.org/wiki/OLE_for_process_control"&gt;OPC&lt;/a&gt;. It just feels like software plumbing gone overboard in the &lt;a href="http://en.wikipedia.org/wiki/Component_Object_Model"&gt;&lt;span style="color:#000000;"&gt;COM&lt;/span&gt;&lt;/a&gt; based architecture it uses. The term “software plumbing” is used to describe software thats forms the basis of software that people (realy people, not developers) actually see. Software plumbing is important as it needs to be establish for the rest of the structure gets built, though I’m sure the analogy is being taken too far here.&lt;/p&gt;&lt;p&gt;I’m currently working on an OPC application that leverages the Technosoftware C++ API that sits on top of OPC to simplify the OPC development somewhat. It does this, but because of &lt;a href="http://en.wikipedia.org/wiki/Leaky_abstraction"&gt;leaky abstractions&lt;/a&gt;, there is need to delve into the library code where it interacts with the OPC interfaces directly. It just seems the combination of COM and C++ result in butt ugly hard to do understand code. You hear/read old Microsofties talking about the wonderful COM architecture (COM is love and all that sort of thing) and wonder what the hell were they smoking? It reminds of the &lt;a href="http://en.wikipedia.org/wiki/Standard_Template_Library"&gt;STL&lt;/a&gt; in that some developers think its a paragon of API design, but to me its difficult to use and difficult to read. Anyway, I’m heading off into bile blog territory here. So back to why I started this blog post…&lt;/p&gt;&lt;p&gt;The Technosoftware OPC C++ Client API treats OPC DA 2.0 and 3.0 servers differently and runs different portions of it’s implementation depending on the OPC version. Its difficult to get access to many OPC servers which require entire systems to practically operate e.g. Yokogawa EXA. Hence there is a need for OPC simulation servers. The one simulation server I’ve found that delivers solely a OPC DA 2.0 interface and sufficiently functional to use in development/testing is the OPC simulator found at &lt;a href="http://www.dsxp.com/"&gt;http://www.dsxp.com&lt;/a&gt;.&lt;a href="http://www.dsxp.com/"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="" src="http://torqsoftware.com/blogs/apolon/images/DSxPOpcSimulator.jpg" border="0" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-6002283981519475704?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/6002283981519475704/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=6002283981519475704" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6002283981519475704?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6002283981519475704?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2008/03/dsxp-opc-da-20.html" title="DSXP OPC DA 2.0" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DEMER347fip7ImA9WB9aGU8.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-7781019383539428792</id><published>2008-01-10T09:53:00.001+09:00</published><updated>2008-01-10T09:53:26.006+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-10T09:53:26.006+09:00</app:edited><title>Fedora Core 7 and VMWare</title><content type="html">&lt;p&gt;Here&amp;rsquo;s a quick tip that I kicked myself when I eventually figured out &amp;ndash; and then felt subsequently quite thick. After installing Fedora Core 7 within a VMWare host on Windows, the screen resolution couldn&amp;rsquo;t go above 800x600. I worked with that for a while using an X windows package to interact with FC7 to get around the low resolution. Today I found out that if you change the display monitor type to be an LCD panel of a particular resolution, lo and behold you can then choose a whole bunch of screen resolutions. The performance of the latest VMWare tools and Fedora Core 7 combination is great. Its now as good as a Windows guest running VMware tools.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="" src="http://torqsoftware.com/blogs/apolon/images/FedoraCore7LcdMonitor.jpg" border="0" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-7781019383539428792?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/7781019383539428792/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=7781019383539428792" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/7781019383539428792?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/7781019383539428792?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2008/01/fedora-core-7-and-vmware.html" title="Fedora Core 7 and VMWare" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;D08FQnwzcCp7ImA9WB9TFE8.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-727400108445774872</id><published>2007-09-22T08:50:00.001+08:00</published><updated>2007-09-22T09:50:13.288+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-09-22T09:50:13.288+08:00</app:edited><title>Real Men Don't Sleep</title><content type="html">&lt;p&gt;There&amp;rsquo;s a new MSDN show called &lt;a href="http://channel9.msdn.com/shows/Striking_Pixels"&gt;Striking Pixels&lt;/a&gt; that is a &amp;ldquo;goofy&amp;rdquo; look at Microsoft&amp;rsquo;s designer offerings&amp;nbsp;such as &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt;. There was one excerpt that just cracked me up. Its shown below. The two hosts are playing two sets of characters. The first set of characters are the customers who have a very dodgy set of accents (and dodgy moustaches). The second set of characters are the designers that are providing design services to the customers. I found it so funny because earlier in the week I had a similar experience. A business partner sent over a rough set of functionality requirements for a product extension. It was only on my second pass at reading the documents that I realized the expectation was to have something ready by October 1&lt;sup&gt;st&lt;/sup&gt; which was just 6 working days away at the time. So I totally get the exasperation and stunned silence shown by the designer characters in the following excerpt:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;embed name="wasp" pluginspage="http://www.macromedia.com/go/getflashplayer" align="middle" src="http://torqsoftware.net/video/player/wasp.swf?theFile=http://torqsoftware.net/video/blog/apolon/RealMenDontSleep.flv&amp;amp;defaultImage=http://torqsoftware.net/video/player/intro.jpg&amp;amp;theVolume=75&amp;amp;startPlayingOnload=no&amp;amp;popUpHelp=no&amp;amp;videoSmoothing=yes" width="360" height="270" type="application/x-shockwave-flash" loop="false" menu="false" quality="high" wmode="transparent" scale="noscale" salign="lt" bgcolor="#000000" allowscriptaccess="always"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now often&amp;nbsp;as developers we can pull out all stops and do some amazing things in a short time.&amp;nbsp;The problem is that this &lt;a href="http://idioms.thefreedictionary.com/make+a+rod+for+own+back"&gt;makes a rod for your own back&lt;/a&gt;. In other words, if the client or business partner doesn&amp;rsquo;t understand the intricacies and details of what goes on to achieve the results, their expectations are then set higher than is realistic. Bottom line: we are going to do whatever we can to meet the business needs of the business partner for their deadlines, but&amp;hellip; I&amp;rsquo;m going to need to successfully communicate the compromises and development follow up that will be needed in the following month.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-727400108445774872?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/727400108445774872/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=727400108445774872" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/727400108445774872?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/727400108445774872?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/09/real-men-don-sleep.html" title="Real Men Don&amp;#39;t Sleep" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;AkQHSHg4fyp7ImA9WB5aFUU.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-1886883269011134546</id><published>2007-09-12T17:12:00.001+08:00</published><updated>2007-09-12T17:12:19.637+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-09-12T17:12:19.637+08:00</app:edited><title>Inside the Agility Cube Excerpt</title><content type="html">&lt;p&gt;I was listening to the Javapolis &lt;a href="http://parleys.com/display/PARLEYS/Inside+the+Agility+Cube+%28Part+1%29?showComments=true"&gt;Inside the Agility Cube session&lt;/a&gt; and snorted at the following excerpt:&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;I know of a project that went into a kind of &lt;a href="http://en.wikipedia.org/wiki/Death_march_%28software_development%29"&gt;death march&lt;/a&gt; chaos and all kinds of other things. The project that I guess you could have.. probably take twenty to twenty five people to develop. At the last count there was something like seventy people involved. So.. slightly off the objective there. And they had originally instituted a two week cycle. And what happened.. eventually the management decided to shut down the agile process pump and one of the reasons was they said they didn&amp;rsquo;t like hearing bad news every two weeks.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I have a four year old boy who is just learning the trick of putting his fingers in his ears and saying I can&amp;rsquo;t hear you, I can&amp;rsquo;t hear you, I can&amp;rsquo;t hear you. He hasn&amp;rsquo;t learned it too well but that is very much what went on at this company. &lt;em&gt;&amp;ldquo;I don&amp;rsquo;t want to hear your feedback. Your feedback is not good. I thought that you guys said you would do Agile development and give us this feedback that it was always going to be good news&amp;rdquo;.&lt;/em&gt; No news is good news. This is not what it is about. The whole point of an agile process. The whole point of an iterative and incremental &amp;ndash; or in their case decremental &amp;ndash; development is you fail fast. If you&amp;rsquo;re going to get it wrong you may as well find out sooner rather than later. And you have to be prepared for that.&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p dir="ltr"&gt;Its tough working with a business partner or customer that expects to hear &amp;ldquo;good news&amp;rdquo; all the time. Its just not workable. To guarantee &amp;ldquo;good news&amp;rdquo; all the time, the performance bar needs to be set really low &amp;ndash; and that&amp;rsquo;s not in anyone&amp;rsquo;s best interest.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-1886883269011134546?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/1886883269011134546/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=1886883269011134546" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/1886883269011134546?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/1886883269011134546?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/09/inside-agility-cube-excerpt.html" title="Inside the Agility Cube Excerpt" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DU8ERXo7eyp7ImA9WB5bFk4.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-6445500337202071568</id><published>2007-09-01T17:10:00.001+08:00</published><updated>2007-09-01T17:10:04.403+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-09-01T17:10:04.403+08:00</app:edited><title>MacroView Excel Addin V1.3.0</title><content type="html">&lt;p&gt;We&amp;rsquo;ve released V1.3.0 of the &lt;a href="http://sencom.com.au/excel.html"&gt;MacroView Excel Add-in&lt;/a&gt; software product just this week. Its a package that we&amp;rsquo;ve developed for &lt;a href="http://sencom.com.au/"&gt;Sentient Computing&lt;/a&gt; who are one of our business partners. Sentient sell the software as part of their suite of MacroView &lt;a href="http://en.wikipedia.org/wiki/SCADA"&gt;SCADA&lt;/a&gt; products. It allows an end user to get access to both current historical information from their manufacturing, process control or other such industrial plant from within the Excel spreadsheet environment. Being &amp;ldquo;head-down bum-up&amp;rdquo; (i.e. really busy) most of the time developing software I don&amp;rsquo;t talk about our successes or what we can do for business partners enough. Its something thats on the cards to rectify in the coming months.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Back to the Excel addin release. The updated documentation can be found over &lt;a href="http://torqsoftware.com/ProjectDocs/MacroView/ExcelAddin/"&gt;here&lt;/a&gt;. The main feature addition in this release is native support for the Excel 2007 ribbon. Check it out below. I personally find the ribbon approach in the Office 2007 product range to be a huge improvement for the most part. It is frustrating occasionally when a feature you remember from Office V-Previous just &amp;ldquo;can&amp;rsquo;t be found&amp;rdquo; in the ribbon UI. Fortunately the command needs for the MacroView ribbon tab are manageable in number and fit easily within a single ribbon tab:&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="" src="http://torqsoftware.com/blogs/apolon/images/MacroViewExcel130Ribbon.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I particularly like the Value and Table buttons. By default, mouse clicks on these will initiate the most common Value and Table data query respectively (an entity value and a historical trend data table). Its only if the advanced query types are needed does the user need to click on the drop down arrow and select from all the different query types available for that category:&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="" src="http://torqsoftware.com/blogs/apolon/images/MacroViewExcel130RibbonDropDown.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The value queries allow you to associate a &lt;a href="http://www.sencom.com.au/macroview.html"&gt;MacroView&lt;/a&gt; value with a cell and then update the value from the &amp;ldquo;real world&amp;rdquo; on demand or in a continuous update mode. You can use these live values in other calculations or as inputs to a graphic visualization such as a pie chart:&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="" src="http://torqsoftware.com/blogs/apolon/images/MacroViewExcel130LiveValues.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The product user can also access &lt;a href="http://www.sencom.com.au/macroview.html"&gt;MacroView&lt;/a&gt; historical data and similarly perform calculations and display charts using that data. Sentient sell the Excel addin as part of the product range. If your business is interested in developing a software product that extends any of the Microsoft Office software then &lt;a href="mailto:apolon@torqsoftware.com"&gt;contact me&lt;/a&gt; to discuss the possibilities. Similarly if your business would benefit from automating part of your workflow with custom software its worth us talking.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="" src="http://torqsoftware.com/blogs/apolon/images/MacroViewExcel130History.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-6445500337202071568?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/6445500337202071568/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=6445500337202071568" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6445500337202071568?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6445500337202071568?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/09/macroview-excel-addin-v130.html" title="MacroView Excel Addin V1.3.0" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;Ck4GQnw9eip7ImA9WB5UEUo.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-2469737456374810891</id><published>2007-08-15T17:42:00.001+08:00</published><updated>2007-08-15T17:42:03.262+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-08-15T17:42:03.262+08:00</app:edited><title>TorqObject Database Decoupling</title><content type="html">&lt;p&gt;We use an in-house framework for building applications and the subject of how we decouple&amp;nbsp;business domain classes from a particular data source recently came up. This blog post provides a quick overview of the core Torq framework classes/interfaces and how they are decoupled from particular database implementations. A business domain class that is to leverage the framework needs to implement the ITorqObject interface. The properties and methods of this interface include functionality related to a Torq specific reflection extension, authorization, property change events, list events, a parent object in the case of object composition scenarios and most importantly the concept of an object source and an object mapper. Every ITorqObject instance is associated with an ITorqObjectSource which defines where it is &amp;ldquo;stored&amp;rdquo; and an ITorqObjectMapper instance whose responsibility is to map between the in-memory object world and the object source. In addition there is an ITorqList&amp;lt;T&amp;gt; list interface that extends the standard IList&amp;lt;T&amp;gt; definition with Torq specific reflection knowledge.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Torq Foundation Core Interfaces" src="http://torqsoftware.com/blogs/apolon/images/Torq_20Foundation_20Core_20Interfaces.png" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="left"&gt;An example of&amp;nbsp;an implementation&amp;nbsp;of&amp;nbsp;the ITorqObjectSource and ITorqObjectMapper interfaces is&amp;nbsp;where a &lt;a href="http://matisse.com/"&gt;Matisse&lt;/a&gt;&amp;nbsp;object database is used in deployment.&amp;nbsp;Fresher have their own Matisse specific API and means of generating .NET classes from an ODL definition or a running database. The problem with using that approach is that the application code is then strongly tied to that API and also the representation of list relationships in the generated code is spread across multiple methods (get, add, remove etc). The approach taken with the Torq framework is to provide an implementation of the ITorqObjectSource and ITorqObjectMapper interfaces that is Matisse specific. The diagram below indicates the main classes involved. Fortunately the Matisse API provides the MtObjectFactory class that can be overridden to provide application specific object creation during interaction with an MtDatabase instance. The MatisseObjectMapper class is-a MtObject and it will create an associated domain object (an ITorqObject instance) as needed. It then provides the data mapping functionality for the ITorqObject instance via its set of Get/Set prefixed methods for various core and&amp;nbsp;parameterized types. Since Matisse is an object database, the mapping is fairly trivial when compared to the mapping needed to an RDBMS.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Matisse Mapping Classes" src="http://torqsoftware.com/blogs/apolon/images/Matisse_20Mapping_20Classes.png" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="left"&gt;The ITorqObject interface is used where-ever the concept of a &amp;ldquo;torq domain object&amp;rdquo; is needed. This allows any base class to implement this interface to work with the framework. Practically all our domain classes are derived from the TorqObject class which provides a default implementation of ITorqObject. This default implementation provides a heap of protected convenience methods for interaction with the ITorqObjectMapper and ITorqObjectSource associated with the domain object.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="TorqObject Class" src="http://torqsoftware.com/blogs/apolon/images/TorqObject_20Class.png" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="left"&gt;In the domain classes, there is a small bit of coding overhead needed for every property or relationship. There is the static definition of a Torq specific reflection object. It is uninitialized in the source code, but the framework initializes these static properties automatically when a business domain assembly is loaded. A private field is then used to store the results of any Get/Set methods. The TorqObject base class then forwards Get/Set method calls onto its ITorqObjectMapper instance to get data from the object source and update the object source. The following example extract shows how this is achieved for a string property. Note that the GetProperty and SetProperty methods provide an &lt;em&gt;interception&lt;/em&gt; point for the framework to insert functionality related to authorization, logging and persistence. Note that the Torq specific reflection information (TorqProperty in the example) provides a useful mechanism for accessing strongly typed class level information in the code. An example is in databinding, where you can use say Party.NameProperty instead of a string literal in defining what property a UI control is being bound to.&lt;/p&gt;&lt;br /&gt;&lt;div style="FONT-WEIGHT: bold; FONT-SIZE: 11pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Consolas"&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;TorqProperty&lt;/span&gt; NameProperty;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Name &lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; GetProperty( NameProperty, &lt;span style="COLOR: blue"&gt;ref&lt;/span&gt; name );}&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { SetProperty( NameProperty, &lt;span style="COLOR: blue"&gt;ref&lt;/span&gt; name, &lt;span style="COLOR: blue"&gt;value&lt;/span&gt; ); }&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;br /&gt;&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p align="left"&gt;Here&amp;rsquo;s an example of the implementation of a list property on a business domain object.&amp;nbsp;Note that the ITorqObjectSource will define the type of the list. Each source can provide its own ITorqList&amp;lt;T&amp;gt; implementation to handle object source specific needs.&lt;/p&gt;&lt;br /&gt;&lt;div style="FONT-WEIGHT: bold; FONT-SIZE: 11pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Consolas"&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;TorqListProperty&lt;/span&gt; ContactMechanismsProperty;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ITorqList&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;IContactMechanism&lt;/span&gt;&amp;gt; contactMechanisms;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ITorqList&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;IContactMechanism&lt;/span&gt;&amp;gt; ContactMechanisms &lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; GetProperty( ContactMechanismsProperty, &lt;span style="COLOR: blue"&gt;ref&lt;/span&gt; contactMechanisms ); }&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;br /&gt;&lt;p align="left"&gt;The Torq framework will evolve over time and it would be handy to reduce the small coding overhead associated with each class property. The use of a private field as an intermediate in memory storage could go and it would be great to be able add more of this code automatically either at run time or as a post compile step. A significant advantage of the current approach is its much easier to use a debugger and just step through the source code. Fancier approaches such as runtime code generation make it conceptually more difficult to debug at run time.&lt;/p&gt;&lt;br /&gt;&lt;p align="left"&gt;This blog post provided a quick dip into the foundation of the Torq framework we use for developing business domain products. The framework is intended purely for in-house use. I decided to put these details up to provide an overview of how you could leverage an OO database such as Matisse but not tie your application code to it. Note that I am an advocate of the Matisse database and do recommend you check it out. Regardless its also beneficial in many scenarios to not tightly couple application code to a specific data store.&lt;/p&gt;&lt;br /&gt;&lt;p align="left"&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-2469737456374810891?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/2469737456374810891/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=2469737456374810891" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/2469737456374810891?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/2469737456374810891?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/08/torqobject-database-decoupling.html" title="TorqObject Database Decoupling" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DE8CR3o8cSp7ImA9WB5VGE0.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-1723799328154478137</id><published>2007-08-11T12:34:00.001+08:00</published><updated>2007-08-11T12:34:26.479+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-08-11T12:34:26.479+08:00</app:edited><title>New Development Machine</title><content type="html">&lt;p&gt;I upgraded to a quad-core &lt;a href="http://processorfinder.intel.com/details.aspx?sSpec=SLACR"&gt;Q6600&lt;/a&gt; based system with two Raptor 10K rpm drives and 4GB RAM this last week. The problem with being my main Windows development machine is that there so many packages to install and configuration to re-setup that it takes a day plus some residue to finish the changeover. The decision was made to stay with Windows XP with this upgrade as I just don&amp;rsquo;t want to spend the time chasing down compatibility issues with Windows Vista and the myriad number of software packages that I depend upon on different software projects.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Apart from taking a day to do the full changeover, things went pretty smoothly. Having the &amp;ldquo;old&amp;rdquo; AMD X2 based system there and available to confirm the package list and&amp;nbsp;configuration settings helped a lot though. I also took the opportunity to get another 22 inch monitor and move to a dual monitor development set up. It&amp;rsquo;s not quite symmetrical but the cost differential for going to another 24 inch monitor wasn&amp;rsquo;t justifiable at the current point in time. My long term goal is to have 3 24 inch or 30 inch monitors.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The quad core and 10k rpm combination has definitely made a difference to my workflow. The system is a lot more responsive when lots of tasks are happening at the same time e.g. developing in visual studio with Resharper, running automated tests, running virtual machines needed for the tests, going&amp;nbsp;back and forth to Outlook&amp;nbsp;etc. I actually thought that compile times hadn&amp;rsquo;t actually changed much but flipping back to the old dev machine showed me that there was a clear improvement. Its amazing how quickly you get used to improvements and forget what it was like before the change.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Take a &lt;a href="http://dictionary.reference.com/browse/squiz"&gt;squiz&lt;/a&gt; at a couple of photos of my work environment. I like to keep things pretty sparse, but this would be the cleanest it will get normally. The desk is an electric desk that can be repositioned at different times of the day so my back varies its position regularly. The first photo is in the seated position, whilst the next is in the standing position. The electric desk was from &lt;a href="http://www.ergomotion.com.au/motiondesk.htm"&gt;Ergomotion&lt;/a&gt; and while expensive has been worth it for me.&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Desk2007Seated" src="http://torqsoftware.com/blogs/apolon/images/Desk2007Seated_small.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Desktop2007Standing" src="http://torqsoftware.com/blogs/apolon/images/Desktop2007Standing_small1.jpg" border="0" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-1723799328154478137?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/1723799328154478137/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=1723799328154478137" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/1723799328154478137?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/1723799328154478137?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/08/new-development-machine.html" title="New Development Machine" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;CE4MQn45eip7ImA9WB5TFk0.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-4120345252657685931</id><published>2007-05-31T17:15:00.000+08:00</published><updated>2007-05-31T17:16:23.022+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-05-31T17:16:23.022+08:00</app:edited><title>Blogger FTP Frustrations</title><content type="html">&lt;p&gt;I haven't been able to publish a blog post for a three or so weeks now because of a problem in the Blogger FTP publishing operation. The last post was queued up in the Blogger database wasn’t able to be written to the web site. The Blogger error output had lots of repeated lines similar to the following (after a long timeout period)&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;/blogger_ftp/archive/2007_05_01_archive.html java.net.ConnectException: Connection timed out&lt;br /&gt;/blogger_ftp/2007/04/silverlight-based-on-microsoft-net.html java.net.SocketException: Broken pipe&lt;br /&gt;/blogger_ftp/2004/06/microsoft-developer-target-profiles.html java.net.SocketException: Broken pipe&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;There’s a bunch of FTP related problem descriptions on the Blogger group pages, but no real consistent solutions. There were entries like “created another FTP account and then it just started working”. I sent a couple of submissions to the black hole that is Blogger support. In the end I decided to set up a Linux FTP server using dynamic DNS and then reconfigure Blogger to transfer to that temporarily. All the FTP transfers succeeded, so attention moved to the web hoster.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;At first the hoster response was something along the lines of “document step by step how to reproduce the problem”. Sometimes it seems that support staff and software or software service companies don’t actually read the first couple of emails you send them. I do get incredibly frustrated when support people ask for a step-by-step instruction set on how they can reproduce the problem even when the contact email explicitly indicates that the problem can’t be reproduced at will by the support person and the reason why.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In an effort to resolve the problem, I quickly looked at alternative blogging platforms. Wordpress was very promising. It was easy to import all the Blogger posts, but the big problems for me were the inability to embed flash content in posts or import third party themes. I had a quick look at Community Server and dasBlog, but didn’t really want to go through the setup and ongoing maintenance hassle. Wordpress hosting solutions were an option, but they cost as much as my existing web site. In the end, the approach taken was to user Blogger custom domains. Yes Blogger is a dog of a blogging platform that is moving glacially considering the resources that Google has available. Regardless its a pain to move the blog elsewhere.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-4120345252657685931?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/4120345252657685931/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=4120345252657685931" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4120345252657685931?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4120345252657685931?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/05/blogger-ftp-frustrations.html" title="Blogger FTP Frustrations" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0QHSX0yfSp7ImA9WBFaFUg.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-5747692499266320883</id><published>2007-05-19T13:08:00.001+08:00</published><updated>2007-05-19T13:08:58.395+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-05-19T13:08:58.395+08:00</app:edited><title>ObjectDisposedException closing Form in click handler</title><content type="html">&lt;p&gt;Okay here's a weird .NET Windows Forms error scenario. One of the applications had a scenario where an ObjectDisposedException was occurring, but for only one of the users. The other users that worked that the particular application functionality involved did not experience the error. I finally managed to reproduce the problem in the office by initiating the application task, clicking the &amp;ldquo;Create Job&amp;rdquo; button and then&amp;nbsp;immediately going to another application and flipping between other windows that have nothing to do with the application. My guess is that the user that experiences the issue interacts with the system in a particular GUI manner that uncovers the problem.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The stack trace when the ObjectDisposedException looks like this:&lt;/p&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 8pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Lucida Sans Typewriter"&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.Control.CreateHandle() + 0x1ff bytes&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.Control.Handle.get() + 0x77 bytes&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.Control.PointToScreen(System.Drawing.Point p) + 0x38 bytes&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs mevent = {X = 36 Y = 7 Button = Left}) + 0x79 bytes&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks) + 0xf2 bytes&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x544 bytes&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.ButtonBase.WndProc(ref System.Windows.Forms.Message m) + 0x151 bytes&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.Button.WndProc(ref System.Windows.Forms.Message m) + 0x2b bytes&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0xd bytes&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0xd6 bytes&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The Button.MouseUp method attempts to identify where on the screen the mouse up event occurred when the button has already been disposed. Being able to reproduce the problem in the office, at least allowed me to identify which button was involved. The button click handler code is pretty standard for a button that does some work then closes the form:&lt;/p&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 8pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Lucida Sans Typewriter"&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; private void HandleCreateClick( object sender, &lt;span style="COLOR: teal"&gt;EventArgs&lt;/span&gt; e )&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// Application specific processing goes here in the real code.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Close();&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;After much experimentation using the debugger and Reflector, it looks like under normal circumstances the Close() causes&amp;nbsp;a side effect of the button losing focus, which then clears internal System.Windows.Forms.Control flags which ensure that the OnMouseUp method doesn&amp;rsquo;t attempt to do any mouse-up event handling. For some reason, in my particular application scenario, the OnLostFocus method is not called and OnMouseUp processing attempts to get the mouse coordinates which then causes the ObjectDisposedException to be thrown. No matter what I tried, I could not reproduce the problem in&amp;nbsp;a simplified project that could be forwarded onto Microsoft to look into. The following workaround was used to stop the problem happening in the application:&lt;/p&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 8pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Lucida Sans Typewriter"&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; private void HandleCreateClick( object sender, &lt;span style="COLOR: teal"&gt;EventArgs&lt;/span&gt; e )&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// Application specific processing goes here in the real code.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// The following line is a workaround for a problem where the createButton's&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// MouseUp event was throwing an ObjectDisposedException. In most scenarios&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// where a button click event handler Closes the Form, a LoseFocus event&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// resets the internal flags which causes the MouseUp event processing to&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// skip any attempts to access button information. For some reason this&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// createButton scenario would occassionally not get the LoseFocus event&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// and cause an exception to be thrown. Setting the Enabled flag to false&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// is a workaround which clears internal button flags so that no&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// MouseUp processing occurs. This works around the problem.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; createButton.Enabled = false;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Close();&lt;/p&gt;&lt;br /&gt;&lt;p style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-5747692499266320883?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/5747692499266320883/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=5747692499266320883" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/5747692499266320883?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/5747692499266320883?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/05/objectdisposedexception-closing-form-in.html" title="ObjectDisposedException closing Form in click handler" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DkQHQX4_eyp7ImA9WBFVF00.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-315641916206937103</id><published>2007-04-16T14:18:00.001+08:00</published><updated>2007-04-16T14:18:50.043+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-04-16T14:18:50.043+08:00</app:edited><title>Silverlight: Based on the Microsoft .NET Framework</title><content type="html">&lt;p&gt;I came across a blog post from &lt;a href="http://blog.brightcove.com/blog/"&gt;Brightcove&lt;/a&gt; which made my day. It indicated that Microsoft&amp;rsquo;s new name for &lt;a href="http://en.wikipedia.org/wiki/WPF/E"&gt;WPF/E&lt;/a&gt; was Silverlight and that Brightcove would be looking at using the technology. So I hopped over to the supplied links and did a few searches. Some useful web pages on the subject include:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/silverlight/"&gt;http://www.microsoft.com/silverlight/&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/presspass/press/2007/apr07/04-15WPFEPR.mspx"&gt;http://www.microsoft.com/presspass/press/2007/apr07/04-15WPFEPR.mspx&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/somasegar/archive/2007/04/15/silverlight-the-next-generation-web-media-experiences.aspx"&gt;http://blogs.msdn.com/somasegar/archive/2007/04/15/silverlight-the-next-generation-web-media-experiences.aspx&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;The main &lt;a href="http://www.microsoft.com/silverlight/"&gt;Silverlight web site&lt;/a&gt;&amp;nbsp;contains these wonderful words:&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;&amp;ldquo;Based on the Microsoft .NET Framework&amp;rdquo;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;Man that&amp;rsquo;s good to hear. The last CTP of the &lt;a href="http://en.wikipedia.org/wiki/WPF/E"&gt;WPF/E&lt;/a&gt; technology had no &lt;a href="http://en.wikipedia.org/wiki/Common_Language_Runtime"&gt;CLR&lt;/a&gt; functionality at all and I was starting to worry. The &lt;a href="http://en.wikipedia.org/wiki/.NET_Framework"&gt;.NET&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Common_Language_Runtime"&gt;CLR&lt;/a&gt; functionality opens up a whole world of functionality to Torq Software business partners (my customers). I was surprised to see news of any of this sort of announcement until the &lt;a href="http://mix07.com/"&gt;Mix07&lt;/a&gt; conference started. It will be good to start seeing some technical details of the Silverlight &lt;a href="http://en.wikipedia.org/wiki/Common_Language_Runtime"&gt;CLR&lt;/a&gt; functionality presumably by next month.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The only disappointing aspect is that there is absolutely no mention of Linux support. This would make the claim that it is &amp;ldquo;cross platform&amp;rdquo; much more reasonable instead of being limited to Windows and Mac. We&amp;rsquo;ll have to see how things pan out, but I&amp;rsquo;m hoping Microsoft &amp;ldquo;sees the light&amp;rdquo; and either provides a Linux version or at least not hamper the open source versions of the technology that will likely result.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-315641916206937103?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/315641916206937103/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=315641916206937103" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/315641916206937103?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/315641916206937103?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/04/silverlight-based-on-microsoft-net.html" title="Silverlight: Based on the Microsoft .NET Framework" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CUIAQXozfyp7ImA9WBFWFUs.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-7253001408188140621</id><published>2007-04-03T09:25:00.001+08:00</published><updated>2007-04-03T09:25:40.487+08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-04-03T09:25:40.487+08:00</app:edited><title>The Fallacy of Local Optimization</title><content type="html">&lt;p&gt;Scoble has an &lt;a href="http://www.podtech.net/scobleshow/technology/1414/joel-spolsky-the-famous-blogger-on-software-productivity"&gt;interview with the founders of Fog Creek&lt;/a&gt;. I smiled at this quote from &lt;a href="http://joelonsoftware.com/"&gt;Joel Spolsky&lt;/a&gt;:&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;That&amp;rsquo;s the big joke inside of Microsoft. Developers are rewarded for writing a lot of code and fixing a lot of bugs. So the incentive is to write a lot of code and write it very quickly.. Churn it..piles of code&amp;hellip; buggy as all hell and then you get a bunch of bug reports and you fix them all and you will look a lot better than a slow methodical developer that gets from point A to point B in the same amount of time or even in less time because of the funny way that that metric might be used.&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;This is an example of &amp;ldquo;&lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/01/29/Once-Upon-a-Team.aspx"&gt;the fallacy of local optimization&lt;/a&gt;&amp;rdquo; which I first came across as a concept&amp;nbsp;in the Poppendieck&amp;rsquo;s &lt;a href="http://www.poppendieck.com/ld.htm"&gt;Lean Software Development&lt;/a&gt; book. Basically if you try and optimize locally (increase software development and reduce software faults/bugs) then you are likely to be far less effective and even introduce unwanted second order effects than if you optimized the whole. Lean principals are based on optimizing the whole and not optimizing a portion of your system (whatever it is). So basing incentives and on measuring some aspect of your business/process one level higher than you would expect is more effective for the business as a whole. Providing incentives or penalizing developers based on source code output and bug fix counts can potentially move developers to produce much more buggy code rather than the end goal of better quality software at an acceptable development cost. What I love about the lean principals is that they are &amp;ldquo;truisms&amp;rdquo; that apply to more than just software development.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-7253001408188140621?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/7253001408188140621/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=7253001408188140621" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/7253001408188140621?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/7253001408188140621?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/04/fallacy-of-local-optimization.html" title="The Fallacy of Local Optimization" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CkEHRX88cSp7ImA9WBFQEk4.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-6727141031307828402</id><published>2007-03-07T10:11:00.001+09:00</published><updated>2007-03-07T10:23:54.179+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-03-07T10:23:54.179+09:00</app:edited><title>Office 2007 UI Licensing Bull</title><content type="html">&lt;p align="left"&gt;I just upgraded to the Infragistics 2007 Volume 1 release which includes support for a ribbon based user interface. It was annoying to come across this dialog during the installation:&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="InfragisticsRibbonUI" src="http://www.torqsoftware.com/blogs/apolon/images/InfragisticsRibbonUI.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="left"&gt;I consider myself a pragmatist and don’t think Microsoft is the evil empire or anything, but… when they pull this sort of thing, it peeves me off. The implication is that software developers need to request for the right to create a user interface that is similar to the Office 2007 ribbon user interface – not the same, just similar. In my opinion, the ribbon UI is a great improvement on previous Office user interfaces with respect to browsing through commands but its not revolutionary. Breaking it down, its just a bunch of tabbed command windows each with a controls grouped together in associated panels. Tabbed windows have existed for ages in windowing systems. So have panels, icons, buttons etc. Given this I don’t think Microsoft have any IP ownership of this style of UI except for the very specific layout/graphics used in MS Word, Excel etc. Now the question for me is if I use the Infragistics ribbon implementation, do I have to ask permission of Microsoft? Do I ignore this unreasonable request and if so is there a risk of being bullied by Microsoft’s legal machine. All in all, it sucks.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-6727141031307828402?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/6727141031307828402/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=6727141031307828402" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6727141031307828402?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6727141031307828402?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/03/office-2007-ui-licensing-bull.html" title="Office 2007 UI Licensing Bull" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CUUEQHoycCp7ImA9WBFSF00.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-3357383590184595274</id><published>2007-02-17T18:06:00.001+09:00</published><updated>2007-02-17T18:06:41.498+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-02-17T18:06:41.498+09:00</app:edited><title>CentOS Linux</title><content type="html">&lt;p&gt;We&amp;rsquo;ve been developing &lt;a href="http://www.sencom.com.au/macroview.html"&gt;MacroView&lt;/a&gt; on Linux since Redhat Linux 7.2 and have deployments on RH 7.2, 7.3, Fedora Core 1 and Fedora Core 5. After RH Linux 9.0, Redhat changed their distribution strategy and effectively their business model by moving all community efforts into the &lt;a href="http://fedora.redhat.com/"&gt;Fedora&lt;/a&gt; project and all commercial efforts into&amp;nbsp;&lt;a href="http://www.redhat.com/rhel/"&gt;RedHat Enterprise Linux&lt;/a&gt;&amp;nbsp;(RHEL). Their Enterprise Linux is protected somewhat from business competition by trademark law and not directly by copyright as the distribution is to my knowledge all &lt;a href="http://en.wikipedia.org/wiki/Gpl"&gt;GPL&lt;/a&gt; code. You can&amp;rsquo;t copy and distribute/sell RHEL because it would violate their trademarks. RHEL is also somewhat protected from business competition by being the defacto standard for commercial applications where source code isn&amp;rsquo;t provided.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Sidetrack: I&amp;rsquo;m not lawyer, so don&amp;rsquo;t treat this blog post as legal advice&amp;hellip; yada yada yada&amp;hellip;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Anyway, back to the point. Fedora releases are good stable releases but man do they come at a fast pace for an OS e.g. every six months or so. Its tough to plan product support around such a quickly moving target. This was obviously part of Redhat&amp;rsquo;s grand plan and it looks like it works pretty well. So Fedora is a good platform for MacroView systems, but the pace of releases makes it difficult to support as easily as an operating system with a slower release cycle. The problem with RHEL is the yearly subscription fees which I think are quite high given that its based on an open source free-as-in-beer base. Some MacroView customers would not have a problem with RHEL fees, but some would. The approach we have been taking is to stagger the support for Fedora Core versions i.e. skipping some version numbers.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;As part of an investigation into an alternative Linux OS support approach, I&amp;rsquo;m checking out the &lt;a href="http://centos.org/"&gt;CentOS distribution&lt;/a&gt;. CentOS stands for the Community ENTerprise Operating System. It is built from the RHEL source code but with Redhat trademark information removed. So its a reasonable basis for future potential use with MacroView. Customers that want Redhat support can go the RHEL route, whilst other customers can use CentOS. Both will have a longer release cycle than Fedora releases i.e. 6 months compared with 18 months to 2 years. Note that this all just experimentation at this stage, so nothing is written in stone.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Check out some of the screen shots from the CentOS install process. Feels familiar doesn&amp;rsquo;t it:&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Centos4InstallBoot" src="http://www.torqsoftware.com/blogs/apolon/images/Centos4InstallBoot.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Centos4Install1" src="http://www.torqsoftware.com/blogs/apolon/images/Centos4Install1.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Centos4Install2" src="http://www.torqsoftware.com/blogs/apolon/images/Centos4Install2.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Centos4Install3" src="http://www.torqsoftware.com/blogs/apolon/images/Centos4Install3.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Centos4Install4" src="http://www.torqsoftware.com/blogs/apolon/images/Centos4Install4.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Centos4Install5" src="http://www.torqsoftware.com/blogs/apolon/images/Centos4Install5.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Centos4Install6" src="http://www.torqsoftware.com/blogs/apolon/images/Centos4Install6.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;img alt="Centos4Install7" src="http://www.torqsoftware.com/blogs/apolon/images/Centos4Install7.jpg" border="0" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-3357383590184595274?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/3357383590184595274/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=3357383590184595274" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/3357383590184595274?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/3357383590184595274?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/02/centos-linux.html" title="CentOS Linux" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEUCQH87cSp7ImA9WBBaFUk.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-2955905196883333366</id><published>2007-01-23T17:47:00.000+09:00</published><updated>2007-01-23T17:51:01.109+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-01-23T17:51:01.109+09:00</app:edited><title>Linux Mini PC MacroView Demo</title><content type="html">I was preparing for a demo scenario today where MacroView Windows Desktop needs to connect to a Linux or Unix system to show X windows connectivity and integration. Because of this, just a straight Windows laptop wasn't enough. I also didn't want to have to depend on Internet or even Intranet access to proceed with any demonstrations. The hardware I'm going to use is a Linux (Fedora Core 5) server running MacroView and a Windows laptop running the various client side software packages that are going to be demonstrated. A Linux server was borrowed from Sentient Computing. Thats the Linux server on the left in the pictures. Its a sweet little unit and is made up of a 1.5GHz Pentium M processor, 1GB RAM and an 80GB hard disk. Man ... I can remember when PSTN modems were way bigger than the Linux box in question.&lt;br /&gt;&lt;br /&gt;The laptop is a Toshiba tablet with 512MB RAM and a 1.6MHz Pentium M. They're connected by a cross over ethernet cable. A nice aspect of the Fedora+mini-pc combination is that it boots without stopping even if no monitor, keyboard or mouse is connected. This means demo set up is quite easy. There is an external power supply which is a bit of a pain but all in all, the unit is quite nifty. The first picture below shows MacroView Windows Desktop with a VNC session running the KDE desktop. The second picture shows the MacroView XAML module running. The photos of the Toshiba screen are average and this is probably due to the nature of tablet pc screen surfaces.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://torqsoftware.com/blogs/apolon/images/MiniPCAndFedora.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://torqsoftware.com/blogs/apolon/images/MiniPCAndFedora.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://torqsoftware.com/blogs/apolon/images/MiniPCAndXaml.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://torqsoftware.com/blogs/apolon/images/MiniPCAndXaml.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-2955905196883333366?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/2955905196883333366/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=2955905196883333366" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/2955905196883333366?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/2955905196883333366?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/01/linux-mini-pc-macroview-demo.html" title="Linux Mini PC MacroView Demo" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0QAQHY_fSp7ImA9WBBaFU8.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-6522469188513481351</id><published>2007-01-23T11:49:00.000+09:00</published><updated>2007-01-23T12:02:21.845+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-01-23T12:02:21.845+09:00</app:edited><title>Ranorex and Screenscraping/Automation</title><content type="html">&lt;p&gt;After many web searches looking into screen scraping technologies for automating legacy Windows applications, I came across a testing automation product from &lt;a href="http://www.ranorex.com"&gt;Ranorex&lt;/a&gt;. It's oriented towards the development process, but technically could also be used to script/automate interaction with a legacy Windows appplication. Check out this screencast where interaction with a Nokia DB2 Manager windows program was automated.&lt;/p&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;embed name="wasp" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://torqsoftware.net/video/player/wasp.swf?theFile=http://torqsoftware.net/video/miscellaneous/RanorexAutomation.swf&amp;defaultImage=http://torqsoftware.net/video/player/intro.jpg&amp;amp;amp;theVolume=75&amp;startPlayingOnload=no&amp;amp;amp;popUpHelp=no&amp;amp;videoSmoothing=yes" type="application/x-shockwave-flash" allowscriptaccess="always" bgcolor="#000000" salign="lt" scale="noscale" wmode="transparent" quality="high" menu="false" loop="false" align="middle" height="600" width="800"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-6522469188513481351?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/6522469188513481351/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=6522469188513481351" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6522469188513481351?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6522469188513481351?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/01/ranorex-and-screenscrapingautomation.html" title="Ranorex and Screenscraping/Automation" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DEQFRXg6fyp7ImA9WBBaEEo.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-4240446756340090022</id><published>2007-01-17T10:44:00.000+09:00</published><updated>2007-01-18T08:25:14.617+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-01-18T08:25:14.617+09:00</app:edited><title>xops3 Command Line Arguments</title><content type="html">I recently received a request from a customer for information on all the command line options for the &lt;a href="http://sencom.com.au/macroview.html"&gt;MacroView&lt;/a&gt; xops3 executable. This post is a quick summary of the command line options:&lt;br/&gt; &lt;br/&gt; &lt;div&gt;  &lt;table border="1" cellpadding="3" cellspacing="0" width="100%"&gt;  &lt;tbody&gt;  &lt;tr&gt;  &lt;td style="VERTICAL-ALIGN:top" width="15%"&gt;  -checkMemory&lt;br/&gt;  &lt;/td&gt;  &lt;td style="VERTICAL-ALIGN:top"&gt;  Runs xops3 in a memory buffer checking mode. This mechanism was included in the original MacroView Version 3 development from ~1992 as a means of chasing down memory faults in C++ applications. It is rarely used these days as tools such as Purify provide a more effective memory debugging approach. When used, every dynamically allocated memory segment is logged in a memory manager and header/footer segments surround the memory allocation. A memory manager then checks for allocation/deallocation pairs and memory overruns. It reports on any memory corruptions found and detects memory leaks. Note that program execution speed is of course much slower when run in this mode.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -file &amp;lt;dgtfile&amp;gt;&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  By default xops3 displays the base.dgt file in the configuration directory. This command line option allows a different startup graphic dgt file to be used.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -updateRate &amp;lt;seconds&amp;gt;&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  Sets the default scan rate for graphic updates in the xops3 session. This can be over-ridden by individual graphic metafiles in the dgt header.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -reportTimes&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  Reports on graphic dgt file load and display times. It is useful for measuring draw time performance.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -edit&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  Puts xops3 in EzEng configuration and editing mode.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -highlight&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  Displays dynamic graphic objects with a rectangular highlight box to allow an engineer to see the bounds of the object at run time.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -processEvents &amp;lt;n&amp;gt;&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  The metascript variable management system in xops3 will automatically inform all graphic objects that reference it that the variable has changed. The graphic objects can then immediately update their graphic state. The process events count defines how many of these events are process in a cycle. Note that a graphic object display update can potentially cause the variable to be set again. The event processing limit stops this potential recursion from continuing indefinitely. A zero value turns off the variable change event processing which means that graphic display updates occur at the dgt page's update rate. The default is that all events in the variable set event queue are processed.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -olderr&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  The xops3 error processing system handles each internally generated error message and either stores the error in an internal (table variable based) list or sends the error as a system alarm to the system message queue. Previous versions of xops3 sent all internal errors to the system message queue and didn't keep an internal list. The -olderr command line option reverts operation to this older message processing implementation.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -noConfig&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  Runs the xops3 session with no configuration directory i.e. the entities, sources and type attribute databases are not read.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -lastGoodValue&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  By default, xops3 expects a shared memory driver to update an entity.attribute value on a regular basis and will display -999 values if it is not updated regularly. The determination of "regular" is data source specific and is based on the requested update rate configured in that data source. The -lastGoodValue command line option turns this check off so that the last good value is displayed even if the communications driver is failing to meet the configured update rate for that entity.attribute. This functionality is not supported in the Windows version of the executable.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -consoleSet&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  A defunct command line option for an xops3 feature called "Console Sets" that is no longer supported.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -letScript &amp;lt;filename&amp;gt;&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  Instructs xops3 to run a metascript from the supplied file every time a LET command is executed on a PLC or sorted image data source entity.attribute. The metascript is run with 3 arguments in the following order: entity name, attribute name and a value string. This allows xops3 to perform LET action side effects across a whole graphic configuration instead of having to embed calls throughout a graphic configuration.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td width="15%"&gt;  -iocount&lt;br/&gt;  &lt;/td&gt;  &lt;td width="50%"&gt;  Reports the IO count for the current configuration. This is the number of entity.attribute instances derived from the configuration. It is also the value used for IO count licensing checks.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td style="VERTICAL-ALIGN:top"&gt;  -dlm&lt;br/&gt;  &lt;/td&gt;  &lt;td style="VERTICAL-ALIGN:top"&gt;  A defunct command line option for an xops3 feature for logging database changes that is no longer supported.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td style="VERTICAL-ALIGN:top"&gt;  -metascriptProgramTime &amp;lt;seconds&amp;gt;&lt;br/&gt;  &lt;/td&gt;  &lt;td style="VERTICAL-ALIGN:top"&gt;  Sets the maximum amount of time a metascript can take to run within the xops3 GUI environment before it is automatically terminated. The default is 10 seconds which is also the minimum setting. A value of -1 turns of the maximum execution time checks.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td style="VERTICAL-ALIGN:top"&gt;  -startMaximized&lt;br/&gt;  &lt;/td&gt;  &lt;td style="VERTICAL-ALIGN:top"&gt;  Starts xops3 in a maximized window state rather than the default window size.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;  &lt;td style="VERTICAL-ALIGN:top"&gt;  Xt command line arguments&lt;br/&gt;  &lt;/td&gt;  &lt;td style="VERTICAL-ALIGN:top"&gt;  xops3 on Unix/Linux also supports standard Xt command line arguments such as -geometry.&lt;br/&gt;  &lt;/td&gt;  &lt;/tr&gt;  &lt;/tbody&gt;  &lt;/table&gt; &lt;/div&gt; &lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-4240446756340090022?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/4240446756340090022/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=4240446756340090022" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4240446756340090022?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4240446756340090022?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/01/xops3-command-line-arguments.html" title="xops3 Command Line Arguments" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0IDRHk5eCp7ImA9WBBbFEQ.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-4005182044398856337</id><published>2007-01-11T15:00:00.000+09:00</published><updated>2007-01-11T15:06:15.720+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-01-11T15:06:15.720+09:00</app:edited><title>Weird ImageListStreamer InvalidOperationException</title><content type="html">&lt;p&gt;One of our MacroView Studio customers sent a strange stack trace from an application crash yesterday. It's strange in that the standard Windows Forms ImageListStreamer class is where the exception occurs. The exception being thrown is a TargetInvocationException wrapping an InvalidOperationException and occurs as a result of very basic form constructor code which is run many times in the application and hence many users will run that code during normal operation. As is typical with tough to resolve faults, I can't reproduce it in the office and will wait for more information from the customer if it occurs again. Regardless the symptoms and some results of web research into the problem has been posted here for any other poor souls that encounter it and also for my own benefit as a record. Here's the stack trace:&lt;/p&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="font-family:Arial,sans-serif;font-size:85%;"&gt;&lt;code&gt;Exception Details:&lt;br /&gt;System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---&amp;gt; System.InvalidOperationException: Loading of the ImageList did not succeed.&lt;br /&gt;   at System.Windows.Forms.ImageListStreamer..ctor(SerializationInfo info, StreamingContext context)&lt;br /&gt;   --- End of inner exception stack trace ---&lt;br /&gt;   at System.RuntimeMethodHandle._SerializationInvoke(Object target, SignatureStruct&amp; declaringTypeSig, SerializationInfo info, StreamingContext context)&lt;br /&gt;   at System.RuntimeMethodHandle.SerializationInvoke(Object target, SignatureStruct declaringTypeSig, SerializationInfo info, StreamingContext context)&lt;br /&gt;   at System.Reflection.RuntimeConstructorInfo.SerializationInvoke(Object target, SerializationInfo info, StreamingContext context)&lt;br /&gt;   at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)&lt;br /&gt;   at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)&lt;br /&gt;   at System.Runtime.Serialization.ObjectManager.DoFixups()&lt;br /&gt;   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)&lt;br /&gt;   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)&lt;br /&gt;   at System.Resources.ResourceReader.DeserializeObject(Int32 typeIndex)&lt;br /&gt;   at System.Resources.ResourceReader.LoadObjectV2(Int32 pos, ResourceTypeCode&amp; typeCode)&lt;br /&gt;   at System.Resources.ResourceReader.LoadObject(Int32 pos, ResourceTypeCode&amp; typeCode)&lt;br /&gt;   at System.Resources.RuntimeResourceSet.GetObject(String key, Boolean ignoreCase, Boolean isString)&lt;br /&gt;   at System.Resources.RuntimeResourceSet.GetObject(String key, Boolean ignoreCase)&lt;br /&gt;   at System.Resources.ResourceManager.GetObject(String name, CultureInfo culture, Boolean wrapUnmanagedMemStream)&lt;br /&gt;   at System.Resources.ResourceManager.GetObject(String name)&lt;br /&gt;   at Syncfusion.Windows.Forms.Edit.FindReplaceDlg.InitializeComponent()&lt;br /&gt;   at Syncfusion.Windows.Forms.Edit.FindReplaceDlg..ctor()&lt;br /&gt;   at Syncfusion.Windows.Forms.Edit.EditControl..ctor()&lt;br /&gt;   at MacroView.Script.MetascriptEditControl.InitializeComponent()&lt;br /&gt;   at MacroView.Script.MetascriptEditControl..ctor()&lt;br /&gt;   at MacroView.Script.MetascriptEditor.InitializeComponent()&lt;br /&gt;   at MacroView.Script.MetascriptEditor..ctor()&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Some links that are relevant:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://groups.google.com/group/microsoft.public.vsnet.general/browse_thread/thread/dd0089e9f0ebfac5/ff299ff6a1391c27?lnk=st&amp;q=ImageListStreamer+InvalidOperationException++Loading+of+the+ImageList+did+not+succeed&amp;amp;amp;rnum=1&amp;hl=en#ff299ff6a1391c27"&gt;Loading ImageList from resources fails in long test run&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.flashdevelop.org/community/viewtopic.php?t=29&amp;amp;sid=03c8ceb0c46fa4abde5805fc26dc07ad"&gt;Exception: Failed to load ImageList&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_20820589.html?qid=20820589"&gt;Threading Issue&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;It appears from web searches on the problem is that it is likely to be caused by accessing winform controls from other than the GUI thread and/or the visual styles functionality. This theory is re-enforced by looking at the code for the System.Windows.Forms.ImageListStreamer class serialization constructor using Reflector. The constructor includes native platform theming calls and synchronization support. I don't what goes on to cause the fault but it's very subtle and is rare. At first I suspected the Syncfusion (legacy) edit control of perform winform control actions across threads but the debugger showed that although the thread code was there, it shouldn't ever be called in the MacroView Studio application scenario.&lt;/p&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;&lt;!-- {\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Fixedsys;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs24       \cf10 IntPtr\cf0  ptr1 ="" UnsafeNativeMethods.ThemingScope.Activate();\par ??      try\par ??      \{\par ??            MemoryStream stream1 ="" new MemoryStream(this.Decompress(buffer1));\par ??            lock (ImageListStreamer.internalSyncObject)\par ??            \{\par ??                  SafeNativeMethods.InitCommonControls();\par ??                  this.nativeImageList ="" new ImageList.NativeImageList(SafeNativeMethods.ImageList_Read(\par ??                      new UnsafeNativeMethods.ComStreamFromDataStream(stream1)));\par ??            \}\par ??      \}\par ??      finally\par ??      \{\par ??            UnsafeNativeMethods.ThemingScope.Deactivate(ptr1);\par ??      \}\par ??      if (this.nativeImageList.Handle ="=" \cf10 IntPtr\cf0 .Zero)\par ??      \{\par ??            throw new \cf10 InvalidOperationException\cf0 (SR.GetString(\cf13 "ImageListStreamerLoadFailed"\cf0 ));\par ??      \}\par ??} --&gt;&lt;br /&gt;&lt;div    style="background: white none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Lucida Sans Typewriter;font-size:8pt;color:black;"&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      &lt;span style="color:teal;"&gt;IntPtr&lt;/span&gt; ptr1 = UnsafeNativeMethods.ThemingScope.Activate();&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      try&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      {&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;            MemoryStream stream1 = new MemoryStream(this.Decompress(buffer1));&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;            lock (ImageListStreamer.internalSyncObject)&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;            {&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;                  SafeNativeMethods.InitCommonControls();&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;                  this.nativeImageList = new ImageList.NativeImageList(SafeNativeMethods.ImageList_Read(&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;                      new UnsafeNativeMethods.ComStreamFromDataStream(stream1)));&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;            }&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      }&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      finally&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      {&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;            UnsafeNativeMethods.ThemingScope.Deactivate(ptr1);&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      }&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      if (this.nativeImageList.Handle == &lt;span style="color:teal;"&gt;IntPtr&lt;/span&gt;.Zero)&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      {&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;            throw new &lt;span style="color:teal;"&gt;InvalidOperationException&lt;/span&gt;(SR.GetString(&lt;span style="color:maroon;"&gt;"ImageListStreamerLoadFailed"&lt;/span&gt;));&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;code&gt;      }&lt;/code&gt;&lt;/p&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-4005182044398856337?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/4005182044398856337/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=4005182044398856337" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4005182044398856337?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4005182044398856337?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/01/weird-imageliststreamer.html" title="Weird ImageListStreamer InvalidOperationException" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DEUFSXYyfSp7ImA9WBBUGUs.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-2727804583097796342</id><published>2007-01-05T11:38:00.000+09:00</published><updated>2007-01-05T12:03:38.895+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-01-05T12:03:38.895+09:00</app:edited><title>Line Margin Selection Edit Control Request</title><content type="html">&lt;p&gt;This post is a request to &lt;a href="http://www.syncfusion.com"&gt;Syncfusion&lt;/a&gt; for an additional feature in their Edit Control functionality. The blog was just a convenient place to put a screencast related to the feature request submitted on their site. Showing a concept rather than describing it in text can often be a better way to communicate.&lt;/p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div align="center"&gt;&lt;embed name="wasp" pluginspage="http://www.macromedia.com/go/getflashplayer" align="middle" src="http://torqsoftware.net/video/player/wasp.swf?theFile=http://torqsoftware.net/video/miscellaneous/syncfusion/SyncfusionEditControlLineNumberMarginSelectionRequest.swf&amp;amp;defaultImage=http://torqsoftware.net/video/player/intro.jpg&amp;amp;theVolume=75&amp;amp;startPlayingOnload=no&amp;amp;popUpHelp=no&amp;amp;videoSmoothing=yes" width="800" height="600" type="application/x-shockwave-flash" allowscriptaccess="always" bgcolor="#000000" salign="lt" scale="noscale" wmode="transparent" quality="high" menu="false" loop="false"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-2727804583097796342?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/2727804583097796342/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=2727804583097796342" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/2727804583097796342?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/2727804583097796342?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2007/01/line-margin-selection-edit-control.html" title="Line Margin Selection Edit Control Request" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CE4NRn85eSp7ImA9WBBVEEU.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-4181197717394529095</id><published>2006-12-14T16:55:00.000+09:00</published><updated>2006-12-14T16:56:37.121+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2006-12-14T16:56:37.121+09:00</app:edited><title>ADX.NET V2.7 and V2.8 Registry Comparison</title><content type="html">&lt;p&gt;We’re just going through some versioning relating development hassles with the MacroView Excel Addin functionality. This blog post is just a means of placing some images in a public location for reference in the &lt;a href="http://www.add-in-express.com/"&gt;Addin Express&lt;/a&gt; forums. It appears that in Version 2.7 of ADX.NET the addin dll’s assembly version number was encoded into the registry as part of the COM component’s .NET load info. See the Assembly registry value below:&lt;img alt="AdxNetRegistryV27Image1" src="http://www.torqsoftware.com/blogs/apolon/images/AdxNetRegistryV27Image1.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;In addition, there was a child key whose name matched the DLL version number below the InprocServer32 key:&lt;img alt="AdxNetRegistryV27Image2" src="http://www.torqsoftware.com/blogs/apolon/images/AdxNetRegistryV27Image2.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now in V2.8 of ADX.NET, there doesn’t appear to be a sub-key and no version number in the Assembly value. This is probably better as there will likely be fewer deployment version issues in the future. Regardless, we are encountering hassles moving from V2.7 to V2.8 – probably because V2.8 can’t handle registering over the top of or unregistering the V2.7 registry info.&lt;img alt="AdxNetRegistryV28" src="http://www.torqsoftware.com/blogs/apolon/images/AdxNetRegistryV28.jpg" border="0" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-4181197717394529095?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/4181197717394529095/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=4181197717394529095" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4181197717394529095?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/4181197717394529095?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2006/12/adxnet-v27-and-v28-registry-comparison.html" title="ADX.NET V2.7 and V2.8 Registry Comparison" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEQDQn86cSp7ImA9WBBWE0o.&quot;"><id>tag:blogger.com,1999:blog-7163644.post-6911814024193255630</id><published>2006-12-06T09:48:00.000+09:00</published><updated>2006-12-06T11:32:53.119+09:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2006-12-06T11:32:53.119+09:00</app:edited><title>WPF/E Linkfest and thoughts</title><content type="html">&lt;p&gt;Yesterday a whole bunch of beta and CTP versions of new Microsoft software was made available. Included was the first CTP (Community Tech Preview) of the &lt;a href="http://en.wikipedia.org/wiki/WPF/E"&gt;WPF/E&lt;/a&gt; functionality that was mentioned in &lt;a href="http://torqsoftware.com/Default.aspx?tabid=79"&gt;my talk&lt;/a&gt; on &lt;a href="http://www.sencom.com.au/macroview.html"&gt;MacroView&lt;/a&gt; directions from the recent user group. Its an exciting time with lots of opportunites and pitfalls depending on which direction Microsoft takes this functionality in. This blog post contains a summary of a useful links relating to the recent Microsoft &lt;a href="http://www.microsoft.com/products/expression/en/default.mspx"&gt;Expression&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/WPF/E"&gt;WPF/E&lt;/a&gt; releases. It also includes some thoughts at the end that relate to the MacroView product direction.&lt;/p&gt;&lt;p&gt;First here’s a bunch of videos and screencasts on the new Expression and WPF/E functionality:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=263358#263358"&gt;Joe Stegman talks about the "WPF/E" CTP&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=263360#263360"&gt;Celso Gomes : Designing in "WPF/E"&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=263442#263442"&gt;Expression - Part One: The Overview&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=263513#263513"&gt;Expression - Part Two: Design&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=263549#263549"&gt;Expression - Part Three: Blend&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=263566#263566"&gt;Expression - Part Four: Web&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=263364#263364"&gt;"WPF/E" CTP Demos&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=263365#263365"&gt;Getting Started with "WPF/E"&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;A series of official Microsoft links relating to the release:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/wpfe"&gt;WPF/E Dev Center&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://forums.microsoft.com/MSDN/default.aspx?ForumGroupID=318&amp;SiteID=1"&gt;MSDN WPF/E Forums&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/products/expression/en/default.mspx"&gt;Expression Home Page&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/design/"&gt;Microsoft Design&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/presspass/features/2006/dec06/12-04expression.mspx"&gt;Official Press Release&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Scott Guthrie: &lt;a href="http://weblogs.asp.net/scottgu/archive/2006/12/04/announcing-the-release-of-the-first-wpf-e-ctp.aspx"&gt;Announcing the release of the first "WPF/E" CTP&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;A series of blog posts from the Expression development team:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/expression/archive/2006/12/04/expression-blend-goes-beta-big-changes-to-expression-design-ctp.aspx"&gt;Expression Blend goes Beta, Big Changes to Expression Design CTP&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/expression/archive/2006/12/04/announcing-the-microsoft-expression-blend-beta.aspx"&gt;Announcing the Microsoft Expression Blend Beta 1&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/expression/archive/2006/12/04/expression-blend-what-is-that.aspx"&gt;Expression Blend -- What Is That?&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/expression/archive/2006/12/04/expression-design-new-name-new-ui.aspx"&gt;Expression Design -- New name, new UI&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;A bunch of posts from bloggers (both Microsoft and others):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.adoguy.com/viewrant.aspx?id=2143"&gt;Demystifying "WPF/E"&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Infragistics: &lt;a href="http://blogs.infragistics.com/blogs/tony_lombardo/archive/2006/12/05/600.aspx"&gt;A first look at WPF/E&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Infragistics: &lt;a href="http://blogs.infragistics.com/blogs/grant_hinkson/archive/2006/12/04/599.aspx"&gt;Microsoft Expression Blend and WPF/E CTP&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.zdnet.com/Stewart/?p=188"&gt;First Look at Windows Presentation Foundation/Everywhere&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://notgartner.wordpress.com/2006/12/05/wpfe-expression-blend-expression-design-and-expression-web/"&gt;WPF/E, Expression Blend, Expression Design and Expression Web&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/charles_sterling/archive/2006/12/05/windows-presentation-foundation-for-the-macintosh-wpf-e.aspx"&gt;Windows Presentation Foundation for the Macintosh (WPF/e)&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://weblogs.asp.net/rweigelt/archive/2006/12/04/1123224.aspx"&gt;WPF/E CTP - Nice, but...&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.itwriting.com/blog/?p=71"&gt;WPF/E preview is out - but no cross-platform .NET for now&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Check out all of the samples that have been made available. Clicking on the samples will prompt for the download of the &lt;a href="http://en.wikipedia.org/wiki/WPF/E"&gt;WPF/E&lt;/a&gt; plugin for IE or Firefox which doesn’t take long to install.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=8AEEBE39-6699-4F4F-9732-CA732E57AE21&amp;amp;displaylang=en"&gt;Downloadable Microsoft Sample Pack&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a onclick="javascript:Track('ctl00_ctl01|ctl00_ctl12',this);" href="http://go.microsoft.com/fwlink/?linkid=79204&amp;clcid=0x409"&gt;Page Turn Media&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a onclick="javascript:Track('ctl00_ctl01|ctl00_ctl14',this);" href="http://go.microsoft.com/fwlink/?linkid=79205&amp;clcid=0x409"&gt;Media Library&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a onclick="javascript:Track('ctl00_ctl01|ctl00_ctl16',this);" href="http://go.microsoft.com/fwlink/?linkid=79206&amp;clcid=0x409"&gt;Sprawl Game&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a onclick="javascript:Track('ctl00_ctl01|ctl00_ctl18',this);" href="http://go.microsoft.com/fwlink/?linkid=79207&amp;clcid=0x409"&gt;Simple Video Playback&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a onclick="javascript:Track('ctl00_ctl01|ctl00_ctl20',this);" href="http://go.microsoft.com/fwlink/?linkid=79208&amp;amp;clcid=0x409"&gt;Film Strip Slideshow&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Photo Viewer: &lt;a href="http://www.nikhilk.net/WPFEAndScriptSharp.aspx"&gt;WPF/E and Script#&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://channel9.msdn.com/playground/wpfe/ch9player/default.html"&gt;Channel 9 Video Player&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blois.us/blog/2006/12/today-was-big-launch-of-couple.html"&gt;XAML Viewer&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://thewpfblog.com/?p=68"&gt;WPF/E and Flash Interactive Example!&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://thewpfblog.com/?p=69"&gt;More WPF/E and Flash Integration Madness!&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;My overall impression is that the functionality released is absolutely fantastic and sits well with the direction we have taken &lt;a href="http://www.sencom.com.au/macroview.html"&gt;MacroView&lt;/a&gt; in the last few years. Regardless there are a number of areas of concern. These include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Microsoft’s interpretation of what the E for “Everywhere” in WPF/E stands for! There has been regular mention of WPF/E being made available by partners on Linux which would be great. The concern is that Joe Stegman didn’t mention the L word once in the recent Channel 9 video even in sections which related to cross platform availability. Together with the recent &lt;a href="http://news.zdnet.com/2100-3513_22-6137444.html"&gt;shannigans&lt;/a&gt;/&lt;a href="http://blog.seattlepi.nwsource.com/microsoft/archives/108806.asp"&gt;rumblings&lt;/a&gt; with Novell and patents gives me cause for concern.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;There is too much of an emphasis on separating the designer and developer roles in the Microsoft releases. I personally believe that the world isn’t that black and white.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A seeming side effect of the designer/developer separation is the lack of Expression tools in MSDN offerings: &lt;a href="http://www.adoguy.com/viewrant.aspx?id=2145"&gt;Expression and MSDN Subscriptions&lt;/a&gt;. I have been subscribed to an MSDN Universal package for a number of years. Even though Microsoft have changed the product names to protect the guilty, I feel that a top level MSDN subscription should include every Microsoft product that could be construed to be useful to a developer. The universe is certainly getting small these days if the expression suite isn’t available to developers.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The lack of .NET integration at this point in time. There is a firmly stated direction for the integration of .NET byte code functionality so it will happen. The concern is more related to what they have to leave out and how interchangeable code that is used with WPF and WPF/E can practically be. We definitely don’t want a totally separate C# code base for WPF and WPF/E applications.&lt;/li&gt;&lt;/ul&gt;I am particularly impressed with:&lt;ul&gt;&lt;li&gt;The ease of integration between &lt;a href="http://en.wikipedia.org/wiki/WPF/E"&gt;WPF/E&lt;/a&gt; and javascript in the browser.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The small size (just over 1MB) of the plugin at this stage. Though having a small download is important for adoption rate, I am hoping Microsoft don’t go myopic on the download size and make some compromises for getting as much .NET environment functionality in as possible.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The media player functionality included.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The Microsoft Design (previously Graphic Designer) &lt;a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation"&gt;WPF&lt;/a&gt; makeover. Its an amazing technical feat given the product &lt;a href="http://en.wikipedia.org/wiki/Graphical_user_interface"&gt;GUI&lt;/a&gt; just a couple of months ago in the September CTP.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The inclusion of an extension API in the Microsoft Blend product (previously Interactive Designer). This will be particularly useful in being able to edit XAML files for use within a MacroView environment.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All in all the releases open up a bunch of functional possibilities for &lt;a href="http://www.sencom.com.au/macroview.html"&gt;MacroView&lt;/a&gt; development. The key of course will be the .NET support that is slated for around a February release.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='//blogger.googleusercontent.com/tracker/7163644-6911814024193255630?l=apolon.torqsoftware.net'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://apolon.torqsoftware.net/feeds/6911814024193255630/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7163644&amp;postID=6911814024193255630" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6911814024193255630?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7163644/posts/default/6911814024193255630?v=2" /><link rel="alternate" type="text/html" href="http://apolon.torqsoftware.net/2006/12/wpfe-linkfest-and-thoughts.html" title="WPF/E Linkfest and thoughts" /><author><name>Apolon</name><uri>http://www.blogger.com/profile/18125320140683620638</uri><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry></feed>
