<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-4328000167354514086</id><updated>2009-11-10T13:49:17.903-05:00</updated><title type="text">Parks Computing</title><subtitle type="html">Welcome to the personal web site of Paul M. Parks. This is where I keep my web development skills current while sharing snippets of code, utilities, libraries, and what little development wisdom I've gathered in my career. It's also where I show off my family, talk about my hobbies, or just pontificate from time to time.</subtitle><link rel="alternate" type="text/html" href="http://www.parkscomputing.com/default.aspx" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default?start-index=26&amp;max-results=25" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://feeds2.feedburner.com/ParksComputing" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/ParksComputing" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-756495562029209778</id><published>2009-11-09T17:40:00.020-05:00</published><updated>2009-11-10T10:41:46.866-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="COM" /><category scheme="http://www.blogger.com/atom/ns#" term="ripsaw" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">Ripsaw COM Interface, First Pass</title><content type="html">In this installment of the &lt;a href="/labels/ripsaw.html"&gt;Ripsaw article series&lt;/a&gt; we'll finally get to write some code. We've already gotten a pretty good idea about how we want to implement the core Ripsaw library, so now we're going to define enough of the COM interface that we can create a simple test script that will eventually be used to exercise the library.&lt;br /&gt;&lt;br /&gt;&lt;span class="summarypost"&gt;(This is a long article, so click the "Read full article" link below for more.)&lt;/span&gt;&lt;div class="fullpost"&gt;To be callable from script, the object's interface should be OLE-automation compatible, so we'll declare it as such in our &lt;a href="http://msdn.microsoft.com/en-us/library/aa367091%28VS.85%29.aspx"&gt;IDL&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;[&lt;br /&gt;   oleautomation,&lt;br /&gt;   uuid(2D486A73-E912-4078-9F38-678226E4A0BD),&lt;br /&gt;   dual,&lt;br /&gt;   pointer_default(unique)&lt;br /&gt;]&lt;br /&gt;interface IRipsawFile : IDispatch&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The interface is also derived from &lt;code&gt;IDispatch&lt;/code&gt; to support late-binding, which means that scripting languages can discover the methods and properties of the interface at runtime.&lt;br /&gt;&lt;br /&gt;Before we can write the test script we'll need decide what basic methods a Ripsaw object needs to implement. A single Ripsaw object will represent a connection to a file, and the object will fire events whenever the file changes so that listeners can take an action based on the update (change the display, parse the update, etc.). At a minimum, then, we need to be able to open a file and close a file.&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;interface IRipsawFile : IDispatch&lt;br /&gt;{&lt;br /&gt;   [id(1)] HRESULT Open(&lt;br /&gt;      [in] BSTR fileName,&lt;br /&gt;      [out,retval] VARIANT_BOOL* pSuccess);&lt;br /&gt;&lt;br /&gt;   [id(2)] HRESULT Close();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The &lt;code&gt;Open&lt;/code&gt; method will accept a path to a file and return a Boolean indicating the success or failure of the method call. The &lt;code&gt;Close&lt;/code&gt; method will close any existing connection, and we won't bother to check for a return code from that method.&lt;br /&gt;&lt;br /&gt;Now, it would probably be useful to be able to query a property of the object for the name of the file to which it is connected, and perhaps another property to check if the object is currently opened or closed. Let's add those properties:&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;interface IRipsawFile : IDispatch&lt;br /&gt;{&lt;br /&gt;   [id(1), propget] HRESULT Name(&lt;br /&gt;      [out,retval] BSTR* pName);&lt;br /&gt;&lt;br /&gt;   [id(2), propget] HRESULT IsOpen(&lt;br /&gt;      [out,retval] VARIANT_BOOL* pRetVal);&lt;br /&gt;&lt;br /&gt;   [id(3)] HRESULT Open(&lt;br /&gt;      [in] BSTR fileName,&lt;br /&gt;      [out,retval] VARIANT_BOOL* pSuccess);&lt;br /&gt;&lt;br /&gt;   [id(4)] HRESULT Close();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Okay, not bad so far. We can open a file, query for the status, query for the name, and close the file. That's no good if we can't catch events fired by the object. We need to define a &lt;code&gt;dispinterface&lt;/code&gt; that specifies the events that the object can fire at its clients:&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;[ uuid(6671C129-C761-42F3-AB2F-D12C33D95160) ]&lt;br /&gt;dispinterface _IRipsawEvents&lt;br /&gt;{&lt;br /&gt;properties:&lt;br /&gt;methods:&lt;br /&gt;   [id(1)] HRESULT Open([in] BSTR fileName);&lt;br /&gt;   [id(2)] HRESULT Close([in] BSTR fileName);&lt;br /&gt;   [id(3)] HRESULT Update([in] BSTR updateData);&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The &lt;code&gt;Open&lt;/code&gt; event fires when a file is opened successfully, of course. &lt;code&gt;Close&lt;/code&gt; fires when a file is closed, and &lt;code&gt;Update&lt;/code&gt; naturally fires when the file changes. The &lt;code&gt;Update&lt;/code&gt; notification will also pass along the data that was gathered from the last file update.&lt;br /&gt;&lt;br /&gt;Okay, based on those interfaces, our script might look like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;var ripsaw = WScript.CreateObject("PMP.RipsawFile", "ripsaw_");&lt;br /&gt;&lt;br /&gt;if (ripsaw)&lt;br /&gt;{&lt;br /&gt;   ripsaw.Open("testfile.log");&lt;br /&gt;&lt;br /&gt;   if (ripsaw.IsOpen)&lt;br /&gt;   {&lt;br /&gt;      WScript.Echo("Ripsaw file is open: '" + ripsaw.Name + "'");&lt;br /&gt;&lt;br /&gt;      /* Uh-oh... */&lt;br /&gt;&lt;br /&gt;      ripsaw.Close();&lt;br /&gt;&lt;br /&gt;      if (!ripsaw.IsOpen)&lt;br /&gt;      {&lt;br /&gt;         WScript.Echo("Ripsaw file is closed: '" + ripsaw.Name + "'");&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;         WScript.Echo("ERROR: Ripsaw file reported open");&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;      WScript.Echo("ERROR: Ripsaw file reported closed");&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;   WScript.Echo("ERROR: Failed to create Ripsaw file");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function ripsaw_Open(fileName)&lt;br /&gt;{&lt;br /&gt;   WScript.Echo("ripsaw_Open(" + fileName + ")")&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function ripsaw_Close(fileName)&lt;br /&gt;{&lt;br /&gt;   WScript.Echo("ripsaw_Close(" + fileName + ")")&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function ripsaw_Update(data) &lt;br /&gt;{&lt;br /&gt;   WScript.Echo("ripsaw_Update(" + data + ")")&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;First of all, I'll explain what all this means for those of you that are new to JavaScript &amp;mdash; err, JScript &amp;mdash; under &lt;a href="http://msdn.microsoft.com/en-us/library/9bbdkx3k%28VS.85%29.aspx"&gt;Windows Script Host&lt;/a&gt; (WSH). The first line creates a COM object based on its &lt;a href="http://msdn.microsoft.com/en-us/library/dd542719%28VS.85%29.aspx"&gt;ProgID&lt;/a&gt;, or programmatic identifier. This is a string that resolves, through the registry, to a &lt;a href="http://en.wikipedia.org/wiki/Globally_Unique_Identifier"&gt;GUID&lt;/a&gt; that uniquely identifies a COM library that provides the requested functionality.&lt;br /&gt;&lt;br /&gt;The second parameter to &lt;code&gt;CreateObject&lt;/code&gt; tells the scripting engine to wire events provided by the object to functions that start with the specified prefix. In our script, we want to handle the Open, Close, and Update notifications, so we created functions named &lt;code&gt;ripsaw_Open&lt;/code&gt;, &lt;code&gt;ripsaw_Close&lt;/code&gt;, and &lt;code&gt;ripsaw_Update&lt;/code&gt; to catch these events. Since they all start with the "ripsaw_" prefix, the script engine will call them when any of the corresponding events are fired by our object.&lt;br /&gt;&lt;br /&gt;If you looked carefully at the script, you noticed that I inserted a comment: "Uh-oh." That's because the script has no way of sitting and waiting for an update other than looping in a tight loop, and that is almost never a good idea. The script would waste CPU time doing nothing while we wait for the file to be updated. In other languages we have access to message loops, &lt;code&gt;WaitForSingleObject&lt;/code&gt;, and other means of yielding CPU until an event occurs, but not in WSH. We need something better. What we'll do is add a method to our object which, when called, will do absolutely nothing until an update occurs. We'll call it &lt;code&gt;WaitForUpdate&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;interface IRipsawFile : IDispatch&lt;br /&gt;{&lt;br /&gt;   [id(1), propget] HRESULT Name(&lt;br /&gt;      [out,retval] BSTR* pName);&lt;br /&gt;&lt;br /&gt;   [id(2), propget] HRESULT IsOpen(&lt;br /&gt;      [out,retval] VARIANT_BOOL* pRetVal);&lt;br /&gt;&lt;br /&gt;   [id(3)] HRESULT Open(&lt;br /&gt;      [in] BSTR fileName,&lt;br /&gt;      [out,retval] VARIANT_BOOL* pSuccess);&lt;br /&gt;&lt;br /&gt;   [id(4)] HRESULT Close();&lt;br /&gt;&lt;br /&gt;   [id(5)] HRESULT WaitForUpdate(&lt;br /&gt;      [in] ULONG timeout,&lt;br /&gt;      [out,retval] BSTR* pNewData);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The first parameter is a timeout, in milliseconds, so that the function will return if no updates arrive in the specified amount of time. We'll take a page from Win32 and say that a value of 0xFFFFFFFF will tell the method to wait forever. If the timeout expires, the method will return a null &lt;code&gt;BSTR&lt;/code&gt;; otherwise, the return value will be the new data from the last file update. We'll modify the heart of our script to call the new method:&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;      WScript.Echo("Ripsaw file is open: '" + ripsaw.Name + "'");&lt;br /&gt;&lt;br /&gt;      var timeout = 5000;&lt;br /&gt;      WScript.Echo("Waiting for data...");&lt;br /&gt;      var newData = ripsaw.WaitForUpdate(timeout);&lt;br /&gt;&lt;br /&gt;      if (newData)&lt;br /&gt;      {&lt;br /&gt;         WScript.Echo("Waited for data:", newData);&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;         WScript.Echo("Timed out after waiting for data for " + timeout + " milliseconds");&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      ripsaw.Close();&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In a real script we'll probably call &lt;code&gt;WaitForUpdate&lt;/code&gt; in a loop, but for now we'll just wait for one update before exiting.&lt;h3&gt;Generalizing the Interface&lt;/h3&gt;This looks good for files, but perhaps later on we'd like to extend Ripsaw to listen to other sources of events, like the &lt;a href="http://msdn.microsoft.com/en-us/library/aa385780%28VS.85%29.aspx"&gt;Windows Event Log&lt;/a&gt; (the first Ripsaw actually did that for a while, but I backed out the feature to focus on files). It would be a good idea to go ahead and factor out the common methods and properties into a base interface that could be extended by other event sources.&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;[&lt;br /&gt;   oleautomation,&lt;br /&gt;   uuid(0270FDFF-56AF-42ec-9971-AE8DCB0DAB36),&lt;br /&gt;   dual,&lt;br /&gt;   pointer_default(unique)&lt;br /&gt;]&lt;br /&gt;interface IRipsawObject : IDispatch&lt;br /&gt;{&lt;br /&gt;   [id(1), propget] HRESULT Name(&lt;br /&gt;      [out,retval] BSTR* pName);&lt;br /&gt;&lt;br /&gt;   [id(2), propget] HRESULT IsOpen(&lt;br /&gt;      [out,retval] VARIANT_BOOL* pRetVal);&lt;br /&gt;&lt;br /&gt;   [id(3)] HRESULT Close();&lt;br /&gt;&lt;br /&gt;   [id(4)] HRESULT WaitForUpdate(&lt;br /&gt;      [in] ULONG timeout,&lt;br /&gt;      [out,retval] BSTR* pNewData);&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;[&lt;br /&gt;   oleautomation,&lt;br /&gt;   uuid(2D486A73-E912-4078-9F38-678226E4A0BD),&lt;br /&gt;   dual,&lt;br /&gt;   pointer_default(unique)&lt;br /&gt;]&lt;br /&gt;interface IRipsawFile : IRipsawObject&lt;br /&gt;{&lt;br /&gt;   [id(10)] HRESULT Open(&lt;br /&gt;      [in] BSTR fileName,&lt;br /&gt;      [out,retval] VARIANT_BOOL* pSuccess);&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Later on, if we define an interface for listening to event logs, we'll derive that interface from &lt;code&gt;IRipsawObject&lt;/code&gt; and define an &lt;code&gt;Open&lt;/code&gt; method specific to event logs. We'll also assign a special ProgID to event log objects so our client applications can create them:&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;var ripsaw = WScript.CreateObject("PMP.RipsawEventLog", "ripsaw_");&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Next Steps&lt;/h3&gt;Now we have an interface, and we have a script to exercise that interface. What we need next is some real code to implement the interface and a binary that the script can load and run. We'll start on a preliminary implementation in the next article. Until then, you can download &lt;a href="/ripsaw/articles/RipsawSource_20091109.zip"&gt;the IDL and the script file&lt;/a&gt; and look them over. Please leave a comment with any suggestions you may have.&lt;/div&gt;&lt;!-- fullpost --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-756495562029209778?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Sn3uTW2fUAxPu8NgAyX5avDTBJY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Sn3uTW2fUAxPu8NgAyX5avDTBJY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Sn3uTW2fUAxPu8NgAyX5avDTBJY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Sn3uTW2fUAxPu8NgAyX5avDTBJY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/o0UCfD5jSzQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/756495562029209778/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=756495562029209778" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/756495562029209778" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/756495562029209778" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/o0UCfD5jSzQ/ripsaw-com-interface-first-pass.html" title="Ripsaw COM Interface, First Pass" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/11/ripsaw-com-interface-first-pass.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-2370552826114028504</id><published>2009-11-06T08:05:00.009-05:00</published><updated>2009-11-07T11:38:19.842-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ripsaw" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">Refining Ripsaw's Design</title><content type="html">In my last entry in the &lt;a href="/labels/ripsaw.html"&gt;Ripsaw article series&lt;/a&gt;, I discussed some of the &lt;a href="/2009/10/design-goals-for-ripsaw.html"&gt;design goals for Ripsaw&lt;/a&gt;. In this article I'll flesh out the design a little more and discuss specific implementation possibilities.&lt;br /&gt;&lt;br /&gt;To bring you up to speed, Ripsaw is a log-viewing utility for Windows that I initially wrote about six years ago, but never released widely. I've decided to rewrite it and discuss each step of the rewrite here.&lt;br /&gt;&lt;h3&gt;Implementing the API&lt;/h3&gt;The initial Ripsaw implementation was a monolithic (albeit small) application, but this time I want to separate the log-reading mechanism from the log-viewing UI. There are times when I'd like to use the log-reading capabilities of Ripsaw from JavaScript or &lt;a href="http://technet.microsoft.com/en-us/scriptcenter/dd742419.aspx"&gt;PowerShell&lt;/a&gt;, and I'd also like to write more than one viewer application around the log reader. There are at least three possible technologies for this API:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;C DLL&lt;/li&gt;&lt;li&gt;COM&lt;/li&gt;&lt;li&gt;.NET&lt;/li&gt;&lt;/ol&gt;Okay, there are a lot more that I could choose from, but for the machines I'm targeting these are the most likely candidates. A DLL exporting C functions would be the simplest to write and would be easy to integrate with most programming languages, but in order to use that sort of API from JavaScript (or similar languages) I'd have to write a COM wrapper. A .NET implementation would be COM-callable, but it would require having .NET installed on the target machine, and sometimes the systems I debug don't have .NET installed (hard to believe, I know, but true). COM, however, is ubiquitous on Windows, fairly straightforward, can be used from JavaScript with ease, and is easily callable from .NET if I had a reason to do so later on. Therefore, I'll implement Ripsaw's non-UI behavior in a COM library.&lt;br /&gt;&lt;h3&gt;What About Registration?&lt;/h3&gt;I'd still like to be able to run Ripsaw from a USB drive without having to install anything on the machine I'm debugging or examining, which means I'd like to avoid the hassle of having to run &lt;a href="http://technet.microsoft.com/en-us/library/bb490985.aspx"&gt;regsvr32&lt;/a&gt; on the target machine before I can use Ripsaw. Fortunately, there is &lt;a href="http://msdn.microsoft.com/en-us/library/ms973913.aspx"&gt;registration-free COM&lt;/a&gt;, which will let me run a Ripsaw viewer that loads the Ripsaw COM library with the aid of a manifest. This will let me keep a viewer and the Ripsaw library in a directory on my USB drive so I can just plug it in and run the viewer without having to register or install anything.&lt;br /&gt;&lt;h3&gt;Supporting Scripting in the Viewer&lt;/h3&gt;Since Ripsaw's log-reading capability will be implemented in COM, I'll be able to write JavaScript apps that can watch for data from a log file, and these scripts can either parse the data or take actions based on the data. Not only would this be useful apart from a viewer, but it might also be useful &lt;em&gt;inside&lt;/em&gt; a viewer. I could define script actions to operate on log lines, highlight them, parse them, etc., while I'm watching a log in the viewer. To take advantage of this I'll add JavaScript support to the Windows Ripsaw viewer, along with the capability to load pre-defined scripts that act on log data.&lt;br /&gt;&lt;h3&gt;Viewer Implementation&lt;/h3&gt;In keeping with my requirement for making Ripsaw light and portable, I don't want to use .NET for the main viewer implementation. I might create a &lt;a href="http://msdn.microsoft.com/en-us/library/dd30h2yb.aspx"&gt;Windows Forms&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/aa663364.aspx"&gt;WPF&lt;/a&gt; viewer later on once .NET becomes more widespread on the systems I mainly work on (point-of-sale terminals and servers for grocery stores), or for when I'm debugging in a controlled environment, but for the main console and GUI viewers I'll use C++ as the development language. COM is still a bit of a pain to use from C++, at least compared to JavaScript or .NET, but it won't be too bad.&lt;br /&gt;&lt;h3&gt;Multiprocessor Support&lt;/h3&gt;Fortunately, the newer POS terminals and servers that are being installed today have multi-core processors, and I definitely want to take advantage of that today. I want to architect the core Ripsaw library to take advantage of multiple threads of execution spread across multiple processors or processor cores. I already write multi-threaded, multi-process systems for these machines, and these systems tend to be heavily instrumented, so sometimes I'm watching several different log files at once during a testing or debugging session. I don't want to slow a system down too much when I start up the viewer, and loading down one core of a multi-core processor with a log viewer would certainly be a bad thing.&lt;br /&gt;&lt;h3&gt;Okay, Can We Start Coding Now?&lt;/h3&gt;Actually, I already have been doing some prototyping, which helped me decide on the details I've described above. Now that I've sorted out some of the lower-level requirements, in the next article I'll start defining the Ripsaw log-reader COM interface.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-2370552826114028504?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EE_Qs1qpCBfnb2fwmgWvFPrn0ls/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EE_Qs1qpCBfnb2fwmgWvFPrn0ls/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EE_Qs1qpCBfnb2fwmgWvFPrn0ls/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EE_Qs1qpCBfnb2fwmgWvFPrn0ls/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/WcM4KCasJUY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/2370552826114028504/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=2370552826114028504" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/2370552826114028504" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/2370552826114028504" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/WcM4KCasJUY/refining-ripsaws-design.html" title="Refining Ripsaw's Design" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/11/refining-ripsaws-design.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-9189092896414351550</id><published>2009-11-02T16:20:00.003-05:00</published><updated>2009-11-02T16:23:21.257-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="consulting" /><title type="text">Busy Until January</title><content type="html">I've been assigned to a new project through the end of 2009 so I'm unavailable for now, but if I'm not picked up for an extension I'll be looking for new projects in 2010. Take a look at &lt;a href="/resume.html"&gt;my resume&lt;/a&gt; and let me know if I might be a good fit for any contract or consulting opportunities in your organization. I'm currently W-2 with a small consulting company, but I'm open to 1099 or corp-to-corp starting next year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-9189092896414351550?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/fHun09j8J1Pd60MOXmrSvlFfkAA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fHun09j8J1Pd60MOXmrSvlFfkAA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/fHun09j8J1Pd60MOXmrSvlFfkAA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fHun09j8J1Pd60MOXmrSvlFfkAA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/jyZue1sXFvI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/9189092896414351550/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=9189092896414351550" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/9189092896414351550" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/9189092896414351550" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/jyZue1sXFvI/busy-until-january.html" title="Busy Until January" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/11/busy-until-january.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-8045707117541255831</id><published>2009-10-27T18:00:00.003-04:00</published><updated>2009-10-27T18:17:25.344-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><category scheme="http://www.blogger.com/atom/ns#" term="band" /><category scheme="http://www.blogger.com/atom/ns#" term="GWA" /><title type="text">George Walton Academy: Champs!</title><content type="html">&lt;a class="img-shadow" style="float: right;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://gwabands.org/default.aspx"&gt;&lt;img src="/images/GWABand2009.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Congratulations to the &lt;a href="http://www.gwa.com/"&gt;George Walton Academy&lt;/a&gt; &lt;a href="http://gwabands.org/default.aspx"&gt;Marching Bulldog Band&lt;/a&gt; for taking first place in the Group VI Open division of the USSBA Southern States band competition this past weekend in Chattanooga. My elder daughter, Madeline, is a member of the color guard. They put on a fantastic show, winning caption awards for overall effect, percussion, and music. They also won the Marine Corps Esprit de Corps award. Way to go, band!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-8045707117541255831?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8BUzzu5PwuCLX5OTX7az4lx7Um8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8BUzzu5PwuCLX5OTX7az4lx7Um8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8BUzzu5PwuCLX5OTX7az4lx7Um8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8BUzzu5PwuCLX5OTX7az4lx7Um8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/ne_1YwE-1tA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/8045707117541255831/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=8045707117541255831" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/8045707117541255831" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/8045707117541255831" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/ne_1YwE-1tA/george-walton-academy-champs.html" title="George Walton Academy: Champs!" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/10/george-walton-academy-champs.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-3438769263383896802</id><published>2009-10-27T16:47:00.005-04:00</published><updated>2009-10-30T12:27:44.577-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ripsaw" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">Design Goals for Ripsaw</title><content type="html">In this installment of the &lt;a href="/2009/10/new-article-series-ripsaw.html"&gt;Ripsaw&lt;/a&gt; project series I'll sketch out some of my design goals for the new version of Ripsaw, and the rationale for those goals.&lt;br /&gt;&lt;h3&gt;Split the App Into DLLs&lt;/h3&gt;&lt;br /&gt;The original Ripsaw was a 32-bit Windows application contained in a single executable. This made it easy to carry around on a USB drive and run on machines that I needed to debug. The downsides were that I had to link the C runtime library into the executable, and application was one monolithic entity that couldn't be easily extended.&lt;br /&gt;&lt;br /&gt;For the new Ripsaw I'm going to build it to use the C runtime in a DLL. For most of the machines I work with this will require carrying around the C runtime distributable, but I'm willing to do that as long as I don't have to install anything on the terminal. I'm not completely up to speed with side-by-side assemblies; I prefer to just place the VS 2010 C runtime DLL in the same directory as the executable and run the app, but I'll have to verify that's still supported. (Edit: It is. &lt;em&gt;Duh!&lt;/em&gt;) So far SxS has caused me a lot of grief, but that's probably because I haven't bothered to really understand it.&lt;br /&gt;&lt;h3&gt;Create a Ripsaw API&lt;/h3&gt;&lt;br /&gt;Since I'm splitting out the C runtime, I'm also going to separate most of Ripsaw's non-visual functionality into a separate API DLL. Not only will this make the core functionality more testable and enforce separation of UI, but I'll be able to build more than one user interface around it. I'd like to build a command-line application as well as a graphical application. Sometimes you just can't beat raw text.&lt;br /&gt;&lt;h3&gt;Embrace 64-bit&lt;/h3&gt;&lt;br /&gt;Even though nearly all of my professional development is still 32-bit, I want to build Ripsaw to compile for both 32-bit and 64-bit architectures. I'll need to do this eventually anyway, and this is a good time to start.&lt;br /&gt;&lt;h3&gt;Support Extensibility&lt;/h3&gt;&lt;br /&gt;My original plans for Ripsaw included the ability to create filters for processing log output as it arrived in the application. Perhaps only lines containing certain values would be displayed, or maybe certain words would be shown in a particular color or font. Rather than trying to build every possible behavior into Ripsaw, I'll publish an extensibility interface so that I can add features later on (or &lt;em&gt;you&lt;/em&gt; can add them) without having to change the core API or UI.&lt;br /&gt;&lt;h3&gt;Create a Windows 7 UI&lt;/h3&gt;&lt;br /&gt;The main UI that I'll use will be a 32-bit graphical application targeting Windows XP, but I'd also like to take advantage of some of the new Windows 7 user interface controls such as the ribbon. I'm not inclined to try to serve both interface styles from one application, so after I finish the primary UI I'll create a version that is specific to Windows 7. Since I'm putting most of the non-visual behavior into a separate DLL I'll be free to experiment with different interfaces anyway.&lt;br /&gt;&lt;h3&gt;Coming Up&lt;/h3&gt;&lt;br /&gt;In the next few articles I'll delve into some more development specifics such as language and library choices.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-3438769263383896802?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/J6_RJrj8oL9T1jMWmK0OdSxRcHA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J6_RJrj8oL9T1jMWmK0OdSxRcHA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/J6_RJrj8oL9T1jMWmK0OdSxRcHA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J6_RJrj8oL9T1jMWmK0OdSxRcHA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/LoDQ3LqVkAc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/3438769263383896802/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=3438769263383896802" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/3438769263383896802" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/3438769263383896802" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/LoDQ3LqVkAc/design-goals-for-ripsaw.html" title="Design Goals for Ripsaw" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/10/design-goals-for-ripsaw.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-164137753722816445</id><published>2009-10-26T15:43:00.003-04:00</published><updated>2009-10-26T16:02:33.452-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="visual studio" /><category scheme="http://www.blogger.com/atom/ns#" term="ripsaw" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="utilities" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">A New Article Series: Ripsaw</title><content type="html">Several years ago I wrote a Windows application called "Ripsaw" that implemented the basic functionality of the Unix &lt;a href="http://en.wikipedia.org/wiki/Tail_%28Unix%29"&gt;tail&lt;/a&gt; utility in a graphical application, with a few twists of my own. I had intended to release the application as an open-source project, and although I still use the tool quite a bit I never got around to giving it the necessary polish for a public release. I've only shared it with a few friends and co-workers.&lt;br /&gt;&lt;br /&gt;I've just downloaded Beta 2 of &lt;a href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx"&gt;Microsoft Visual Studio 2010&lt;/a&gt;, and I've decided to create a new version of Ripsaw from the ground up so that I can become familiar with the new IDE and compiler. Besides being a chance to finally get Ripsaw right, this will also be an opportunity to create a series of articles on how I develop a complete application, from the first ideas through design, implementation, testing, and release. I'll walk you through all of the design decisions and trade-offs, the problems I run into along the way, and the development methodologies I use.&lt;br /&gt;&lt;br /&gt;I would really appreciate your feedback, ideas, suggestions, and criticisms. This is going to be fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-164137753722816445?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0yYUWf7rgYkKiyevPe27Z6r-gUY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0yYUWf7rgYkKiyevPe27Z6r-gUY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0yYUWf7rgYkKiyevPe27Z6r-gUY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0yYUWf7rgYkKiyevPe27Z6r-gUY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/e5eyBkI4BXA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/164137753722816445/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=164137753722816445" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/164137753722816445" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/164137753722816445" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/e5eyBkI4BXA/new-article-series-ripsaw.html" title="A New Article Series: Ripsaw" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/10/new-article-series-ripsaw.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-6817876138219527467</id><published>2009-10-23T01:40:00.004-04:00</published><updated>2009-10-23T01:43:54.676-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title type="text">Does Your Company Need a Consultant?</title><content type="html">My current project is coming to an end, and although I'm looking at a couple of new projects to pick up, I thought it might be prudent to update my &lt;a href="/resume.html"&gt;resume&lt;/a&gt;. If my skills look like they might be a match for a need you have in your company, please &lt;a href="mailto:paul@parkscomputing.com"&gt;let me know&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-6817876138219527467?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4AhfsZZPkYz9crzFfIX3nC-cTF0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4AhfsZZPkYz9crzFfIX3nC-cTF0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4AhfsZZPkYz9crzFfIX3nC-cTF0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4AhfsZZPkYz9crzFfIX3nC-cTF0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/-XPYS7CbnYA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/6817876138219527467/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=6817876138219527467" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6817876138219527467" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6817876138219527467" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/-XPYS7CbnYA/does-your-company-need-consultant.html" title="Does Your Company Need a Consultant?" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/10/does-your-company-need-consultant.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-1900636263806118595</id><published>2009-08-04T15:32:00.005-04:00</published><updated>2009-08-04T15:46:37.714-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ui computers software rants" /><title type="text">The Hitchhiker's Guide to UI Design</title><content type="html">&lt;a href="http://blogs.msdn.com/larryosterman/archive/2009/08/03/a-few-of-my-favorite-win7-sound-features-ui-refinements.aspx"&gt;Larry Osterman talked about Windows 7 user interface changes&lt;/a&gt; in a post today, and it generated a minor comment storm, in which I participated. He talked about some buttons that used to be obvious buttons in Windows Vista, but which were made "flat" in Windows 7 so that they're no longer obviously buttons until the user hovers over them with a mouse.&lt;br /&gt;&lt;br /&gt;I &lt;a href="http://blogs.msdn.com/larryosterman/archive/2009/08/03/a-few-of-my-favorite-win7-sound-features-ui-refinements.aspx#9856853"&gt;gave my opinion&lt;/a&gt; a &lt;a href="http://blogs.msdn.com/larryosterman/archive/2009/08/03/a-few-of-my-favorite-win7-sound-features-ui-refinements.aspx#9857328"&gt;couple of times, &lt;/a&gt;coming down on the side of non-flat buttons. The whole discussion, though, reminded me of a couple of passages from &lt;a href="http://www.amazon.com/Hitchhikers-Guide-Galaxy-25th-Anniversary/dp/1400052920/ref=sr_1_1?ie=UTF8&amp;amp;qid=1249414638&amp;amp;sr=8-1"&gt;The Hitchhiker's Guide To the Galaxy&lt;/a&gt; that describe the design of the ship The Heart of Gold.&lt;br /&gt;&lt;blockquote&gt;The cabin was mostly white, oblong, and about the size of a smallish restaurant. In fact it wasn't perfectly oblong: the two long walls were raked round in a slight parallel curve, and all the angles and corners of the cabin were contoured in excitingly chunky shapes. The truth of the matter is that it would have been a great deal simpler and more practical to build the cabin as an ordinary three-dimensional oblong room, but then the designers would have got miserable.&lt;/blockquote&gt;That sounds like everything I dislike about UI design these days, particularly in Flash and Silverlight apps where designers feel compelled to recreate UI widgets that behave almost, but not quite, entirely unlike standard widgets.&lt;br /&gt;&lt;blockquote&gt;A loud clatter of gunk music flooded through the Heart of Gold cabin as Zaphod searched the sub-etha radio wave bands for news of himself. The machine was rather difficult to operate. For years radios had been operated by means of pressing buttons and turning dials; then as the technology became more sophisticated the controls were made touch-sensitive -- you merely had to brush the panels with your fingers; now all you had to do was wave your hand in the general direction of the components and hope. It saved a lot of muscular expenditure, of course, but meant that you had to sit infuriatingly still if you wanted to keep listening to the same program.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;That sounds a lot like where flat buttons are headed. In fact, it sounds strikingly like an iPod.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-1900636263806118595?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7s04A0sTOhBXT9WKpp7Wv2IoULo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7s04A0sTOhBXT9WKpp7Wv2IoULo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7s04A0sTOhBXT9WKpp7Wv2IoULo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7s04A0sTOhBXT9WKpp7Wv2IoULo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/AVjD7A6-JiE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/1900636263806118595/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=1900636263806118595" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/1900636263806118595" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/1900636263806118595" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/AVjD7A6-JiE/hitchhikers-guide-to-ui-design.html" title="The Hitchhiker's Guide to UI Design" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/08/hitchhikers-guide-to-ui-design.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-6312395930694399864</id><published>2009-08-04T14:38:00.002-04:00</published><updated>2009-08-04T14:44:21.448-04:00</updated><title type="text">Diablog?</title><content type="html">I can't stand all the silly neologisms floating around the "blogosphere" (ugh) these days, like "webinar," "vlog," and all the silly tripe like that. But earlier today, I traded blog comments (I can't even stand &lt;em&gt;that&lt;/em&gt; word) with &lt;a href="http://blogs.msdn.com/larryosterman/"&gt;Larry Osterman&lt;/a&gt;, and it occurred to me that we were having a "diablog."&lt;br /&gt;&lt;br /&gt;Ugh. Ugh. Ugh. It's a contagious disease.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-6312395930694399864?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ejBwzRNjAm8v9tuBgLEyYB5UZKc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ejBwzRNjAm8v9tuBgLEyYB5UZKc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ejBwzRNjAm8v9tuBgLEyYB5UZKc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ejBwzRNjAm8v9tuBgLEyYB5UZKc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/f7jO3ipNwWs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/6312395930694399864/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=6312395930694399864" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6312395930694399864" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6312395930694399864" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/f7jO3ipNwWs/diablog.html" title="Diablog?" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/08/diablog.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-245392226592590978</id><published>2009-05-08T10:36:00.010-04:00</published><updated>2009-05-08T13:59:39.421-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">An API is Forever</title><content type="html">An &lt;a href="http://en.wikipedia.org/wiki/API"&gt;API&lt;/a&gt; is an &lt;a href="http://en.wikipedia.org/wiki/Interface_(computer_science)"&gt;interface&lt;/a&gt;. Those of you that have worked with &lt;a href="http://en.wikipedia.org/wiki/Component_Object_Model"&gt;COM&lt;/a&gt; already know that &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2005/11/01/487658.aspx"&gt;once an interface is published, it can never, ever change&lt;/a&gt;. Ever. Not until the end of time. The reason is that some bit of code somewhere is going to be using that interface, and if you change it you've just broken that code. Of course, not changing an interface also means not deleting a portion of it.&lt;br /&gt;&lt;br /&gt;At my job I have worked on, and currently maintain, a few APIs implemented in Windows &lt;a href="http://en.wikipedia.org/wiki/Dynamic-link_library"&gt;DLLs&lt;/a&gt;, some of which have been around for a long time. I had to rewrite significant portions of the internal implementation of one particular DLL in order to add some new features, fix several bugs, and improve the overall performance of the DLL. The old API exposed from the DLL wasn't able to take advantage of the new features, and it wasn't designed all that well to begin with. Since nearly all of the use of that API was through a C++ template wrapper implemented a header, I just added a new set of API functions and changed the wrapper to use the new API.&lt;br /&gt;&lt;br /&gt;I did some digging around in the code base (it's a huge code base) to see what else was using the class wrapper around the DLL, and I found out that the component was in far more widespread use than I had anticipated. There were components in all corners of the code base using it now.&lt;br /&gt;&lt;br /&gt;The component was still desperately in need of a new API, so what I did was write a new one and forward the old API to the new API. I changed the header file that declared the API functions to look like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;FICTIONAL_API void NaDoStuff(&lt;br /&gt;   HANDLE hFict,&lt;br /&gt;   DWORD flags, &lt;br /&gt;   LPCSTR name,&lt;br /&gt;   LPCVOID bytes, &lt;br /&gt;   DWORD byteCount,&lt;br /&gt;   LPCSTR desc);&lt;br /&gt;&lt;br /&gt;// The rest of the new API was declared here...&lt;br /&gt;// ...&lt;br /&gt;// ...&lt;br /&gt;&lt;br /&gt;/************************************************************************&lt;br /&gt;Old, deprecated API. This API is still supported, but calls to all of &lt;br /&gt;these functions are now forwarded to the new API described above. &lt;br /&gt;Please use only the new API in new code.&lt;br /&gt;************************************************************************/&lt;br /&gt;&lt;br /&gt;/* DEPRECATED: Use NaDoStuff instead. */&lt;br /&gt;FICTIONAL_API BOOL OaDoStuff(&lt;br /&gt;   HANDLE hFict,&lt;br /&gt;   DWORD flags, &lt;br /&gt;   LPCSTR desc,&lt;br /&gt;   LPCVOID bytes, &lt;br /&gt;   DWORD byteCount);&lt;br /&gt;&lt;br /&gt;// The rest of the old API was declared here...&lt;br /&gt;// ...&lt;br /&gt;// ...&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;I hoped that the comments would make clear that the use of the old API is discouraged, and that any clients should move to the new API. Likewise, in the implementation, I forwarded the old API functions to the new API functions:&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;FICTIONAL_API void NaDoStuff(&lt;br /&gt;   HANDLE hFict,&lt;br /&gt;   DWORD flags, &lt;br /&gt;   LPCSTR name,&lt;br /&gt;   LPCVOID bytes, &lt;br /&gt;   DWORD byteCount,&lt;br /&gt;   LPCSTR desc)&lt;br /&gt;{&lt;br /&gt;   // Go do stuff&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Elsewhere in the code..&lt;br /&gt;&lt;br /&gt;FICTIONAL_API BOOL OaDoStuff(&lt;br /&gt;   HANDLE hFict,&lt;br /&gt;   DWORD flags, &lt;br /&gt;   LPCSTR desc,&lt;br /&gt;   LPCVOID bytes, &lt;br /&gt;   DWORD byteCount)&lt;br /&gt;{&lt;br /&gt;   NaDoStuff(hFict, flags, "", bytes, byteCount, desc);&lt;br /&gt;   return TRUE;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In some cases, forwarding the old API to the new API meant that I had to make the new API implement the semantics of the old API whenever it was being called through the old API functions. For example, the old API had a nasty habit of writing sub-keys all over the company's registry key under HKLM\SOFTWARE. I made the new API put these settings into a tidy sub-key that belonged to the API, like HKLM\SOFTWARE\ComanyName\Fictional. It would even hunt down the all of the old keys created by the old API and move them into the new sub-key. In a later story I'll explain why I had to preserve that behavior in the old API, but for now just remember that I did.&lt;br /&gt;&lt;br /&gt;Recently, a co-worker changed a customer-specific branch of the archive so that it would point to the newest implementation of this component. He was writing an application using some libraries that called this component's API. He asked me to help with at a problem he was having, and when I went to look in the registry at some of the settings the API had written, I was dismayed to find that the settings were in the old location, all over the root of the company's HKLM\SOFTWARE key. At first, I thought that he was still somehow using the old DLL, but when I checked the version information on the DLL it was, indeed, the new one. How could this be?&lt;br /&gt;&lt;br /&gt;As I mentioned above, most clients use this DLL through a C++ wrapper, since most of the archive is now C++. Only a handful of older C modules call this API directly. The wrapper is a C++ template class, which means it is implemented in a header file. This customer archive was still pointing at the old version the header that called the old API. As I mentioned above, the new API preserves the semantics of the old API &lt;span style="font-style:italic;"&gt;when it is called through the old API&lt;/span&gt;, and that's what we were seeing here.&lt;br /&gt;&lt;br /&gt;My first suggestion, without really thinking about it, was to change the archive to point at the newer header. My co-worker pointed out that this would mean rebuilding &lt;span style="font-weight:bold;"&gt;all&lt;/span&gt; of the components in the archive that used the header, not just the one he was working on.&lt;br /&gt;&lt;br /&gt;We left it alone, and everything is working as it should be. At some point in the future we'll move all of the other components up to the newer version of the wrapper, and they'll start seeing the behavior associated with the new API. In the meantime, the customer still benefit from a less buggy and more efficient component.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-245392226592590978?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2OFvx9f7HeXked34wEMZqV-epTQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2OFvx9f7HeXked34wEMZqV-epTQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2OFvx9f7HeXked34wEMZqV-epTQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2OFvx9f7HeXked34wEMZqV-epTQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/-DvVB6dTUGc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/245392226592590978/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=245392226592590978" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/245392226592590978" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/245392226592590978" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/-DvVB6dTUGc/api-is-forever.html" title="An API is Forever" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/05/api-is-forever.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-3308824496674812605</id><published>2009-05-06T15:46:00.004-04:00</published><updated>2009-05-06T16:10:37.773-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="hardware" /><category scheme="http://www.blogger.com/atom/ns#" term="rants" /><title type="text">Useless Gadget Features</title><content type="html">I guess I would never make it as the CEO of some electronic gadget company, because I would never dream of loading down every gadget with a web browser and a picture viewer. I love my Nintendo Wii; I've spent hours playing Mario Kart or bowling with the kids. I even got Wii Fit, though I use the Balance Board more for Shaun White Snowboarding (and get a better workout doing it). But I've never looked at pictures on my Wii. I've only browsed the web just to see what it looks like, and whether a couple of my sites were readable (not very).&lt;br /&gt;&lt;br /&gt;So, I'm dying to know why gadget companies feel that it's necessary to load down every product with useless stuff like this? If a professional geek like me doesn't even bother to use these features, then who is using them?&lt;br /&gt;&lt;br /&gt;I'd much rather see gadget makes spend some time and resources on the core functionality of their gadgets (do you hear me, phone people?) than on browsing, social networking, or photo viewing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-3308824496674812605?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6WKVEPRxJuEpsc5G7upJPFcMoAg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6WKVEPRxJuEpsc5G7upJPFcMoAg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6WKVEPRxJuEpsc5G7upJPFcMoAg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6WKVEPRxJuEpsc5G7upJPFcMoAg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/soLGXl6jU4g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/3308824496674812605/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=3308824496674812605" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/3308824496674812605" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/3308824496674812605" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/soLGXl6jU4g/useless-gadget-features.html" title="Useless Gadget Features" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/05/useless-gadget-features.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-6279942747859427467</id><published>2009-04-27T08:14:00.029-04:00</published><updated>2009-05-02T11:51:32.219-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><category scheme="http://www.blogger.com/atom/ns#" term="site" /><title type="text">Looking for Havanafolks.com?</title><content type="html">&lt;a class="img-shadow" style="float: right;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.havanafolks.com/phil/photos/50th/family/photo21.jpg"&gt;&lt;img src="http://www.parkscomputing.com/uploaded_images/tresmonos_sm-766574.jpg" alt="" border="0" /&gt;&lt;/a&gt;The site &lt;a href="http://www.havanafolks.com/"&gt;www.havanafolks.com&lt;/a&gt; should be working fine now. If you still can't get there, please &lt;a href="mailto:paul@smartsam.com?subject=Havanafolks"&gt;let me know&lt;/a&gt;. I apologize for messing up the redirect yesterday. I share web space with my brother &lt;a href="http://www.havanafolks.com/phil/"&gt;Phil&lt;/a&gt;, and yesterday when I was converting to Blogger I messed up the redirect that forwards his traffic to his folder. He actually gets a lot more hits than I do, so I feel pretty bad. Sorry, bro!&lt;br /&gt;&lt;br /&gt;By the way, the picture is of me and my brothers, Phil and Steve. It was taken at my parent's 50th wedding anniversary / family reunion a couple of years ago, and I think it probably says all I need to say.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-6279942747859427467?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Uqkscdphi7nRlGfUQaln9A8WpHc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Uqkscdphi7nRlGfUQaln9A8WpHc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Uqkscdphi7nRlGfUQaln9A8WpHc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Uqkscdphi7nRlGfUQaln9A8WpHc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/yB_Ppomhij0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/6279942747859427467/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=6279942747859427467" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6279942747859427467" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6279942747859427467" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/yB_Ppomhij0/looking-for-havanafolkscom.html" title="Looking for Havanafolks.com?" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/04/looking-for-havanafolkscom.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-5128102543119381453</id><published>2009-04-26T16:23:00.008-04:00</published><updated>2009-04-26T21:35:58.378-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><category scheme="http://www.blogger.com/atom/ns#" term="guitar" /><title type="text">Guitar Videos</title><content type="html">I've uploaded some videos of me playing the guitar to my &lt;a href="http://www.youtube.com/profile?user=paulmooreparks&amp;view=videos"&gt;YouTube site&lt;/a&gt;. Go take a look and let me know what you think. &lt;br /&gt;&lt;br /&gt;I've got a lot more stuff that I plan to upload, such as a step-by-step instructional video series on how to play &lt;a href="http://www.youtube.com/watch?v=78hN5nrhAng"&gt;&lt;em&gt;Spanish Fly&lt;/em&gt;&lt;/a&gt;, which is so far the second most-difficult piece I've ever learned. The most difficult, by far, is Paganini's &lt;em&gt;Caprice No. 24&lt;/em&gt;. I'm still trying to polish that one before I post it.&lt;br /&gt;&lt;br /&gt;Here's a sample:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/78hN5nrhAng&amp;hl=en&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/78hN5nrhAng&amp;hl=en&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-5128102543119381453?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9R2Ma2xpCK4Ecqu1k8CPwd8OnMY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9R2Ma2xpCK4Ecqu1k8CPwd8OnMY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9R2Ma2xpCK4Ecqu1k8CPwd8OnMY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9R2Ma2xpCK4Ecqu1k8CPwd8OnMY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/jIYnke_5pLc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/5128102543119381453/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=5128102543119381453" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/5128102543119381453" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/5128102543119381453" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/jIYnke_5pLc/guitar-videos.html" title="Guitar Videos" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/04/guitar-videos.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-7842171646952396770</id><published>2009-04-26T14:32:00.004-04:00</published><updated>2009-04-26T16:59:23.216-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><category scheme="http://www.blogger.com/atom/ns#" term="site" /><title type="text">Updating More Often</title><content type="html">I wired my site up to &lt;a href="http://www.blogger.com/"&gt;Blogger&lt;/a&gt; so now I won't have any excuse for not updating my site more often. Maybe now I'll drop a new entry in every few days, or perhaps even start writing regular articles.&lt;br /&gt;&lt;br /&gt;There's still a lot of content linked from my top menu that's old and out of date. I will probably start moving a lot of that to archive eventually and replace it with more up-to-date content.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-7842171646952396770?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JceGGdNvI2M4E1z3doVA0dZLXmQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JceGGdNvI2M4E1z3doVA0dZLXmQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JceGGdNvI2M4E1z3doVA0dZLXmQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JceGGdNvI2M4E1z3doVA0dZLXmQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/w323mvzs4qY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/7842171646952396770/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=7842171646952396770" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/7842171646952396770" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/7842171646952396770" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/w323mvzs4qY/updating-more-often.html" title="Updating More Often" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/04/updating-more-often.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-7393014712314608459</id><published>2009-04-15T12:52:00.003-04:00</published><updated>2009-04-26T19:36:29.590-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">Pre-emptive Snarkiness</title><content type="html">It's all about the sense of humor, people. First of all, read the "pre-emptive snarky comment" that I wrote in the  &lt;a href="/2009/04/windows-drag-sensitivity-utility.html"&gt;earlier entry&lt;/a&gt; about the &lt;em&gt;dragsens&lt;/em&gt; utility. It's pretty clear that, first of all, I'm tipping my hat to Raymond Chen by even adding a pre-emptive snarky comment. Second, it should also be clear that I'm mentioning the size only because I'm trying to head off any snarky comments about it. Alas, that just doesn't stop some people.&lt;br /&gt;&lt;br /&gt;In my &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2009/04/10/9541813.aspx#9543899"&gt;first comment to Raymond's article&lt;/a&gt;  I mentioned that it took me only eleven minutes to write the utility. That was the entire point of the exercise, really.  If the utility happens to be useful as well, that's fantastic. In fact, the reason that I bothered to take an extra 30 seconds  and link in the C runtime was to make it easier to use. Just copy it to your favorite USB drive, and off you go.  If you don't have 84KB free on your drive for the &lt;a href="dragsens.zip"&gt;ZIP file&lt;/a&gt;, then that's still okay. You can download the  &lt;a href="/code/dragsens_src.zip"&gt;source and VS project&lt;/a&gt; and build it any way you like. Not a problem.&lt;br /&gt;&lt;br /&gt;So, despite the fact that I &lt;strong&gt;clearly stated&lt;/strong&gt; that I was aware that I could make the utility very tiny if I wanted to take  the time to do so (when I said, "Of course you could. So could I."), someone still didn't get it. I guess  &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2009/04/10/9541813.aspx#9547397"&gt;quoting me out of context&lt;/a&gt;,  or perhaps even &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2009/04/10/9541813.aspx#9550342"&gt;putting words in my mouth&lt;/a&gt;, is more fun.&lt;br /&gt;&lt;br /&gt;If I wanted to make it smaller, perhaps I could dispense with the CRT altogether. Perhaps I could write it in assembly language. Who knows. &lt;em&gt;It doesn't matter.&lt;/em&gt; I just wasn't inclined to take any more time gold-plating what I regarded as a very simple exercise. The utility does what it is supposed to do, with a very tiny investment in programming time. That's all I was out to prove. I made the source freely available, with no strings, in case anyone wanted to tweak it to handle some situation that I didn't think about, or perhaps wanted a different implementation (like setting the width and height separately).&lt;br /&gt;&lt;br /&gt;As Raymond might say, I can't believe I had to write that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-7393014712314608459?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/emanTUZ-bQe5mQwHNhglwpH-Y48/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/emanTUZ-bQe5mQwHNhglwpH-Y48/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/emanTUZ-bQe5mQwHNhglwpH-Y48/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/emanTUZ-bQe5mQwHNhglwpH-Y48/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/wD-9ybm_WeQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/7393014712314608459/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=7393014712314608459" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/7393014712314608459" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/7393014712314608459" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/wD-9ybm_WeQ/pre-emptive-snarkiness.html" title="Pre-emptive Snarkiness" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/04/pre-emptive-snarkiness.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-7248703255540120453</id><published>2009-04-10T11:10:00.013-04:00</published><updated>2009-10-27T15:03:02.591-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="utilities" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">Windows Drag Sensitivity Utility</title><content type="html">Inspired by an article by Raymond Chen about  &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2009/04/10/9541813.aspx"&gt;how to correctly change the Windows mouse drag sensitivity&lt;/a&gt;, I wrote a quick &lt;a href="http://www.parkscomputing.com/dragsens.zip"&gt;utility called &lt;em&gt;dragsens&lt;/em&gt;&lt;/a&gt;. It's a small command-line utility that will allow you to change the number of pixels the mouse has to travel before a drag operation is initiated. Just download and unzip the utility, then run it at the command line, supplying a single parameter that is the number of pixels for the mouse to travel.&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://blogs.msdn.com/oldnewthing/"&gt;Raymond's&lt;/a&gt; honor, I'll provide my own &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2008/01/30/7315957.aspx"&gt;pre-emptive snarky comment&lt;/a&gt;:  "That executable is 164KB! I could write that in only 4KB!"&lt;br /&gt;&lt;br /&gt;Of course you could. So could I. I linked in the C runtime library so you wouldn't have to install the Visual Studio 2008 distributable package just to run a simple command-line utility. I don't normally do that with typical desktop applications, but for small utilities like this is saves a lot of trouble.&lt;br /&gt;&lt;br /&gt;If you'd like modify the utility, or examine its source, you may &lt;a href="http://www.parkscomputing.com/code/dragsens_src.zip"&gt;download the Visual Studio 2008 project&lt;/a&gt;. If you just want the utility itself, you may &lt;a href="http://www.parkscomputing.com/dragsens.zip"&gt;download a ZIP of the executable&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="fullpost"&gt;&lt;h2 id="about"&gt;About the Utility&lt;/h2&gt;The utility is actually very simple. It accepts a single parameter, which is the number of pixels the mouse must travel with a button depressed before the motion registers as a drag action. Rather than separate out the width and height, I just set both to the same number since this is generally all that's necessary.&lt;br /&gt;&lt;br /&gt;&lt;div class="example"&gt;&lt;pre&gt;BOOL success = FALSE;&lt;br /&gt;&lt;br /&gt;success = SystemParametersInfo(SPI_SETDRAGWIDTH, numPixels, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);&lt;br /&gt;&lt;br /&gt;if (!success)&lt;br /&gt;{&lt;br /&gt;  DWORD error = GetLastError();&lt;br /&gt;  std::wcout &amp;lt;&amp;lt; L"Error " &amp;lt;&amp;lt; std::hex &amp;lt;&amp;lt; error &amp;lt;&amp;lt; std::dec &amp;lt;&amp;lt; " while setting drag width." &amp;lt;&amp;lt; std::endl;&lt;br /&gt;  return 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;success = SystemParametersInfo(SPI_SETDRAGHEIGHT, numPixels, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);&lt;br /&gt;&lt;br /&gt;if (!success)&lt;br /&gt;{&lt;br /&gt;  DWORD error = GetLastError();&lt;br /&gt;  std::wcout &amp;lt;&amp;lt; L"Error " &amp;lt;&amp;lt; std::hex &amp;lt;&amp;lt; error &amp;lt;&amp;lt; std::dec &amp;lt;&amp;lt; " while setting drag height." &amp;lt;&amp;lt; std::endl;&lt;br /&gt;  return 1;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It would be fairly simple to modify the application to set the width and height independently, if you so desired.&lt;br /&gt;&lt;br /&gt;&lt;h2 id="update"&gt;Update&lt;/h2&gt;I'm already at version 1.1. I decided to add a version resource and support for a "/?" parameter.&lt;br /&gt;&lt;br /&gt;&lt;h2 id="snarky"&gt;About the Snarky Comments&lt;/h2&gt;Please see the entry entitled &lt;a href="http://www.parkscomputing.com/2009/04/pre-emptive-snarkiness.html"&gt;Pre-emptive Snarkiness&lt;/a&gt; for my response to the comments about my utility that were posted on Raymond's blog.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-7248703255540120453?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MdlWSsahCGiH1dOOnx8EPJpYFpI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MdlWSsahCGiH1dOOnx8EPJpYFpI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MdlWSsahCGiH1dOOnx8EPJpYFpI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MdlWSsahCGiH1dOOnx8EPJpYFpI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/tGjw1qnBcx4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/7248703255540120453/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=7248703255540120453" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/7248703255540120453" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/7248703255540120453" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/tGjw1qnBcx4/windows-drag-sensitivity-utility.html" title="Windows Drag Sensitivity Utility" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/04/windows-drag-sensitivity-utility.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-8256279518480073701</id><published>2007-06-07T13:15:00.002-04:00</published><updated>2009-04-26T14:59:56.128-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="wiki" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">A New, New Wiki</title><content type="html">I've replaced the old Wiki with a &lt;a href="http://www.parkscomputing.com/cppwiki/"&gt;new Wiki&lt;/a&gt; based on the &lt;a href="http://www.mediawiki.org/wiki/"&gt;Mediawiki engine&lt;/a&gt;.  This is now the official Wiki for the Undernet IRC channels #c++ and #c++/cli. It's still in the beginning stages, so feel free  to create an account and start adding articles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-8256279518480073701?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-NztJUjyGoPpCvmXV4U9OTxLhvo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-NztJUjyGoPpCvmXV4U9OTxLhvo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-NztJUjyGoPpCvmXV4U9OTxLhvo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-NztJUjyGoPpCvmXV4U9OTxLhvo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/dxiwiDRu9C4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/8256279518480073701/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=8256279518480073701" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/8256279518480073701" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/8256279518480073701" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/dxiwiDRu9C4/new-new-wiki.html" title="A New, New Wiki" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2007/06/new-new-wiki.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-2596493897603098290</id><published>2006-05-18T12:54:00.002-04:00</published><updated>2009-04-26T15:00:43.852-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="barcodes" /><title type="text">Barcode Generator</title><content type="html">More fun with one of my favorite languages: A &lt;a href="http://www.parkscomputing.com/barcode.html"&gt;barcode generator&lt;/a&gt; written in JavaScript that will  create an &lt;a href="http://www.barcodeisland.com/ean13.phtml"&gt;EAN-13 barcode&lt;/a&gt;. The page is completely self-contained and  uses no graphics or server-side code.&lt;br /&gt;&lt;br /&gt;I've only tested the page in Internet Explorer 6, Internet Explorer 7 beta, and Firefox 1.5. I'm not going to target  older browsers, but I am interested in hearing about problems in current browsers other than those mentioned above.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-2596493897603098290?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bQ55ajbAc7Ad2IskYdckphk7A0s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bQ55ajbAc7Ad2IskYdckphk7A0s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bQ55ajbAc7Ad2IskYdckphk7A0s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bQ55ajbAc7Ad2IskYdckphk7A0s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/eONwMxPjgvg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/2596493897603098290/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=2596493897603098290" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/2596493897603098290" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/2596493897603098290" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/eONwMxPjgvg/barcode-generator.html" title="Barcode Generator" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2006/05/barcode-generator.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-2591457470325294862</id><published>2005-02-23T12:55:00.004-05:00</published><updated>2009-04-26T15:01:47.753-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Lisp" /><title type="text">Lisp Interpreter in JavaScript</title><content type="html">Lisp is becoming a theme here, apparently. I suppose I've read so many &lt;a href="http://www.paulgraham.com/paulgraham/articles.html"&gt;Paul Graham&lt;/a&gt;  essays that I'm becoming a fan of the language. In order to become more familiar with it, I decided to write a  &lt;a href="http://www.parkscomputing.com/lisptest.html"&gt;Lisp interpreter in JavaScript&lt;/a&gt;. It's not quite complete, and the semantics are definitely not  entirely correct, but it's at least usable. The page is even partially scripted in Lisp, and as I debug the interpreter and add  more to it (such as loop constructs) I'll convert more (and eventually all) of the JavaScript to Lisp. Once you  &lt;a href="http://www.parkscomputing.com/lisptest.html"&gt;browse to the page&lt;/a&gt;, view the source and scroll down until you see a &lt;code&gt;&amp;lt;script type="text/lisp"&amp;gt;&lt;/code&gt; block.&lt;br /&gt;&lt;br /&gt;I have only tested the interpreter in Firefox and Internet Explorer 6, so I'd &lt;a href="mailto:paul@parkscomputing.com?subject=Lisp"&gt;like to know&lt;/a&gt; how it works in  other browsers. If you want to look over the interpreter code, &lt;a href="http://www.parkscomputing.com/js/lisp.js"&gt;download it&lt;/a&gt; and play around with it. If you make any additions, changes, or corrections, I'd love to &lt;a href="mailto:paul@parkscomputing.com?subject=Lisp"&gt;hear about them&lt;/a&gt;  so I can incorporate them into the code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-2591457470325294862?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WRiTBxtlwqhog9slEp2XD_ghn2E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WRiTBxtlwqhog9slEp2XD_ghn2E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WRiTBxtlwqhog9slEp2XD_ghn2E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WRiTBxtlwqhog9slEp2XD_ghn2E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/MTc_yw_-AA0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/2591457470325294862/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=2591457470325294862" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/2591457470325294862" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/2591457470325294862" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/MTc_yw_-AA0/lisp-interpreter-in-javascript.html" title="Lisp Interpreter in JavaScript" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2005/02/lisp-interpreter-in-javascript.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-6534783715323479347</id><published>2004-12-16T13:16:00.002-05:00</published><updated>2009-04-26T15:02:19.026-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">Lisp for C++ Templates</title><content type="html">I'm not working quite as many hours as I was earlier in the year, so I'm able to concentrate on more long-term projects of my own in addition to my regular work responsibilities. Before I get back to the &lt;a href="http://www.parkscomputing.com/acpp/"&gt;Accelerated C++ Solutions&lt;/a&gt; I'm going to play around a little bit with extreme template meta-programming in C++. Toward this end, I am implementing Lisp primitives with C++ templates for manipulating typelists. So far &lt;a href="http://www.parkscomputing.com/tlp/"&gt;I only have the primitives online&lt;/a&gt;, but I'll hopefully have some examples of their usage up soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-6534783715323479347?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TSBJIoVgp49y5p2Mc1tVeb74_rY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TSBJIoVgp49y5p2Mc1tVeb74_rY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TSBJIoVgp49y5p2Mc1tVeb74_rY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TSBJIoVgp49y5p2Mc1tVeb74_rY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/ARTlPqCL9ag" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/6534783715323479347/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=6534783715323479347" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6534783715323479347" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6534783715323479347" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/ARTlPqCL9ag/lisp-for-c-templates.html" title="Lisp for C++ Templates" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2009/04/lisp-for-c-templates.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-6410821832057498532</id><published>2004-07-14T13:24:00.003-04:00</published><updated>2009-04-26T15:30:16.429-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="compilers" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="pbrain" /><title type="text">The pbrain Programming Language</title><content type="html">I've been working &lt;em&gt;really&lt;/em&gt; hard lately - 70 or more hours a week. Consequently, I haven't had many opportunities for diversion. After staring at the same application all day, every day, though, it's important to step away and give my brain another puzzle to solve now and then. One such late-night/early-morning excursion produced &lt;a href="http://www.parkscomputing.com/code/pbrain/"&gt;The pbrain Programming Language&lt;/a&gt;. This language is an extension of  an extremely tiny Turing-complete language called &lt;a href="http://home.planet.nl/%7Efaase009/Ha_BF.html"&gt;Brainf**k&lt;/a&gt;  (yes, the name contains a really, really bad word).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update: A pbrain Compiler for .NET&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since I was halfway home with the interpreter, I decided to go ahead and write &lt;a href="http://www.parkscomputing.com/code/pbrain/"&gt;a compiler&lt;/a&gt; for .NET platforms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-6410821832057498532?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WxztXdMhsYuh1HD9TYYtWcRv4fc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WxztXdMhsYuh1HD9TYYtWcRv4fc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WxztXdMhsYuh1HD9TYYtWcRv4fc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WxztXdMhsYuh1HD9TYYtWcRv4fc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/MFax8vi0EYk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/6410821832057498532/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=6410821832057498532" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6410821832057498532" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6410821832057498532" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/MFax8vi0EYk/pbrain-programming-language.html" title="The pbrain Programming Language" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2004/07/pbrain-programming-language.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-6662495266856946241</id><published>2004-03-09T13:30:00.001-05:00</published><updated>2009-04-26T15:06:48.200-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="HTML" /><title type="text">Updated HTML 4.01 Reference</title><content type="html">I have updated the &lt;a href="http://www.parkscomputing.com/html4/"&gt;index&lt;/a&gt; for the  &lt;a href="http://www.w3.org/TR/html4/" target="_blank"&gt;HTML 4.01 Reference&lt;/a&gt;. Each element now has a collapsible list of  attributes beneath it. I was more than a little bleary eyed when I finally finished, so please  &lt;a href="mailto:paul@parkscomputing.com?subject=HTML4%20Reference"&gt;let me know&lt;/a&gt; if you find any mistakes.  There's a lot more that I want to add to this index, such as a list of  attributes and different categorizations of elements, but this will do for now.&lt;br /&gt;&lt;br /&gt;The index was inspired by Eric Meyer's  &lt;a href="http://www.meyerweb.com/eric/css/references/css2ref.html" target="_blank"&gt;indexed CSS2 Reference&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-6662495266856946241?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/s5iUZ-rq9xIyMJS7F4R72cLUNug/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s5iUZ-rq9xIyMJS7F4R72cLUNug/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/s5iUZ-rq9xIyMJS7F4R72cLUNug/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s5iUZ-rq9xIyMJS7F4R72cLUNug/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/spXuyl40_mA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/6662495266856946241/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=6662495266856946241" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6662495266856946241" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/6662495266856946241" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/spXuyl40_mA/updated-html-401-reference.html" title="Updated HTML 4.01 Reference" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2004/03/updated-html-401-reference.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-3494561886543948757</id><published>2003-12-03T13:32:00.005-05:00</published><updated>2009-04-26T15:08:25.574-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="games" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title type="text">Updated MMP Mancala</title><content type="html">I've received a few complaints from people who downloaded my &lt;a href="http://www.parkscomputing.com/code/mancala"&gt;Mancala&lt;/a&gt; game, telling me that certain DLLs were missing. I've rebuilt the game and repackaged the &lt;a href="http://www.parkscomputing.com/code/mancala/mancinst.exe"&gt;installation file&lt;/a&gt; to include all necessary files. I apologize for this oversight.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-3494561886543948757?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/eYurg6vxylAQN0PKn5BD6uZtpR0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eYurg6vxylAQN0PKn5BD6uZtpR0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/eYurg6vxylAQN0PKn5BD6uZtpR0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eYurg6vxylAQN0PKn5BD6uZtpR0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/UivoUT_RNtQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/3494561886543948757/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=3494561886543948757" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/3494561886543948757" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/3494561886543948757" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/UivoUT_RNtQ/updated-mmp-mancala.html" title="Updated MMP Mancala" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2003/12/updated-mmp-mancala.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-1075239168116244239</id><published>2003-12-03T13:32:00.004-05:00</published><updated>2009-04-26T15:07:44.865-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Accelerated C++" /><title type="text">More on Accelerated C++ Solutions</title><content type="html">For those of you that have been kind enough to write with regard to the &lt;a href="http://www.parkscomputing.com/acpp/default.aspx"&gt;Accelerated C++ Solutions page&lt;/a&gt;, I haven't forgotten you. I will be updating the site with new chapters Real Soon Now. If you have any suggestions on how to improve the solutions site, please &lt;a href="mailto:paul@parkscomputing.com?subject=Feedback"&gt;let me know&lt;/a&gt;&lt;span class="printonly"&gt; [paul@parkscomputing.com] &lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-1075239168116244239?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Cbvho2Xvzie_c4ezvbs8vFvT4bI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Cbvho2Xvzie_c4ezvbs8vFvT4bI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Cbvho2Xvzie_c4ezvbs8vFvT4bI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Cbvho2Xvzie_c4ezvbs8vFvT4bI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/gOnjcqNO5ZE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/1075239168116244239/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=1075239168116244239" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/1075239168116244239" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/1075239168116244239" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/gOnjcqNO5ZE/more-on-accelerated-c-solutions.html" title="More on Accelerated C++ Solutions" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2003/12/more-on-accelerated-c-solutions.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-4328000167354514086.post-7889928357835455438</id><published>2003-09-30T13:34:00.001-04:00</published><updated>2009-04-26T15:09:02.656-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><category scheme="http://www.blogger.com/atom/ns#" term="exercise" /><title type="text">My Workout Routine</title><content type="html">In case you're wondering: No, a buff computer geek is not in the same category as Bigfoot, the Loch Ness Monster, and little green men. I've been on a &lt;a href="http://www.parkscomputing.com/workout.aspx"&gt;bodybuilding program&lt;/a&gt; for the last 5 months, and I look and feel better than I ever have.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Update: I've resumed working out after a layoff, and my new information is at &lt;a href="http://www.parkscomputing.com/cppwiki/index.php?title=High_intensity_training"&gt;http://www.parkscomputing.com/cppwiki/index.php?title=High_intensity_training&lt;/a&gt;.&lt;/i&gt;&lt;div class="sectioncontent"&gt;  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4328000167354514086-7889928357835455438?l=www.parkscomputing.com%2Fdefault.aspx'/&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/X5nSmRM3SXwwJk7llLitIft-_bI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/X5nSmRM3SXwwJk7llLitIft-_bI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/X5nSmRM3SXwwJk7llLitIft-_bI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/X5nSmRM3SXwwJk7llLitIft-_bI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ParksComputing/~4/NiKJgqus7P8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/7889928357835455438/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=4328000167354514086&amp;postID=7889928357835455438" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/7889928357835455438" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4328000167354514086/posts/default/7889928357835455438" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ParksComputing/~3/NiKJgqus7P8/my-workout-routine.html" title="My Workout Routine" /><author><name>Paul M. Parks</name><uri>http://www.blogger.com/profile/14475847713043100910</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="17769436791794165599" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.parkscomputing.com/2003/09/my-workout-routine.html</feedburner:origLink></entry></feed>
