<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Chip's Tips for Developers » Windows</title>
	
	<link>http://www.chipstips.com</link>
	<description>Contains coding, but not narcotic.</description>
	<lastBuildDate>Mon, 04 Feb 2013 20:50:40 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ChipsTipsWindows" /><feedburner:info uri="chipstipswindows" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Vim syntax highlighting for Synergy/DE</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/LMlWv3TiqXs/</link>
		<comments>http://www.chipstips.com/?p=637#comments</comments>
		<pubDate>Sun, 26 Aug 2012 22:42:46 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[businesscraft]]></category>
		<category><![CDATA[config]]></category>
		<category><![CDATA[johncottrell]]></category>
		<category><![CDATA[syntax]]></category>
		<category><![CDATA[synvim]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=637</guid>
		<description><![CDATA[It&#8217;s been more than a year since John Cottrell of BusinessCraft sent me his vim configuration files for Synergy/DE syntax highlighting. Today I finally got around to looking at them. Despite John&#8217;s apologies, they seem pretty complete. I&#8217;ve tested them on both Unix (FreeBSD) and Windows (7). John apparently developed them on the OS/X, so [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=637"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=637" data-text="Vim syntax highlighting for Synergy/DE" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D637&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=637";
			reddit_title = "Vim syntax highlighting for Synergy/DE";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=637";</script>
		<script type="text/javascript">var dzone_title = "Vim syntax highlighting for Synergy/DE";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>It&#8217;s been more than a year since John Cottrell of <a href="http://www.businesscraft.com">BusinessCraft</a> sent me his vim configuration files for Synergy/DE syntax highlighting.  Today I finally got around to looking at them.  Despite John&#8217;s apologies, they seem pretty complete.</p>
<p>I&#8217;ve tested them on both Unix (FreeBSD) and Windows (7).  John apparently developed them on the OS/X, so it should work there, too.  See the README for installation.  Please use the <a href="http://bitbucket.org/sterlingcamden/synvim/issues">Issue tracker</a> or leave a comment here about any issues you encounter.  Happy vimming, and many thanks to John!</p>
<div class="downloadbuttons">
    <a href="http://bitbucket.org/sterlingcamden/synvim"><img src="http://www.chipstips.com/images/bitbucket.png" alt="BitBucket repository" /></a>
</div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/LMlWv3TiqXs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=637</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=637</feedburner:origLink></item>
		<item>
		<title>Managing simultaneous events in Synergy/DE UI Toolkit</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/9kRXs-a8OdE/</link>
		<comments>http://www.chipstips.com/?p=631#comments</comments>
		<pubDate>Sun, 15 Jan 2012 01:31:05 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[UI Toolkit]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[m_signal]]></category>
		<category><![CDATA[synthesis]]></category>
		<category><![CDATA[uitoolkit]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=631</guid>
		<description><![CDATA[I&#8217;ve written before (PDF) about the unique event model of the Synergy/DE UI Toolkit. For historical reasons, these events are often called &#8220;menu entries,&#8221; and even though they are handled in a synchronous, delayed manner you can&#8217;t have more than one such event pending at any given time. This didn&#8217;t cause too many problems back [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=631"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=631" data-text="Managing simultaneous events in Synergy/DE UI Toolkit" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D631&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=631";
			reddit_title = "Managing simultaneous events in Synergy/DE UI Toolkit";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=631";</script>
		<script type="text/javascript">var dzone_title = "Managing simultaneous events in Synergy/DE UI Toolkit";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p><img src="http://chipstips.com/images/synthesis.png" align="left" height="100" width="100" alt="synthesis" style="padding-right:10px;"/>I&#8217;ve <a href="http://www.synergyde.com/common/downloads/EventModelW.pdf">written before (PDF)</a> about the unique <a href="http://www.chipstips.com/?p=78">event model</a> of the Synergy/DE UI Toolkit.  For historical reasons, these events are often called &#8220;menu entries,&#8221; and even though they are handled in a synchronous, delayed manner you can&#8217;t have more than one such event pending at any given time.  This didn&#8217;t cause too many problems back in the old days when they were almost limited to user-initiated events.  But now that they&#8217;ve also become a standard means for converting asynchronous system-level events into synchronous Toolkit events, the need to generate more than one at a time has become something much more than academic.</p>
<p>Consider, for instance, an input field that needs to perform non-trivial processing at three points: when it is modified, when it is displayed, and when focus leaves the field.  Each of these events can be hooked to a &#8220;method&#8221; routine, but if those routines need to do anything involving user interaction, then on Windows it needs to be deferred to the outer loop by means of passing an event to M_SIGNAL.  Why?  Because in an asychronous callback, the UI Toolkit can&#8217;t process Windows messages, so the user will not see any changes to the UI until after that event has been handled and the routine returns.  Non-Windows platforms like Unix and OpenVMS don&#8217;t have that problem, but if your code is portable to Windows then you probably want to write it that way anyway.</p>
<p>Now, when the user types something in the field and then advances to the next field (via Tab, etc.), all three of those events will fire: first the &#8220;change&#8221; event, then the &#8220;display&#8221; event (to display the reformatted value after validation), then the &#8220;leave&#8221; event.  All three associated methods will be called in that order.  If each of them signals a menu entry event, then only the last one will be seen.</p>
<p>I&#8217;ve added a class to my Synthesis library to extend menu-entry signaling to maintain a queue of pending events.  To make use of it, you replace M_SIGNAL with <a href="http://chipstips.com/doc/synthesis/multisignal.html#ref-signal">multi_signal</a>.  In the outer routine that consumes events, you change M_SIGNAL(&#8230;, D_REMOVE) (or testing g_select and g_entnam, after the older form), with a loop of calls to <a href="http://chipstips.com/doc/synthesis/multisignal.html#ref-remove">multi_remove</a>, until it returns ^null.  Each non-null return value will be a string containing an event that was signaled, in the order in which they were signaled.</p>
<p>To ease the transition, I&#8217;ve made multisignal somewhat compatible with M_SIGNAL.  If the consuming code isn&#8217;t changed to the new paradigm, then it will still see the most recent event &#8212; whether it was passed to M_SIGNAL or multisignal.</p>
<p>See the test program (test_multisignal.dbl in the tests subdirectory) for an example of how to solve the scenario I related above.</p>
<p>With this feature, I&#8217;m putting a lid on Synthesis version 2.2.1.  Any further changes will go in the next version.</p>
<div class="downloadbuttons">
    <a href="http://bitbucket.org/sterlingcamden/synthesis"><img src="http://www.chipstips.com/images/bitbucket.png" alt="BitBucket repository" /></a><br />
    <a href="http://www.chipstips.com/download/synthesis.tar.bz2"><img src="http://www.chipstips.com/images/tarball.png" alt="tarball" /></a><br />
    <a href="http://www.chipstips.com/download/synthesis.zip"><img src="http://www.chipstips.com/images/zip.png" alt="Zip archive" /></a>
</div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/9kRXs-a8OdE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=631</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=631</feedburner:origLink></item>
		<item>
		<title>Synergy/DE command line utility for printing labels</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/xe6yskzZZr0/</link>
		<comments>http://www.chipstips.com/?p=625#comments</comments>
		<pubDate>Mon, 12 Sep 2011 00:13:24 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[beer]]></category>
		<category><![CDATA[labels]]></category>
		<category><![CDATA[printing]]></category>
		<category><![CDATA[synlabels]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=625</guid>
		<description><![CDATA[I recently started brewing beer again, after a 13 year hiatus. Now that my first batch has been in the bottle for a couple of weeks, and my second batch is fermenting, I decided I should label my bottles to keep the batches straight. I found some removable bottle labels at OnlineLabels.com, which I ordered [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=625"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=625" data-text="Synergy/DE command line utility for printing labels" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D625&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=625";
			reddit_title = "Synergy/DE command line utility for printing labels";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=625";</script>
		<script type="text/javascript">var dzone_title = "Synergy/DE command line utility for printing labels";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>I recently started brewing beer again, after a 13 year hiatus.  Now that my first batch has been in the bottle for a couple of weeks, and my second batch is fermenting, I decided I should label my bottles to keep the batches straight.  I found some <a href="http://www.onlinelabels.com/Products/OL125WR.htm">removable bottle labels at OnlineLabels.com</a>, which I ordered and received.</p>
<p>Next came the question of how to print them?  Back in the old days, I would painstakingly copy/paste/align each label in Microsoft Paint for every batch.  There had to be an easier way.</p>
<p>I took a look at Microsoft Publisher, which appears to have the necessary options, but for some reason they just don&#8217;t work.</p>
<p>Then it occurred to me:  why not write a little program using the Synergy/DE Windows Print API (which I helped design, after all)?  I designed a command-line interface for specifying the origin, size, and spacing of the labels; as well as an image to print on them, optional outline (for testing alignment), and print preview.  Implementation and testing took about an hour.  &#8216;Tis a thing of beauty.</p>
<p>And so is the design for the labels for my first batch:</p>
<p><img src="http://chipstips.com/images/NutAgain.png" /></p>
<p>In case you&#8217;re wondering about the name &#8212; when I brewed my very first batch of beer in May of 1994, it was a nut brown ale.  It turned out so good that I decided that was a good place to start for round 2.  The good folks at <a href="http://olybrew.com">Olympic Brewing Supplies</a> provided an easy kit to get me back in the saddle.  It isn&#8217;t my finest creation, but it&#8217;s a good bit nicer than anything you can buy in a store.  Maybe I&#8217;m biased.</p>
<p>Anyway, I created a batch file to align for these labels, and I&#8217;ve included it as an example of usage.  You still have to add the -image (or -outline for testing) and -n switches, but the spacing and sizing are all worked out for you.</p>
<p>Unfortunately, this program will only work on Windows platforms, because it makes use of the Windows Print API.</p>
<div class="downloadbuttons">
    <a href="http://bitbucket.org/sterlingcamden/synlabels"><img src="http://www.chipstips.com/images/bitbucket.png" alt="BitBucket repository" /></a><br />
    <a href="http://www.chipstips.com/download/synlabels.tar.bz2"><img src="http://www.chipstips.com/images/tarball.png" alt="tarball" /></a><br />
    <a href="http://www.chipstips.com/download/synlabels.zip"><img src="http://www.chipstips.com/images/zip.png" alt="tarball" /></a>
</div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/xe6yskzZZr0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=625</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=625</feedburner:origLink></item>
		<item>
		<title>Oi: Object-integer mapping for Synergy/DE</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/GFx8PD32QQ0/</link>
		<comments>http://www.chipstips.com/?p=599#comments</comments>
		<pubDate>Mon, 28 Mar 2011 21:44:50 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[synthesis]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=599</guid>
		<description><![CDATA[One of the most important features about the (new since version 9) object-oriented syntax in Synergy/DE is that it&#8217;s not a purist&#8217;s OOP. You can mix object-oriented and imperative programming at will. Thus, if you want to start using object-orientation in a decades-old application, you don&#8217;t have to rewrite a large portion of your existing [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=599"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=599" data-text="Oi: Object-integer mapping for Synergy/DE" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D599&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=599";
			reddit_title = "Oi: Object-integer mapping for Synergy/DE";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=599";</script>
		<script type="text/javascript">var dzone_title = "Oi: Object-integer mapping for Synergy/DE";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p><img src="http://chipstips.com/images/synthesis.png" align="left" height="100" width="100" alt="synthesis" style="padding-right:10px;"/>One of the most important features about the (new since version 9) object-oriented syntax in Synergy/DE is that it&#8217;s not a purist&#8217;s OOP.  You can mix object-oriented and imperative programming at will.  Thus, if you want to start using object-orientation in a decades-old application, you don&#8217;t have to rewrite a large portion of your existing code in order to do so.</p>
<p>However, not all existing code is well-suited to adding objects.  In particular, existing routines that expect an argument of a primitive type (alpha, decimal, integer) cannot be passed an object instead.  Since Synergy/DE supports boxing of primitives, you could go and change the type of each such parameter to object (@*), but then you&#8217;d have to go and change every place where those routines are called in order to box the existing primitive parameters.  That could become a huge effort, and for the majority of cases it would add an unnecessary performance penalty.</p>
<p>In the case of the optional method data arguments passed through UI Toolkit routines to callback methods, Synergy/DE introduced a new parameter type, &#8220;any&#8221;.  You can pass either an object or a primitive to an &#8220;any&#8221; parameter, but in a routine that accesses it in any way other than to pass it on, the parameter must be declared with a compatible type for the object passed.  A good example of this would be a selection list that you&#8217;d like to load from an <a href="http://chipstips.com/doc/synthesis/ls.html">ls</a>.  In order to get a reference to the ls through to the load method, you can pass it as an optional argument to l_process.  In the load method for that list, declare the corresponding argument as type <code>@ls</code>, and you can then use it.</p>
<p>But what if you do your list processing within a wrapper routine, so you don&#8217;t have control over the argument list?  One way to attach data to a list is via the l_user routine, which stores or retrieves a record associated with the list for user-defined purposes.  You can&#8217;t store an object (like an ls) in that record &#8212; Synergy/DE does not support that kind of serialization.  What you need instead is a way to convert the object reference into a primitive type that you can then use later on to restore the reference.  That&#8217;s the purpose of a new class I just added to the Synthesis library:  <a href="http://chipstips.com/doc/synthesis/oi.html">Oi</a>, which stands for Object-integer.</p>
<p>For any object, you can call Oi.o2i, passing the object, and retrieve a unique integer that only refers to that object.  if you call it more than once for the same object, you&#8217;ll get the same integer (unless you drop it in between).  To reverse the operation, pass the integer to Oi.i2o, and you&#8217;ll get back the object reference.</p>
<p>Naturally, this involves maintaining a reference to each object so registered within Oi.  Thus, when you&#8217;re all done with an object, call Oi.drop and pass it either the object reference or its integer value, and that object will no longer be tracked.</p>
<p>Using Oi, you can therefore pass an integer around to any place that needs an object reference, without having to deal with the difficulties of passing an object.  Obviously, a cleaner approach would be to change an API here or there, or store object references as properties of other objects.  But the evolution of large systems doesn&#8217;t always lend itself to a proper redesign in order to get from point A to point B.  Oi is intended to help you along your migration path, not to become a permanent solution or a recommended practice.</p>
<div class="downloadbuttons">
    <a href="http://bitbucket.org/sterlingcamden/synthesis"><img src="http://www.chipstips.com/images/bitbucket.png" alt="BitBucket repository" /></a><br />
    <a href="http://www.chipstips.com/download/synthesis.tar.bz2"><img src="http://www.chipstips.com/images/tarball.png" alt="tarball" /></a><br />
    <a href="http://www.chipstips.com/download/synthesis.zip"><img src="http://www.chipstips.com/images/zip.png" alt="Zip archive" /></a>
</div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/GFx8PD32QQ0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=599</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=599</feedburner:origLink></item>
		<item>
		<title>Synthesis 2.2: full compatibility for Unix, .NET, Synergy/DE 9.5</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/jCw7I9gf9ZM/</link>
		<comments>http://www.chipstips.com/?p=566#comments</comments>
		<pubDate>Tue, 16 Nov 2010 21:33:35 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[synthesis]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=566</guid>
		<description><![CDATA[Synergex will soon release Synergy/DE version 9.5, which includes a released version of Synergy for the .NET Framework. In preparation for this event, I have modified the Synthesis library to be fully compatible with the released version of 9.5. You can download it at the links below. One late-breaking (double entendre alert) surprise in Synergy.NET [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=566"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=566" data-text="Synthesis 2.2: full compatibility for Unix, .NET, Synergy/DE 9.5" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D566&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=566";
			reddit_title = "Synthesis 2.2: full compatibility for Unix, .NET, Synergy/DE 9.5";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=566";</script>
		<script type="text/javascript">var dzone_title = "Synthesis 2.2: full compatibility for Unix, .NET, Synergy/DE 9.5";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p><img src="http://chipstips.com/images/synthesis.png" align="left" height="100" width="100" alt="synthesis" style="padding-right:10px;"/><br />
Synergex will soon release <a href="http://synergyde.com/news/article.aspx?id=3259">Synergy/DE version 9.5</a>, which includes a released version of Synergy for the .NET Framework.  In preparation for this event, I have modified the <a href="http://chipstips.com/?tag=synthesis">Synthesis library</a> to be fully compatible with the released version of 9.5.  You can download it at the links below.</p>
<p>One late-breaking (double entendre alert) surprise in Synergy.NET involves class fields that are primitive .NET types, such as &#8220;int&#8221;.  If class members having these types are not enclosed in a record (aka, &#8220;loose&#8221;), then you may not pass them as arguments to any of the built-in Synergy/DE subroutines or functions, because the runtime cannot pin them properly (resulting in all sorts of unpredictable memory access havoc).  The easy fix for this is to enclose member fields within a member record.  You can also use Synergy/DE types instead of .NET types (for instance, i4 instead of int), but it&#8217;s sometimes hard to tell what types the compiler will translate into .NET types.  If you fail to catch one of these, the compiler should provide a &#8220;loose int&#8221; error to help you round up these promiscuous bitties.</p>
<p>Simultaneously, I purchased a Synergy/DE for Linux license and installed it on my FreeBSD 8.1-STABLE system using the Linux kernel module and the Fedora 10 port (ports/emulators/linux_base-f10).  I still don&#8217;t have terminal input or termcap working right, but everything else seems to work, so that was enough for testing Synthesis.  Rather than buying PVCS Configuration Builder for Unix, I translated the PVCS makefiles into standard Unix Makefiles, and those are now included in the distribution.  I also made minor changes to the sources for compatibility with either Unix/Linux or make.</p>
<p>Third, I decided to move the archives for Synthesis to Mercurial on BitBucket and remove the PVCS archives from the distribution.  This makes the distribution much smaller.  If you need access to older versions, just <a href="http://chjipstips.com/?page_id=3">contact me</a>.  I&#8217;ve also provided a tarball distribution in addition to the traditional ZIP format.  Here are all those links:</p>
<div class="downloadbuttons">
    <a href="http://bitbucket.org/sterlingcamden/synthesis"><img src="http://www.chipstips.com/images/bitbucket.png" alt="BitBucket repository" /></a><br />
    <a href="http://www.chipstips.com/download/synthesis.tar.bz2"><img src="http://www.chipstips.com/images/tarball.png" alt="tarball" /></a><br />
    <a href="http://www.chipstips.com/download/synthesis.zip"><img src="http://www.chipstips.com/images/zip.png" alt="Zip archive" /></a>
</div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/jCw7I9gf9ZM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=566</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=566</feedburner:origLink></item>
		<item>
		<title>Tiling Windows windows, my way</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/LL7wScwDkLY/</link>
		<comments>http://www.chipstips.com/?p=541#comments</comments>
		<pubDate>Sun, 01 Aug 2010 00:50:54 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[C and C++]]></category>
		<category><![CDATA[Wildly popular]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[cpptile]]></category>
		<category><![CDATA[C_language]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[tiling]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=541</guid>
		<description><![CDATA[Now that I&#8217;ve been using XMonad as my window manager on FreeBSD for a while, I find that when I have to work on Windows one of the more painful aspects thereof is, ironically, window management. I spend way too much time hunting for the right window or arranging windows so I can clearly see [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=541"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=541" data-text="Tiling Windows windows, my way" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D541&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=541";
			reddit_title = "Tiling Windows windows, my way";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=541";</script>
		<script type="text/javascript">var dzone_title = "Tiling Windows windows, my way";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>Now that I&#8217;ve been using <a href="http://xmonad.org">XMonad</a> as my window manager on FreeBSD for a while, I find that when I have to work on Windows one of the more painful aspects thereof is, ironically, window management.  I spend way too much time hunting for the right window or arranging windows so I can clearly see all the ones I need at once.  Windows Vista and 7 have the ability to view windows side-by-side or stacked, but that&#8217;s not adequate to my needs and it virtually requires using the mouse.  I desperately want an automatic tiling window manager like XMonad.</p>
<p>So, I created the next best thing:  a command-line utility that will arrange all the windows in a tiled fashion, according to a pattern specified per monitor.  In the download below you will find all the sources, plus in the Release subdirectory I&#8217;ve included an executable built with Visual Studio 2010.</p>
<p>For usage, type &#8217;tile&#8217; at a command prompt without arguments.  But, to give you some examples:</p>
<p><code>tile 1 2</code></p>
<p>This tiles both the primary and second monitors using a column-based scheme, with no maximum of columns.  Each display will be divided into the number of columns needed to hold all of the windows on that monitor.</p>
<p><code>tile 1:2r 2:3c</code></p>
<p>This tiles the primary monitor into 2 rows, with each row split as evenly as possible to accomodate all of the windows.  Thus, if the primary window contains three windows, the first window will occupy the entire top row, and the second row will be split between the other two windows.  On monitor #2, we&#8217;ll have three columns &#8212; so if we have five windows there, we&#8217;ll get one window in the first column and two windows stacked in each of the two remaining columns.</p>
<p>If you specify more rows or columns than there are windows on that monitor, it&#8217;s automatically reduced to the number of windows.  Tile silently ignores most errors, such as specifying a monitor that doesn&#8217;t exist.  Tile does not affect windows that are maximized or minimized.  In order to be considered within a monitor, at least 10 pixels of the window in both directions must intersect the monitor&#8217;s rectangle.</p>
<p>As noted above, all parts of an argument except for the monitor number are optional.  If omitted, the max defaults to 99, and row/column defaults to column.</p>
<p>So, now I can choose my optimal layout, put it in a little batch file named &#8216;t.bat&#8217;, and whenever I need my windows to snap into place I can just type &#8216;t&#8217; at a command prompt.</p>
<div class="downloadbutton"><a href="http://www.chipstips.com/download/cpptile.zip"><img src="http://www.chipstips.com/images/download.gif" alt="download" /></a></div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/LL7wScwDkLY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=541</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=541</feedburner:origLink></item>
		<item>
		<title>Changing the text and size of drill buttons in Synergy/DE</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/3I_re-N5VLY/</link>
		<comments>http://www.chipstips.com/?p=485#comments</comments>
		<pubDate>Wed, 14 Apr 2010 17:16:53 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[UI Toolkit]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[buttons]]></category>
		<category><![CDATA[syndrilltext]]></category>
		<category><![CDATA[toolkit]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=485</guid>
		<description><![CDATA[Glynis Lyttle recently asked on the synergy-l mailing list about how to change the appearance of the drill buttons on Synergy/DE UI Toolkit input windows.&#160; These are buttons that are placed to the right of an input field if it has a drill method (IDRILL_METHOD).&#160; They’re always sized to the width of a vertical scroll [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=485"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=485" data-text="Changing the text and size of drill buttons in Synergy/DE" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D485&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=485";
			reddit_title = "Changing the text and size of drill buttons in Synergy/DE";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=485";</script>
		<script type="text/javascript">var dzone_title = "Changing the text and size of drill buttons in Synergy/DE";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>Glynis Lyttle recently asked on the synergy-l mailing list about how to change the appearance of the drill buttons on Synergy/DE UI Toolkit input windows.&#160; These are buttons that are placed to the right of an input field if it has a drill method (IDRILL_METHOD).&#160; They’re always sized to the width of a vertical scroll bar, and contain the text “…” as show below:</p>
<p><a href="http://chipstips.com/wp-content/images/ChangingthetextandsizeofdrillbuttonsinSy_91BB/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://chipstips.com/wp-content/images/ChangingthetextandsizeofdrillbuttonsinSy_91BB/image_thumb.png" width="96" height="63" /></a> </p>
<p>Usually, these buttons are used to launch some sort of lookup function that will populate the field.&#160; But Glynis has multiple uses for these buttons, and would like a way to indicate the distinction between launching the calendar control for a date field versus launching a new email to the address contained in an email address field.</p>
<p>The Synergy UI Toolkit does not provide a documented way to do this, but it can be achieved without resorting to any undocumented functionality.</p>
<p>The download below includes a new function named set_drill_text, which has the following syntax:</p>
<p><code>%set_drill_text(<em>wndid</em>, <em>field</em>, <em>text</em>) =&gt; <em>success</em></code></p>
<p>where</p>
<ul>
<li><em>wndid</em> is the ID of the input window</li>
<li><em>field </em>is either the name or the index of the input field whose drill button will be modified</li>
<li><em>text </em>is the new text for the button</li>
<li><em>success </em>is returned true if successful, false if not</li>
</ul>
<p>The text of the button will be changed to the right-trimmed value of <em>text</em>, and the button will be resized appropriately.&#160; The height of the button will not be changed, but its width will be set to the width of the text plus the width of two 3D edges as described by the current theme.&#160; For example:</p>
<p><a href="http://chipstips.com/wp-content/images/ChangingthetextandsizeofdrillbuttonsinSy_91BB/image_3.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://chipstips.com/wp-content/images/ChangingthetextandsizeofdrillbuttonsinSy_91BB/image_thumb_3.png" width="153" height="56" /></a> </p>
<p>The function can fail for a number of reasons:</p>
<ul>
<li><em>wndid </em>is not a valid input window ID</li>
<li><em>field </em>is not the name of a field in the window or a numeric value within the range of 1 to the number of fields</li>
<li>the drill button for the field has not yet been created.&#160; Either I_FRAMES or I_INPUT must have been previously called for an input set that contains the field.</li>
<li>probably something else I haven’t thought of.</li>
</ul>
<p>Note:&#160; whenever the input set controls are recreated, the drill button text and size revert to their original form until you call this function again.&#160; Input set controls are recreated whenever you switch the active input set for I_INPUT/I_FRAMES, or call I_INPFLD, as well as some cases of I_FLDMOD for that field.</p>
<p>It would be nice to be able to change the button to display an image instead of text.&#160; Unfortunately, that’s quite a bit more involved and would require some non-Synergy/DE code (probably C or C++) to subclass the button’s WM_PAINT handler.&#160; We’ll leave that as an exercise for another day.</p>
<div class="downloadbutton"><a href="http://www.chipstips.com/download/syndrilltext.zip"><img alt="download" src="http://www.chipstips.com/images/download.gif" /></a></div>
<div></div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/3I_re-N5VLY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=485</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=485</feedburner:origLink></item>
		<item>
		<title>Masked coder saves the day with updates to tee utility for Windows</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/j7fqIsiRqXE/</link>
		<comments>http://www.chipstips.com/?p=430#comments</comments>
		<pubDate>Thu, 28 Jan 2010 19:05:37 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C and C++]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[cpptee]]></category>
		<category><![CDATA[pipe]]></category>
		<category><![CDATA[tee]]></category>
		<category><![CDATA[utility]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=430</guid>
		<description><![CDATA[A commenter going by Anonymous Coward (I bet that’s not his real name, and I beg forgiveness if the masculine pronoun doesn’t apply) provided a solution to the double-spaced output problem users occasionally experienced with my tee utility for Windows. Naturally, this issue occurred because of the inconsistent usage of carriage-returns and linefeeds to terminate [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=430"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=430" data-text="Masked coder saves the day with updates to tee utility for Windows" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D430&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=430";
			reddit_title = "Masked coder saves the day with updates to tee utility for Windows";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=430";</script>
		<script type="text/javascript">var dzone_title = "Masked coder saves the day with updates to tee utility for Windows";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p><img style="margin: 0px 10px 0px 0px; display: inline" align="left" src="http://chipstips.com/wp-content/images/TeeutilityinRubythatalsoworksonWindows_BAA3/image05.png" />A commenter going by Anonymous Coward (I bet that’s not his real name, and I beg forgiveness if the masculine pronoun doesn’t apply) <a href="http://www.chipstips.com/?p=129#comment-96940">provided a solution</a> to the <a href="http://www.chipstips.com/?p=349">double-spaced output problem</a> users occasionally experienced with my <a href="http://www.chipstips.com/?p=129">tee utility for Windows</a>.</p>
<p>Naturally, this issue occurred because of the inconsistent usage of carriage-returns and linefeeds to terminate lines of text, combined with Console::ReadLine’s interpretation thereof.&#160; The solution, simply enough, was to use BinaryReader for input, and BinaryWriter for output, so no interpretation or translation of the characters would occur.</p>
<p>Like most good programmers, once he had inserted hands in the code, Anonymous Coward couldn’t leave this one alone.&#160; He coded up several more features and emailed them to me.&#160; I made a few corrections and included the new version here.</p>
<p>New features include:</p>
<ul>
<li>Duplicated file names are silently ignored, rather than causing a file open conflict.</li>
<li>/? or –help displays usage information.</li>
<li>-i or –ignore ignores cancel (Ctrl+C), instead of always ignoring it.</li>
<li>-f optionally marks the end of switches and interprets all remaining arguments as filenames.</li>
</ul>
<p>Thanks, Anonymous Coward – whoever you are!</p>
<div class="downloadbutton"><a href="http://www.chipstips.com/download/cpptee.zip"><img src="http://www.chipstips.com/images/download.gif" /></a></div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/j7fqIsiRqXE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=430</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=430</feedburner:origLink></item>
		<item>
		<title>Synthesis 2.0: code coverage analysis, .NET compatibility, and more</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/oQ45CW3jjZw/</link>
		<comments>http://www.chipstips.com/?p=418#comments</comments>
		<pubDate>Sat, 26 Dec 2009 23:08:06 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[OpenVMS]]></category>
		<category><![CDATA[Regexen]]></category>
		<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[codecoverage]]></category>
		<category><![CDATA[regexen]]></category>
		<category><![CDATA[synthesis]]></category>
		<category><![CDATA[telnet]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=418</guid>
		<description><![CDATA[I can’t believe that it’s been more than two months since I unleashed the Synthesis library on the unsuspecting Synergy/DE world.&#160; I promised then to enhance it further, so herewith I announce the arrival of Synthesis 2.0, which you can download via the link below.&#160; I bumped the primary version number because this version involves [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=418"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=418" data-text="Synthesis 2.0: code coverage analysis, .NET compatibility, and more" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D418&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=418";
			reddit_title = "Synthesis 2.0: code coverage analysis, .NET compatibility, and more";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=418";</script>
		<script type="text/javascript">var dzone_title = "Synthesis 2.0: code coverage analysis, .NET compatibility, and more";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>I can’t believe that it’s been more than two months since <a href="http://www.chipstips.com/?p=399">I unleashed the Synthesis library</a> on the unsuspecting Synergy/DE world.&#160; I promised then to enhance it further, so herewith I announce the arrival of Synthesis 2.0, which you can download via the link below.&#160; I bumped the primary version number because this version involves numerous changes throughout, and some significant new features.&#160; See the <a href="http://www.chipstips.com/doc/synthesis/changelog.html#ver-2.0.0">full change log here</a>.</p>
<p><strong>Synergy/DE Version 9.3.1</strong></p>
<p>Synthesis 2.0 is fully compatible with <a href="http://synergyde.com">Synergy/DE</a> version 9.3.1.&#160; Unfortunately, I was unable to maintain compatibility with earlier versions of Synergy/DE, so don’t upgrade Synthesis until you’re ready to upgrade Synergy/DE as well.</p>
<p><strong>Synergy.NET beta</strong></p>
<p>Synergy/DE 9.3.1 also includes a beta version of Synergy.NET (Synergy/DE for the .NET Framework) on 32-bit Windows platforms.&#160; Synthesis 2.0 includes limited compatibility with this version as well.&#160; See the <a href="http://www.chipstips.com/doc/synthesis/index.html#issues">Known Issues</a> for what’s missing.&#160; You can also search the code for DOTNET_BETA_WORKAROUND to see the code that I expect to support in the future versus what I’m doing now.</p>
<p><strong>Code Coverage analysis</strong></p>
<p>Synthesis 2.0 includes two new utilities for analyzing code coverage:&#160; <a href="http://www.chipstips.com/doc/synthesis/cover.html">cover</a> and <a href="http://www.chipstips.com/doc/synthesis/htmlcover.html">htmlcover</a>.&#160; These are command-line utilities that can be run with either dbr or dbs.&#160; The only difference between them is the format of their output – cover writes tab-delimited data to stdout, while htmlcover writes an HTML-formatted report to a file.</p>
<p>Both utilities sample code execution by driving a debug session of the executable and stepping a line at a time through the code.&#160; For this purpose, they use the Synergy/DE remote debugger, which operates over Telnet.&#160; Thus, I added classes to Synthesis to support the <a href="http://www.chipstips.com/doc/synthesis/telnet.html">Telnet protocol</a> and <a href="http://www.chipstips.com/doc/synthesis/socket.html">sockets</a>.</p>
<p>You can sample the code coverage for any Synergy/DE executable (except for .NET, because the Telnet debugger isn’t supported there).&#160; I’ve added a ‘coverage’ dependency to the makefile in the tests directory to generate HTML reports for each of the Synthesis tests into the coverage subdirectory.&#160; I didn’t include those in the download because of their size, but you can generate them with a ‘build coverage’ in the tests directory, if you have PVCS Configuration Builder and you’re patient enough to wait for them (especially test_regex).&#160; They’ve already revealed some areas where I need to beef up my tests.</p>
<p>For more information about how this works, see the <a href="http://www.chipstips.com/doc/synthesis/coverage.html">CodeCoverage</a> class.</p>
<p><strong>Bug fixes</strong></p>
<p>In several places, the comparison operators used for alphanumeric did not distinguish between strings of unequal length that match up to the lesser length (e.g., “bug” == “bugger”).&#160; That’s been corrected.</p>
<p>I fixed two issues related to <a href="http://www.chipstips.com/doc/synthesis/regex.html">Regular Expressions</a>:</p>
<ol>
<li>You may now enclose a begin-line or end-line anchor within parentheses.&#160; Previously, they could only occur as the very first or last character in the pattern, respectively.&#160; Now, for example,
<pre><code>R$('/(^front|or_not)/')</code></pre>
<p>will correctly find “front” at the beginning of the line, or “or_not” anywhere.&#160; Likewise for a $ anchor. </li>
<li>Certain complex nested sub-expressions had a bug that prevented them from ever matching. </li>
</ol>
<p><strong>For the future</strong></p>
<p>I still have much more to add to this library.&#160; Here are some of the things on my list:</p>
<ul>
<li>Improved .NET compatibility</li>
<li>Additional <a href="http://www.chipstips.com/doc/synthesis/regex.html">Regex</a> features (full Perl 5 syntax)</li>
<li>More methods for <a href="http://www.chipstips.com/doc/synthesis/ls.html">ls</a> (inject/fold, etc.)</li>
<li>Prevent multiple evaluation of <a href="http://www.chipstips.com/doc/synthesis/assertions.html">assertion</a> arguments when formatting a message</li>
<li>… and more.</li>
</ul>
<p>Is there anything you’d like to see added?</p>
<p><a href="http://www.chipstips.com/download/synthesis.zip"><img src="http://www.chipstips.com/images/download.gif" /></a></p>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/oQ45CW3jjZw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=418</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=418</feedburner:origLink></item>
		<item>
		<title>Tee utility for Windows updated</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/VUaywpf8tPA/</link>
		<comments>http://www.chipstips.com/?p=349#comments</comments>
		<pubDate>Tue, 18 Aug 2009 23:32:07 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C and C++]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[clr]]></category>
		<category><![CDATA[clroldsyntax]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[cpptee]]></category>
		<category><![CDATA[foreach]]></category>
		<category><![CDATA[lambdas]]></category>
		<category><![CDATA[tee]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=349</guid>
		<description><![CDATA[How could something so simple turn into something so complicated? One of my most popular (perhaps the most popular) post on this site is my tee utility for Windows.  I wrote it back in 2003 using the Visual Studio vintage of the same year.  Rather than including stdio.h and writing it in good old plain [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=349"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=349" data-text="Tee utility for Windows updated" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D349&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=349";
			reddit_title = "Tee utility for Windows updated";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=349";</script>
		<script type="text/javascript">var dzone_title = "Tee utility for Windows updated";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p><img style="margin: 0px 10px 0px 0px; display: inline" src="http://chipstips.com/wp-content/images/TeeutilityinRubythatalsoworksonWindows_BAA3/image05.png" alt="" align="left" />How could something so simple turn into something so complicated?</p>
<p>One of my most popular (perhaps <strong>the </strong>most popular) post on this site is my <a href="http://www.chipstips.com/?p=129">tee utility for Windows</a>.  I wrote it back in 2003 using the Visual Studio vintage of the same year.  Rather than including stdio.h and writing it in good old plain vanilla C code, I decided to employ the then-new managed extensions for C++ so it could &lt;scare-quotes&gt; benefit from &lt;/scare-quotes&gt; the .NET Framework 1.1.  That’s where my troubles were begotten – but it took a while for them to gestate.</p>
<p>The first problem I encountered was trying to run it from a network share.  Microsoft, in a truly dramatic performance of <a href="http://blogs.techrepublic.com.com/security/?p=1274">security theater</a>, decided to treat network shares as “Intranet Zone” and untrusted by default.  Sure, there were ways to establish a trusted zone, but it was a pain to remember.  Thankfully, <a href="http://adrianba.net/archive/2008/09/06/running-managed-code-from-a-network-share.aspx">they’ve solved that one for me</a>.</p>
<p>Then recently, user Alex Armstrong <a href="http://www.chipstips.com/?p=129#comment-80495">noticed a few anomalies</a> when using tee with ping.  He likes to use ping –t to repeat until interrupted, at which point ping prints out its statistics and then stops.  But when ping was piped to tee, Ctrl+C would interrupt tee instead – which closed the pipe and killed ping before it could relieve itself of its statistics.  Not only that, but since tee’s output files were not flushed, some of the output that had already been displayed on the console would not make it to the file(s).</p>
<p>I tried setting the Console property <a href="http://msdn.microsoft.com/en-us/library/system.console.treatcontrolcasinput.aspx">TreatControlCAsInput</a> to true, but when the input stream is a pipe that caused tee to go into la-la land.  Reading further, I found the <a href="http://msdn.microsoft.com/en-us/library/system.console.cancelkeypress.aspx">CancelKeyPress</a> event – but for some reason I couldn’t get it to compile with the old syntax that I had used back in 2003.  With a little research, I found that the only reason why the compiler was tolerating most of my code was because the project upgrade wizard had added the <a href="http://msmvps.com/blogs/vandooren/archive/2006/11/13/calling-labview-vis-through-c-style-callback-function-pointers.aspx">/clr:oldSyntax switch</a> when upgrading to VS2008.  When I removed that switch, all hell broke loose.  How could they change the syntax for writing managed code in C++ so drastically?  This little utility, which is only about 35 lines of real code, required changes on 15 of those lines.  Yes, they were mostly trivial – but how annoying.  It’s not the same language.  Yes, it’s probably better syntax, but it’s not the same language.</p>
<p>One change I would have liked to make is to use <a href="http://msdn.microsoft.com/en-us/library/bwabdf9z.aspx">List&lt;T&gt;.ForEach</a> to iterate through the list, rather than a for loop.  But I couldn’t find any way to write the Action code inline until <a href="http://msdn.microsoft.com/en-us/library/dd293608(VS.100).aspx">lambdas arrive in VS2010</a>.  Now that’s a syntax change I could get excited about.</p>
<p>Long story short, canceling the CancelKeyPress event (is that a double negative?) worked &#8212; Ctrl+C is now seen by ping, which prints out its statistics and closes the pipe, which stops tee normally.  If you should ever need to interrupt tee itself, use Ctrl+Break.</p>
<p>One more thing (as <a rel="nofollow" href="http://en.wikipedia.org/wiki/Columbo_(TV_series)">Columbo</a> says) – Alex also noticed that ping’s output is double-spaced when piped through tee.  That’s because ping ends each line with a double carriage-return.  Console::ReadLine treats each of those as a terminator.  I don’t know why the command prompt window doesn’t have an issue with that, but I do.  I can’t just ignore zero-length lines, because then I’d lose spacing from other programs that don’t use a double carriage-return.  Any ideas?  This is supposed to be simple.</p>
<div class="downloadbutton"><a href="http://www.chipstips.com/download/cpptee.zip"><img src="http://www.chipstips.com/images/download.gif" alt="" /></a></div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/VUaywpf8tPA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=349</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=349</feedburner:origLink></item>
		<item>
		<title>CFile::GetStatus on root folder works sometimes</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/w0zylgECzq8/</link>
		<comments>http://www.chipstips.com/?p=267#comments</comments>
		<pubDate>Sun, 03 May 2009 17:04:42 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[C and C++]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CFile]]></category>
		<category><![CDATA[GetFileAttributes]]></category>
		<category><![CDATA[GetStatus]]></category>
		<category><![CDATA[mfc]]></category>
		<category><![CDATA[SHGetFileInfo]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=267</guid>
		<description><![CDATA[There’s nothing particularly magical about this tip, but its solution stumped me for a while so perhaps it will help out some other poor developer who is madly googling for an answer. An MFC application needs to determine whether the path entered by a user is a valid folder.  The user already has to be [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=267"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=267" data-text="CFile::GetStatus on root folder works sometimes" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D267&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=267";
			reddit_title = "CFile::GetStatus on root folder works sometimes";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=267";</script>
		<script type="text/javascript">var dzone_title = "CFile::GetStatus on root folder works sometimes";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>There’s nothing particularly magical about this tip, but its solution stumped me for a while so perhaps it will help out some other poor developer who is madly googling for an answer.</p>
<p>An MFC application needs to determine whether the path entered by a user is a valid folder.  The user already has to be an Administrator, so we don’t care about privileges.  All we want to know is, does this folder exist and is it indeed a folder and not a file or something else?</p>
<p>The MFC Way of doing this is to call CFile::GetStatus on the path, which fills in a CFileStatus structure and returns TRUE or FALSE.  The CFileStatus structure contains an m_attribute member that has bit values for whether its a folder, a file, etc.  This works fine most of the time.  But occasionally, calling it on the root folder of a device (e.g., “C:\”) will return FALSE.  The user reported that it failed only when the application was started from a command prompt instead of the Start menu.  That elicited from me a great big “Huh?”</p>
<p>Digging into it, I found that the problem reproduced when running from some command prompts, but not others.  From a command prompt where it normally failed, it wouldn’t fail if I started Visual Studio from that same prompt to debug it.  Thus, I resorted to the dreaded MessageBox debugging methodology.</p>
<p>I also googled this problem, found that others had run across it as well, but didn’t come up with any good solution.  One commenter suggested using SHGetFileInfo, which seemed to solve the problem until I realized that it also returned normally for folders that don’t exist.</p>
<p>I looked through the MFC sources and found that while the instance method for CFile::GetStatus simply uses GetFileAttributes, the static method that I was using does a FindFirstFile instead.  So I changed my application to call GetFileAttributes directly, and that works exactly as I would have expected.  It returns INVALID_FILE_ATTRIBUTES if the file or folder does not exist, and it returns a bit value that includes FILE_ATTRIBUTE_FOLDER if it is a folder of any kind (including a root folder).</p>
<p>GetFileAttributes provides a better solution anyway.  CFile::GetStatus just adds a bunch of extra code I didn’t need – even if I had used the instance version instead (which probably would also work).  The lesson here is that in an MFC application, it’s not always optimal to cling to MFC methods.  Take the blinders off and use the Win32 API when that provides precisely what you need.</p>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/w0zylgECzq8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=267</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=267</feedburner:origLink></item>
		<item>
		<title>Tee utility in Ruby that works on Windows</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/K2JyPATWeeE/</link>
		<comments>http://www.chipstips.com/?p=188#comments</comments>
		<pubDate>Sat, 28 Jun 2008 20:37:07 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[tee]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=188</guid>
		<description><![CDATA[I often check my referrer logs to see how people found my site.  Chip&#8217;s Tips gets the vast majority of its traffic from search engines.  Sometimes I&#8217;ll see a search that didn&#8217;t quite reach its intended result, and that will inspire a new post. Quite often I see &#8220;ruby tee windows&#8221; or something similar, which leads [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=188"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=188" data-text="Tee utility in Ruby that works on Windows" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D188&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=188";
			reddit_title = "Tee utility in Ruby that works on Windows";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=188";</script>
		<script type="text/javascript">var dzone_title = "Tee utility in Ruby that works on Windows";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p><img style="margin: 0px 10px 0px 0px" src="http://chipstips.com/wp-content/images/TeeutilityinRubythatalsoworksonWindows_BAA3/image05.png" alt="" width="100" height="82" align="left" /> I often check my referrer logs to see how people found my site.  Chip&#8217;s Tips gets the vast majority of its traffic from search engines.  Sometimes I&#8217;ll see a search that didn&#8217;t quite reach its intended result, and that will inspire a new post.</p>
<p>Quite often I see &#8220;ruby tee windows&#8221; or something similar, which leads people to my <a href="http://www.chipstips.com/?p=129">tee utility for Windows</a>.  That seems fair enough, except that it isn&#8217;t written in Ruby.  It&#8217;s written in C#, which means that it has 12 source files and the &#8220;real&#8221; code requires 29 lines.  Furthermore, since it&#8217;s a .NET executable, it won&#8217;t run if it&#8217;s installed in a folder that isn&#8217;t &#8220;trusted&#8221;.  Talk about red tape.</p>
<p>Besides, this application is trivial with a capital TRIV in Ruby, using the &#8216;shell&#8217; library.  Heedless of its impact on page load time, I&#8217;m including the entire source file right here:</p>
<p><code>require 'shell'<br />
Shell.new.tee(ARGV[0]) &lt; STDIN &gt; STDOUT</code></p>
<p>Save that to tee.rb, and then you can perform the canonical basic test:</p>
<p><code>echo hello world | tee.rb "hello.txt"</code></p>
<p>See &#8220;hello&#8221; echoed to the console, and check out the contents of hello.txt.  Naturally, this utility is far more useful for trapping the log of a long build procedure or some other process that generates tons of output, but which you&#8217;d like to see echoed to the console at the same time.</p>
<p>Of course, you could also do the whole thing at the command line:</p>
<p><code>echo hello | ruby -e "require 'shell';Shell.new.tee('hello.txt') &lt; STDIN &gt; STDOUT"</code></p>
<p>But I like having it saved in a file so I don&#8217;t have to remember it.  This should also work just fine on *nix systems, but heck you&#8217;ve got the native tee there.</p>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/K2JyPATWeeE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=188</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=188</feedburner:origLink></item>
		<item>
		<title>Scoping a wait cursor in Synergy/DE</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/r3wDdJHxzZk/</link>
		<comments>http://www.chipstips.com/?p=184#comments</comments>
		<pubDate>Mon, 05 May 2008 18:23:28 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[UI Toolkit]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[constructor]]></category>
		<category><![CDATA[cursor]]></category>
		<category><![CDATA[destructor]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[scope]]></category>
		<category><![CDATA[synwait]]></category>
		<category><![CDATA[waitcursor]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=184</guid>
		<description><![CDATA[On Windows, Synergy/DE provides access to the mouse cursor via the WP_CURSOR subfunction of W_PROC. Because this API is purely imperative, managing a wait cursor properly becomes a recurring problem in non-trivial applications. Typically, it begins like this (in pseudo-code): set wait cursor do lengthy process clear wait cursor But what happens if &#8220;do lengthy [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=184"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=184" data-text="Scoping a wait cursor in Synergy/DE" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D184&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=184";
			reddit_title = "Scoping a wait cursor in Synergy/DE";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=184";</script>
		<script type="text/javascript">var dzone_title = "Scoping a wait cursor in Synergy/DE";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>On Windows, Synergy/DE provides access to the mouse cursor via the WP_CURSOR subfunction of W_PROC.  Because this API is purely imperative, managing a wait cursor properly becomes a recurring problem in non-trivial applications.  Typically, it begins like this (in pseudo-code):</p>
<p>set wait cursor<br />
do lengthy process<br />
clear wait cursor</p>
<p>But what happens if &#8220;do lengthy process&#8221; throws an exception that&#8217;s caught outside this code?  You&#8217;ll skip right over &#8220;clear wait cursor&#8221; and leave the user unable to click anything.  What you&#8217;d like to do is more like this:</p>
<p><code>begin<br />
&nbsp;&nbsp;set wait cursor<br />
&nbsp;&nbsp;do lengthy process<br />
end</code></p>
<p>&#8230; and have the cursor reset whenever and however you exit the code block.</p>
<p>The downloadable code below demonstrates how to do this with the new object syntax in Synergy/DE version 9.  The WaitCursor class sets the wait cursor in its constructor and resets it in its destructor.  So you can code it like this:</p>
<p><code>begin<br />
&nbsp;&nbsp;data wait, @*, new WaitCursor()<br />
&nbsp;&nbsp;do lengthy process<br />
end</code></p>
<p>The data statement declares a variable that has the scope of its containing begin-end block.  The variable <em>wait</em> is declared as an object (@*).  We could have more precisely declared it as @WaitCursor, but that&#8217;s just more typing (pun intended).  It&#8217;s initial value is returned by the &#8220;new&#8221; expression, creating a new WaitCursor object.  This invokes its constructor, setting the wait cursor.  When <em>wait</em> goes out of scope, the last reference to the object is lost, and the destructor is invoked and the cursor is reset &#8212; no matter how you get out of the code block.  If you want to preserve the cursor instead, you can just pass a reference to the object out of the block in another variable, and clear that variable when you no longer want the wait cursor.</p>
<p>But what happens if you have nested operations that, agnostic of each other, each want to set a wait cursor?  When the inner one finishes, it will reset the cursor to normal.  That&#8217;s not what you want at all.  I solved this by adding a static counter to the class, so we only reset the cursor if our count of active WaitCursor objects gets back to zero.</p>
<p>Of course it&#8217;s possible that other code is manipulating the cursor without using our class.  That could definitely interfere with our scheme, and should be avoided if possible.  One common case is the set of message box routines in the UI Toolkit (U_MESSAGE, U_MSGBOX, U_WAIT).  These routines always reset the cursor to the normal pointer so the user can use the mouse to click the buttons.  If you want to have the cursor go back to what it was before these routines were called, then you&#8217;ll probably need to <a href="http://www.chipstips.com/?p=109">wrap them in your own version</a> that saves off the current cursor state, calls the original, and then restores the cursor.</p>
<p><a href="http://www.chipstips.com/download/synwait.zip"><img src="http://www.chipstips.com/images/download.gif" alt="" /></a></p>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/r3wDdJHxzZk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=184</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=184</feedburner:origLink></item>
		<item>
		<title>Stopwatch application in C#</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/PvVOvt3q21w/</link>
		<comments>http://www.chipstips.com/?p=179#comments</comments>
		<pubDate>Fri, 29 Feb 2008 21:51:12 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Wildly popular]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[csstopwatch]]></category>
		<category><![CDATA[threads]]></category>
		<category><![CDATA[timers]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=179</guid>
		<description><![CDATA[As an independent consultant who bills by the hour, I have to keep track of how much time I spend on projects for different clients.  When various emergencies arise, that can get pretty confusing to reconstruct at the end of the day.  I needed an easy way to monitor my time with just a few [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=179"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=179" data-text="Stopwatch application in C#" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D179&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=179";
			reddit_title = "Stopwatch application in C#";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=179";</script>
		<script type="text/javascript">var dzone_title = "Stopwatch application in C#";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>As an independent consultant who bills by the hour, I have to keep track of how much time I spend on projects for different clients.  When various emergencies arise, that can get pretty confusing to reconstruct at the end of the day.  I needed an easy way to monitor my time with just a few mouse clicks.  So a few years ago I created the simple stopwatch application that you can download below.  One click to start, another to stop.  You can enter a description, and previously entered descriptions are remembered in a dropdown.  You can run multiple instances to keep track of time for multiple clients.  At the end of the day, you&#8217;ve got a total for each.</p>
<p>I wrote this as a C# Windows application using Visual Studio 2003.  Converting it for VS 2005 introduced a challenge, because accessing a control from another thread (the timer&#8217;s) is now considered unsafe and throws an exception.  So as you&#8217;ll see in the SetText method, I adopted a work-around from the MSDN documentation.</p>
<p>Back when I wrote this application, the code seemed quite concise.  Now that I&#8217;m older and wiser and have been exposed to Ruby, I can&#8217;t get over how verbose it is.  I can&#8217;t help but think that to do the same thing in JavaScript would be pretty trivial.  Maybe I&#8217;ll give it a go one day.</p>
<p><a href="http://www.chipstips.com/download/csstopwatch.zip"><img src="http://www.chipstips.com/images/download.gif" alt="" /></a></p>
<p>UPDATE 11/10/2008:  <a href="http://www.chipstips.com/?p=206">Here&#8217;s the JavaScript version</a>.</p>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/PvVOvt3q21w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=179</wfw:commentRss>
		<slash:comments>17</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=179</feedburner:origLink></item>
		<item>
		<title>Determining the size of an array passed as an argument in Synergy/DE</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/0IIOpQronlM/</link>
		<comments>http://www.chipstips.com/?p=166#comments</comments>
		<pubDate>Tue, 07 Aug 2007 19:13:26 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[OpenVMS]]></category>
		<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[dimension]]></category>
		<category><![CDATA[syngetdim]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=166</guid>
		<description><![CDATA[When an array is passed to a function or subroutine in Synergy/DE, the number of dimensions must be declared in the subroutine &#8212; but the size of each dimension may not be specified.&#160; Not knowing where the edge of a dimension lies can easily lead you to step off the garden path and over the [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=166"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=166" data-text="Determining the size of an array passed as an argument in Synergy/DE" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D166&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=166";
			reddit_title = "Determining the size of an array passed as an argument in Synergy/DE";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=166";</script>
		<script type="text/javascript">var dzone_title = "Determining the size of an array passed as an argument in Synergy/DE";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>When an array is passed to a function or subroutine in Synergy/DE, the number of dimensions must be declared in the subroutine &#8212; but the size of each dimension may not be specified.&nbsp; Not knowing where the edge of a dimension lies can easily lead you to step off the garden path and over the cliff known as &#8220;Segmentation violation&#8221;.&nbsp; Let&#8217;s not go there.</p>
<p>Synergy/DE version 9 adds a handy function, ^argdim, that lets you obtain the size of an array dimension.&nbsp; You pass it the argument number (starting at 1 &#8212; you can use ^argnum(name) to&nbsp;obtain that if you don&#8217;t feel like counting) and the dimension number (again, starting at 1 for the left-most dimension), and it returns the number of elements in that dimension.</p>
<p>If you&#8217;re still stuck on a pre-9 version of Synergy/DE, do not despair.&nbsp; The downloadable code below contains a function, %get_dim (in getdim.dbl), which does the same thing (except you pass it the argument name instead of the number).&nbsp; Get_dim achieves this magic by declaring the array parameter as a ^val address of a descriptor.&nbsp; When an argument is normally passed to a function, what really gets placed on the stack is a pointer to a descriptor that, um, describes the argument.&nbsp; The descriptor contains information about type, size, address of the data itself, and several other things including dimension information.&nbsp; If you look at the code you&#8217;ll probably notice that the dimension info is not all that straightforward.&nbsp; For one thing, on OpenVMS Synergy/DE uses a native descriptor, so the information is stored completely differently than on other platforms.&nbsp; That difference is conditionally compiled in the function, which works on UNIX, Windows, and OpenVMS.</p>
<p>The other file included, tdim.dbl, is a test routine for our function.&nbsp; It also uses conditional compilation to&nbsp;employ ^argdim if we&#8217;re on version 9 or later, and %get_dim otherwise.&nbsp; If you&#8217;re planning to use this in production code that&#8217;s cross-version, I would recommend putting that .ifdef block into an include file, and using the macro instead of calling %get_dim or ^argdim directly.</p>
</p>
<div class="downloadbutton"><a href="http://www.chipstips.com/download/syngetdim.zip"><img src="http://www.chipstips.com/images/download.gif"></a></div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/0IIOpQronlM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=166</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=166</feedburner:origLink></item>
		<item>
		<title>Ruby script to parse a version log file and update source files</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/_3CqoDnV7LQ/</link>
		<comments>http://www.chipstips.com/?p=160#comments</comments>
		<pubDate>Sun, 18 Mar 2007 21:23:32 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[Wildly popular]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[pvcs]]></category>
		<category><![CDATA[rbupdate]]></category>
		<category><![CDATA[regexen]]></category>
		<category><![CDATA[samba]]></category>
		<category><![CDATA[versioncontrol]]></category>
		<category><![CDATA[vpn]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=160</guid>
		<description><![CDATA[Working remotely via VPN on a big project presents some challenges, not the least of which is keeping your local source files up to date with the thousands of version control archives. Running a script to check all of the remote archives against your local sources can take a lot of time and bandwidth. Yet, [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=160"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=160" data-text="Ruby script to parse a version log file and update source files" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D160&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=160";
			reddit_title = "Ruby script to parse a version log file and update source files";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=160";</script>
		<script type="text/javascript">var dzone_title = "Ruby script to parse a version log file and update source files";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>Working remotely via VPN on a big project presents some challenges, not the least of which is <a href="http://www.chipsquips.com/?p=795">keeping your local source files up to date with the thousands of version control archives</a>.  Running a script to check all of the remote archives against your local sources can take a lot of time and bandwidth.  Yet, if you don&#8217;t stay up to date, how will you know if your changes will be compatible with the latest version?  You&#8217;d really like to know exactly which archives have been modified and just check those against your local copies.</p>
<p>One such project I work on uses <a href="http://synergex.com/solutions/pvcs/products/">PVCS</a> for version control.  PVCS writes a log file for all modifications to the archives.  Each entry in the log contains the name of the archive file (full path), the person who made the modification, the date, time, and nature of the modification &#8212; all comma-delimited.  So, I wrote a handy little Ruby script (which you can download below) to read the log, looking for updates on or after a specified date.  For those it finds, it spawns a PVCS &#8216;get&#8217; command using -u (update only if more recent) and -n (answer &#8216;n&#8217; to any prompts, such as &#8220;a writable version exists, overwrite?&#8221;).</p>
<p>Even if you don&#8217;t have a need for such a script yourself, you might find some interesting features of Ruby in this example.  Or, if you&#8217;re a better Rubyist than I, maybe you could show me how to make this script even more elegant.</p>
<p>The archives are stored in a directory structure that mirrors the source file directory structure on the local machine.  Development occurs on both *nix and Windows workstations, so the root of the archive path in the log may be &#8216;/usr/archive&#8217; or a drive letter mapped over <a href="http://us1.samba.org/samba/">Samba</a>.  Thus, we must strip off any of these archive path prefixes, and then add our local source root, in order to know where each source file needs to go.</p>
<p>To avoid duplication of effort, we use a hash keyed on the full archive path (with root prefix stripped).  The corresponding value in the hash is an array containing the archive directory and the filename.</p>
<p>See the comments within the script for further information and usage instructions.</p>
<div class="downloadbutton"><a href="http://www.chipstips.com/download/rbupdate.zip"><img src="http://www.chipstips.com/images/download.gif" /></a></div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/_3CqoDnV7LQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=160</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=160</feedburner:origLink></item>
		<item>
		<title>Launching Windows applications by associated file extension for ruby (or C#)</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/V4MFExUzs9k/</link>
		<comments>http://www.chipstips.com/?p=156#comments</comments>
		<pubDate>Wed, 24 Jan 2007 21:14:10 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Wildly popular]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[codeproject]]></category>
		<category><![CDATA[dll]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[rbshellexecute]]></category>
		<category><![CDATA[shell32]]></category>
		<category><![CDATA[shellexecute]]></category>
		<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[win32api]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=156</guid>
		<description><![CDATA[Quite frequently, sometimes several times a day, a Google search for something like &#8220;launch application by file extension&#8221; or &#8220;shellexecute&#8221; will bring the errant searcher to this post, which describes how to do just exactly that &#8212; in Synergy/DE. Unfortunately, most of these seekers of wisdom usually add &#8220;C#&#8221; or &#8220;ruby&#8221; to their queries. I [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=156"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=156" data-text="Launching Windows applications by associated file extension for ruby (or C#)" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D156&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=156";
			reddit_title = "Launching Windows applications by associated file extension for ruby (or C#)";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=156";</script>
		<script type="text/javascript">var dzone_title = "Launching Windows applications by associated file extension for ruby (or C#)";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>Quite frequently, sometimes several times a day, a Google search for something like &#8220;launch application by file extension&#8221; or &#8220;shellexecute&#8221; will bring the errant searcher to <a href="http://www.chipstips.com/?p=89">this post</a>, which describes how to do just exactly that &#8212; in Synergy/DE.  Unfortunately, most of these seekers of wisdom usually add &#8220;C#&#8221; or &#8220;ruby&#8221; to their queries.</p>
<p>I hate to see people land on my site and not get the answer they&#8217;re looking for.  So lets give them something to find, shall we?</p>
<p>No need to create a C# example because there&#8217;s a great one over on <a href="http://www.codeproject.com/csharp/csdoesshell2.asp">The Code Project</a>.</p>
<p>However, a good Ruby example eluded my search, so I whipped one up.  You can download it below.  As you might expect, it creates a Win32API object for the necessary linkage to ShellExecute in shell32.dll, then calls it to launch the associated application for whatever file and verb you pass.  Naturally, this only works on Microsoft Windows platforms.</p>
<div class="downloadbutton" ><a href="http://www.chipstips.com/download/rbshellexecute.zip"><img src="http://www.chipstips.com/images/download.gif" /></a></div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/V4MFExUzs9k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=156</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=156</feedburner:origLink></item>
		<item>
		<title>Drawing a blank</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/Jott6414NYw/</link>
		<comments>http://www.chipstips.com/?p=155#comments</comments>
		<pubDate>Tue, 09 Jan 2007 23:39:49 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[UI Toolkit]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[apotheon]]></category>
		<category><![CDATA[check]]></category>
		<category><![CDATA[dandesch]]></category>
		<category><![CDATA[harlandfs]]></category>
		<category><![CDATA[menu]]></category>
		<category><![CDATA[synmnuchk]]></category>
		<category><![CDATA[trim]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=155</guid>
		<description><![CDATA[Dan Desch of Harland Financial Solutions pointed out a bug in my June 2001 post on checked menu entries in Synergy/DE. Synergy/DE has no built-in function to trim leading spaces from a string, so I had used the following snippet: while (.not. text(1:1)) text = text(2,^size(text)) ;Trim leading spaces which works fine so long as [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=155"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=155" data-text="Drawing a blank" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D155&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=155";
			reddit_title = "Drawing a blank";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=155";</script>
		<script type="text/javascript">var dzone_title = "Drawing a blank";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p><img height="106" alt="" hspace="10" src="http://www.chipstips.com/wp-content/uploads/2007/01/checkedmenu.jpg" width="124" align="left" />Dan Desch of <a href="http://harlandfs.com/">Harland Financial Solutions</a> pointed out a bug in my June 2001 post on <a href="http://www.chipstips.com/?p=94">checked menu entries in Synergy/DE</a>. Synergy/DE has no built-in function to trim leading spaces from a string, so I had used the following snippet:</p>
<pre>
<code>        while (.not. text(1:1))<br />
          text = text(2,^size(text))        ;Trim leading spaces</code>
</pre>
<p>which works fine so long as text contains at least one non-space character. Most menu entries fall into that category, except for those created by the &#8220;.BLANK&#8221; script command. In that case, this code goes into an infinite loop, because the overlay move blank extends to the length of the field, so you end up with exactly what you had to begin with.</p>
<p>Dan&#8217;s proposed solution was to branch around this logic if the entire field was blank, but I took this opportunity to optimize this code a bit. After all, performing iterative overlay moves of the entire field by one character doesn&#8217;t really jingle my <a href="http://sob.apotheon.org/?p=113">elegance</a> bells. So I replaced it with this algorithm:</p>
<pre>
<code>        for ptr2 from 1 thru %trimz(text) ;For trimmed length<br />
          if (text(ptr2:1))   ;Search for non-blank                   <br />
             exitloop<br />
        if (ptr2 .gt. 1)<br />
          text = text(ptr2,^size(text)) ;Trim leading spaces</code>
</pre>
<p>Synergy/DE optimizes the &#8220;for&#8221; statement such that %trimz is only executed once to get the right-trimmed length.  If the field is all blank %trimz returns 0, so we&#8217;ll just exit the loop with ptr2 set to 1.</p>
<p>Now no matter how many leading spaces the field contains, we will do a maximum of 1 overlay move of the data. If the field contains no leading spaces (by far the majority of cases) then we&#8217;ve only executed one iteration of the for loop and the two if&#8217;s.</p>
<p>Naturally, if you have a need to do this sort of thing regularly, you could write your own function using this logic, and instead of moving the data over, just return the left-trimmed portion, else return the original, like so:</p>
<pre>
<code>        for ptr2 from 1 thru %trimz(text) ;For trimmed length<br />
          if (text(ptr2:1))   ;Search for non-blank<br />
            exitloop<br />
        if (ptr2 .gt. 1)<br />
          freturn text(ptr2,^size(text)) ;Trim leading spaces
        freturn text</code>
</pre>
<p>You can download the corrected version at the <a href="http://www.chipstips.com/?p=94">original post</a>.</p>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/Jott6414NYw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=155</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=155</feedburner:origLink></item>
		<item>
		<title>Disable/enable double-click on Synergy lists in Windows.</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/hLrTlKTxxGQ/</link>
		<comments>http://www.chipstips.com/?p=147#comments</comments>
		<pubDate>Tue, 01 Aug 2006 17:31:11 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[Wildly popular]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[dblclk]]></category>
		<category><![CDATA[l_method]]></category>
		<category><![CDATA[l_select]]></category>
		<category><![CDATA[spread]]></category>
		<category><![CDATA[synldblclk]]></category>
		<category><![CDATA[u_wndevents]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/?p=147</guid>
		<description><![CDATA[On Windows platforms, Synergy/DE lists provide three different ways to handle a mouse double-click: By default, a RETURN is simulated (thus selecting the item, when using L_SELECT). You can register a list double-click method in the listclass, or by using L_METHOD with D_LDBLCLK. You can include a UWNDEVENTS_METHOD for double-click in a method set provided [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=147"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=147" data-text="Disable/enable double-click on Synergy lists in Windows." data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D147&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=147";
			reddit_title = "Disable/enable double-click on Synergy lists in Windows.";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=147";</script>
		<script type="text/javascript">var dzone_title = "Disable/enable double-click on Synergy lists in Windows.";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>On Windows platforms, Synergy/DE lists provide three different ways to handle a mouse double-click:</p>
<ol>
<li>By default, a RETURN is simulated (thus selecting the item, when using L_SELECT).</li>
<li>You can register a list double-click method in the listclass, or by using L_METHOD with D_LDBLCLK.</li>
<li>You can include a UWNDEVENTS_METHOD for double-click in a method set provided to L_METHOD with D_LWNDEVENT.</li>
</ol>
<p>But what if you just want to suppress any action on double-click?  The downloadable code below shows you how.  The example includes a subroutine to modify the style of the window class to disable or enable double-clicks.  Note, however, that because this style is included in the window class rather than the window itself, the change affects ALL Listbox windows in the entire application (thanks, Microsoft).  So, a good practice is to change the style for the smallest possible duration, and then change it back.</p>
<p><strike>Note also that this technique does not work with the ActiveX list, although a similar technique could be used (hint: the Spread window is a grandchild of the container, and its class name changes with each major version).</strike>  UPDATE: I modified this code to work for ActiveX lists as well (just for you, Glynis).  Note that on the next major version of <a href="http://fpoint.com/products/spread/spread.aspx">Spread</a>, the class name used (&#8220;SPR32A70_SpreadSheet&#8221;) will no doubt change.  Also, when you call this routine for an ActiveX list, the double-click suppression will apply to not only all ActiveX lists in your application, but also to any Spread controls you may be using.</p>
<p>The example also includes code that requires Synergy/DE version 8.3 or higher.</p>
<div><a href="http://www.chipstips.com/download/synldblclk.zip"><img src="http://www.chipstips.com/images/download.gif" /></a></div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/hLrTlKTxxGQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=147</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=147</feedburner:origLink></item>
		<item>
		<title>Changing the foreground color for disabled fields</title>
		<link>http://feedproxy.google.com/~r/ChipsTipsWindows/~3/eI47gIsbimM/</link>
		<comments>http://www.chipstips.com/?p=92#comments</comments>
		<pubDate>Wed, 05 Apr 2006 22:46:23 +0000</pubDate>
		<dc:creator>Sterling Camden</dc:creator>
				<category><![CDATA[SynergyDE]]></category>
		<category><![CDATA[UI Toolkit]]></category>
		<category><![CDATA[Wildly popular]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[colors]]></category>
		<category><![CDATA[controlpanel]]></category>
		<category><![CDATA[disabled]]></category>
		<category><![CDATA[graytext]]></category>
		<category><![CDATA[setsyscolors]]></category>
		<category><![CDATA[syndsaclr]]></category>
		<category><![CDATA[user32]]></category>

		<guid isPermaLink="false">http://www.chipstips.com/new/?p=92</guid>
		<description><![CDATA[In Synergy/DE on Windows, the colors applied to some parts of your application are determined by the Windows registry, rather than by renditions settings in Synergy/DE. This means that most of the time a user can figure out how to control a given component&#8217;s rendition by looking in Windows Control Panel or the Synergy Control [...]]]></description>
				<content:encoded><![CDATA[<div class="socialize-in-content socialize-in-content-right"><div class="socialize-in-button socialize-in-button-right"><g:plusone size="tall" href="http://www.chipstips.com/?p=92"></g:plusone></div><div class="socialize-in-button socialize-in-button-right"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://www.chipstips.com/?p=92" data-text="Changing the foreground color for disabled fields" data-count="vertical" data-via="socializeWP" ><!--Tweetter--></a></div><div class="socialize-in-button socialize-in-button-right"><iframe src="//www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.chipstips.com%2F%3Fp%3D92&amp;send=&amp;layout=box_count&amp;width=50&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=65" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:50px; height:65px;" allowTransparency="true"></iframe></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">
			<!-- 
			reddit_url = "http://www.chipstips.com/?p=92";
			reddit_title = "Changing the foreground color for disabled fields";	//-->
		</script><script type="text/javascript" src="http://www.reddit.com/static/button/button2.js"></script></div><div class="socialize-in-button socialize-in-button-right"><script type="text/javascript">var dzone_url = "http://www.chipstips.com/?p=92";</script>
		<script type="text/javascript">var dzone_title = "Changing the foreground color for disabled fields";</script>
		<script type="text/javascript">
			<!-- 
			var dzone_style = "1";
			//-->
		</script><script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script></div></div><p>In Synergy/DE on Windows, the colors applied to some parts of your application are determined by the Windows registry, rather than by renditions settings in Synergy/DE.  This means that most of the  time a user can figure out how to control a given component&#8217;s rendition by looking in Windows Control Panel or the Synergy Control Panel.</p>
<p>Not so for disabled fields.  Windows does not provide a visual means for altering the &#8220;gray text&#8221; rendition, and it forces that rendition on all disabled fields.  There is literally no way around it, short of subclassing the display for edit controls.  With the default background color being a darker gray, the text of disabled fields can be difficult to read, which has caused some frustration for Synergy/DE users and developers.</p>
<p>All Windows colors can be programmatically manipulated via the user32.dll function &#8220;SetSysColors&#8221;. The download below demonstrates how to modify the COLOR_GRAYTEXT system color to whatever color you would like.  Note, however, that after you change that color, the change takes effect for ALL applications from this point forward for the current user.  So, wield this weapon with care.</p>
<p>Blogged about this <a href="http://www.chipstips.com/microblog/index.php/post/335/">here</a>.</p>
<div><a href="http://www.chipstips.com/download/syndsaclr.zip"><img src="http://www.chipstips.com/images/download.gif" /></a></div>
<img src="http://feeds.feedburner.com/~r/ChipsTipsWindows/~4/eI47gIsbimM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.chipstips.com/?feed=rss2&amp;p=92</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.chipstips.com/?p=92</feedburner:origLink></item>
	</channel>
</rss>
