<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/wordpress-mu-1.2.3-2.2.1" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Craig Stuntz's Weblog</title>
	<link>http://blogs.teamb.com/craigstuntz</link>
	<description>News of interest to Delphi, .NET, and InterBase developers</description>
	<pubDate>Fri, 04 Jul 2008 15:18:48 +0000</pubDate>
	<generator>http://wordpress.org/?v=wordpress-mu-1.2.3-2.2.1</generator>
	<language>en-US</language>
			<item>
		<title>JAWS, XP Themes, and Accessibility</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/07/03/37823</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/07/03/37823#comments</comments>
		<pubDate>Thu, 03 Jul 2008 21:34:31 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[General Software Development]]></category>

		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/07/03/37823</guid>
		<description><![CDATA[It seems that the popular screen reader (software which translates text on the computer screen into spoken audio for the blind) JAWS has problems with applications produced in Delphi when they are manifested for Windows XP.  I don&#8217;t know if the problem is limited only to Delphi applications, though.  What I do know is that [...]]]></description>
			<content:encoded><![CDATA[<p>It seems that the popular screen reader (software which translates text on the computer screen into spoken audio for the blind) <a href="http://www.freedomscientific.com/products/fs/jaws-product-page.asp">JAWS</a> has problems with applications produced in Delphi when they are manifested for Windows XP.  I don&#8217;t know if the problem is limited only to Delphi applications, though.  What I do know is that we tested the latest version of JAWS with a do-nothing application which simply displays a single, standard, text edit control, and a standard label which specifies the text editor as its FocusControl.  When we produce the application without an XP manifest, JAWS reads the caption correctly when the editor is focused.  When we add an XP manifest, JAWS no longer reads the caption.</p>
<p>So if accessibility for the blind is important for your software, it would probably be a good idea to download the free demo version of JAWS and test your software.  If it doesn&#8217;t work, try making the manifest optional.</p>
<p>One would think that the makers of JAWS would want software producers to test their products with JAWS.  But according to a salesperson for Freedom Scientific, there is no developer program for the tool.  JAWS is moderately expensive — about $900 — but this is not a barrier for us.  What we would really like is to have access to a defect reporting system for JAWS and early access to future versions of the software.</p>
<p><strong>Update:</strong>  Darrell Shandrow, from the <a href="http://blog.blindaccessjournal.com/">Blind Access Journal</a>, <a href="http://blog.blindaccessjournal.com/2008/07/delphi-programmer-says-freedom.html">comments on this post</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37823&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37823" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=JAWS%2C%20XP%20Themes%2C%20and%20Accessibility&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F07%2F03%2F37823" id="akst_email_37823" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/07/03/37823/feed</wfw:commentRss>
		</item>
		<item>
		<title>Visual Studio 2008 Service Pack 1 Beta Installation Fails</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/05/23/37822</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/05/23/37822#comments</comments>
		<pubDate>Fri, 23 May 2008 15:17:31 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[.NET]]></category>

		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/05/23/37822</guid>
		<description><![CDATA[The other day I tried to install the Visual Studio 2008 Service Pack 1 beta. The installer failed. Here's the solution.]]></description>
			<content:encoded><![CDATA[<p>The other day I tried to install the <a href="http://msdn.microsoft.com/en-us/vstudio/products/cc533447.aspx">Visual Studio 2008 Service Pack 1 beta</a>.  The installer failed.</p>
<p>In the installation log, I found:</p>
<blockquote><p>Patch (C:\DOCUME~1\CMS~1.VER\LOCALS~1\Temp\Microsoft Visual Studio 2008 SP1 (Beta)\VS90sp1-KB945140-X86-ENU.msp;C:\DOCUME~1\CMS~1.VER\LOCALS~1\Temp\Microsoft Visual Studio 2008 SP1 (Beta)\VC90sp1-KB947888-x86-enu.msp) install failed on product (Microsoft Visual Studio 2008 Professional Edition - ENU). Msi Log: &lt;Microsoft Visual Studio 2008 SP1 (Beta)_20080521_093532362-MSP0.txt&gt;</p></blockquote>
<p>Opening the linked file, I saw this:</p>
<blockquote><p>DEBUG: Error 2746: Transform RTM.1 invalid for package C:\WINDOWS\Installer\5d5916dc.msi. Expected product {80C06CCD-7D07-3DB6-86CD-B57B3F0614D8}, found product {D7DAD1E4-45F4-3B2B-899A-EA728167EC4F}.</p>
<p>DEBUG: Error 2746: Transform RTM.2 invalid for package C:\WINDOWS\Installer\5d5916dc.msi. Expected product {91C325A6-D5DE-3444-B598-97DF50EE0FAF}, found product {D7DAD1E4-45F4-3B2B-899A-EA728167EC4F}.</p>
<p>DEBUG: Error 2746: Transform RTM.3 invalid for package C:\WINDOWS\Installer\5d5916dc.msi. Expected product {4298C783-524F-3C3E-9B11-36FA64604B2B}, found product {D7DAD1E4-45F4-3B2B-899A-EA728167EC4F}.</p>
<p>DEBUG: Error 2746: Transform RTM.4 invalid for package C:\WINDOWS\Installer\5d5916dc.msi. Expected product {8F10429A-DFF5-3B55-9306-0ADEB337CFD3}, found product {D7DAD1E4-45F4-3B2B-899A-EA728167EC4F}.</p>
<p>DEBUG: Error 2746: Transform RTM.5 invalid for package C:\WINDOWS\Installer\5d5916dc.msi. Expected product {23D0117E-F9A5-364E-A379-70EC2DE02B9F}, found product {D7DAD1E4-45F4-3B2B-899A-EA728167EC4F}.</p>
<p>DEBUG: Error 2746: Transform RTM.6 invalid for package C:\WINDOWS\Installer\5d5916dc.msi. Expected product {F434F50E-7614-3EA8-9008-2FB866B697DA}, found product {D7DAD1E4-45F4-3B2B-899A-EA728167EC4F}.</p>
<p>DEBUG: Error 2746: Transform RTM.7 invalid for package C:\WINDOWS\Installer\5d5916dc.msi. Expected product {BA0C9AAF-1327-3F06-B49C-349B4BE8F740}, found product {D7DAD1E4-45F4-3B2B-899A-EA728167EC4F}.</p></blockquote>
<p><a href="http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx#6211120">A commenter on Scott Guthrie&#8217;s blog</a>, however, gave me a clue which eventually allowed me to figure out a fix.  The installer for the beta cannot deal with hotfixes which have been applied to Visual Studio.  Before running the installer, you need to perform the following steps:</p>
<ol>
<li>Control Panel, Add or Remove Programs</li>
<li>Check "Show Updates"</li>
<li>Scroll to Microsoft Visual Studio 2008</li>
<li>If there are any hotfixes under this entry, click the Remove button for each</li>
</ol>
<p>Now the installer should work.  The Service Pack installer will add the hotfixes back for you.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37822&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37822" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Visual%20Studio%202008%20Service%20Pack%201%20Beta%20Installation%20Fails&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F05%2F23%2F37822" id="akst_email_37822" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/05/23/37822/feed</wfw:commentRss>
		</item>
		<item>
		<title>Embedded User Authentication Error in InterBase 2007</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/05/20/37821</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/05/20/37821#comments</comments>
		<pubDate>Tue, 20 May 2008 14:03:42 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[InterBase]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/05/20/37821</guid>
		<description><![CDATA[This tells me that ALTER DATABASE ADD ADMIN OPTION does not work unless the ODS is the latest version available for the current server version. I wish the error message was better, but at least the problem is easy to fix.]]></description>
			<content:encoded><![CDATA[<p>Yesterday, an InterBase user reported the following error which he received when he tried to add <a href="http://ibdeveloper.com/issues/issue-1-sep-1-2005/embedded-user-authentication-in-interbase-75/">Embedded User Authentication</a> to an existing database in InterBase 2007:</p>
<blockquote><p>In Delphi code, I log in as SYSDBA and open an existing database.  I execute the SQL:</p>
<p><code>ALTER DATABASE ADD ADMIN OPTION</code></p>
<p>The following exception occurs:</p>
<p>ClassName: "EIBInterBaseError"<br />
Error Message:<br />
"unsuccessful metadata update<br />
STORE RDB$USERS failed"</p></blockquote>
<p>This ring a bell with me, so I asked him to confirm that the ODS (On-Disk Structure; essentially, the version number of the database file format) of his database indicated that it actually was an InterBase 2007 database.  InterBase 2007 does not automatically upgrade older databases to the newest file format; you have to backup and restore the database to accomplish this.</p>
<p>He responded:</p>
<blockquote><p>The database had been automatically upgraded from InterBase 7, and reported<br />
via the TIBDatabaseInfo properties that the On Disk Structure (ODS) Version<br />
was 11.2&#8242;.</p>
<p>I backed up and restored the database and the ODS Version was then reported<br />
as 12.0.</p>
<p>With this version of the database, the exception did not occur.</p></blockquote>
<p>This tells me that ALTER DATABASE ADD ADMIN OPTION does not work unless the ODS is the latest version available for the current server version.  I wish the error message was better, but at least the problem is easy to fix.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37821&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37821" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Embedded%20User%20Authentication%20Error%20in%20InterBase%202007&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F05%2F20%2F37821" id="akst_email_37821" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/05/20/37821/feed</wfw:commentRss>
		</item>
		<item>
		<title>InterBase Procedure Dependency-Checking Bug</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/05/20/37820</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/05/20/37820#comments</comments>
		<pubDate>Tue, 20 May 2008 13:37:36 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[InterBase]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/05/20/37820</guid>
		<description><![CDATA[InterBase seems to have a bug in checking dependencies when you alter the arguments to a procedure which is referenced by a trigger.  It's easy to work around, though.]]></description>
			<content:encoded><![CDATA[<p>InterBase seems to have a bug in checking dependencies when you alter the arguments to a procedure which is referenced by a trigger.  It&#8217;s easy to work around, though.</p>
<p>Yesterday, and InterBase user reported on the IB newsgroups that he had tried the following steps:</p>
<ol>
<li>Alter a procedure to change the number of arguments it takes.</li>
<li>Alter a trigger which calls that procedure, so that the trigger source passes the new member of the procedure arguments.</li>
</ol>
<p>Now, if the dependency checking had been working, step 1 would have been impossible, due to the reference to the procedure within the trigger body.  The correct way of doing this process is to first ALTER the trigger source so that it does not reference the procedure, then change the procedure, then change the trigger source to reference the new procedure signature.  But step 1 <em>did </em>work for this user, and when he tried to step 2, he <em>then </em>received the dependency error. The reason he received the error in step 2 is that InterBase was checking the dependencies of the old (compiled) version of the trigger before it compiled the new version.  That doesn&#8217;t seem right; if we&#8217;re replacing the source code of a trigger, why do we care if the old version is legitimate? So there seemed to be at least two bugs here.</p>
<p>If you find yourself in this situation, probably the easiest way to work around the problem is to ALTER the procedure back to its original form, and then update the trigger and procedure in the correct order.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37820&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37820" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=InterBase%20Procedure%20Dependency-Checking%20Bug&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F05%2F20%2F37820" id="akst_email_37820" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/05/20/37820/feed</wfw:commentRss>
		</item>
		<item>
		<title>"Let It Crash" Programming</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/05/19/37819</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/05/19/37819#comments</comments>
		<pubDate>Mon, 19 May 2008 20:28:02 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[Erlang]]></category>

		<category><![CDATA[General Software Development]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/05/19/37819</guid>
		<description><![CDATA[This past weekend I read Joe Armstrong&#8217;s paper on the history of Erlang.  Now, HOPL papers in general are like candy for me, and this one did not disappoint.  There&#8217;s more in this paper that I can cover in one post, so today I&#8217;m going to concentrate on one particular feature of Erlang [...]]]></description>
			<content:encoded><![CDATA[<p>This past weekend I read <a href="http://www.cs.chalmers.se/Cs/Grundutb/Kurser/ppxt/HT2007/general/languages/armstrong-erlang_history.pdf">Joe Armstrong&#8217;s paper on the history of Erlang</a>.  Now, <a href="http://research.ihost.com/hopl/HOPL.html" title="ACM SIGPLAN Conferences on the History of Programming Languages">HOPL</a> papers in general are like candy for me, and this one did not disappoint.  There&#8217;s more in this paper that I can cover in one post, so today I&#8217;m going to concentrate on one particular feature of Erlang highlighted by Armstrong.</p>
<p>Although Erlang is designed to encourage/facilitate a massively parallel programming style, its error handling may be even more noteworthy. Like everything else in Erlang, its error handling is designed to be distributed, and for good reason:</p>
<blockquote><p>Error handling in Erlang is very different from error handling in conventional programming languages. The key observation here is to note that the error-handling mechanisms were designed for building fault-tolerant systems, and not merely for protecting from program exceptions. You cannot build a fault-tolerant system if you only have one computer. The minimal configuration for a fault tolerant system has two computers. These must be configured so that both observe each other. If one of the computers crashes, then the other computer must take over whatever the first computer was doing.</p>
<p>This means that the model for error handling is based on the idea of two computers that observe each other.</p></blockquote>
<p>Erlang is famous for its features which help programmers to produce stable systems in the real world.  Its shared nothing architecture and ability to hot-swap code are well-known.  But these features are available in other systems.  The "links" feature, on the other hand, seems to be unique.  When you create a process in Erlang, you can link it to another process; this link essentially means, "If that process crashes, I&#8217;d like to crash, also; and if I crash, that process should die, too."  Here is Armstrong&#8217;s description:</p>
<blockquote><p>Links in Erlang are provided to control error propagation paths for errors between processes. An Erlang process will die if it evaluates illegal code, so, for example, if a process tries to divide by zero it will die. The basic model of error handling is to assume that some other process in the system will observe the death of the process and take appropriate corrective actions. But which process in the system should do this? If there are several thousand processes in the system then how do we know which process to inform when an error occurs? The answer is the linked process. If some process A evaluates the primitive link(B) then it becomes linked to A . If A dies then B is informed. If B dies then A is informed.</p>
<p>Using links, we can create sets of processes that are linked together. If these are normal processes, they will die immediately if they are linked to a process that dies with an error. The idea here is to create sets of processes such that if any process in the set dies, then they will all die. This mechanism provides the invariant that either all the processes in the set are alive or none of them are. This is very useful for programming error-recovery strategies in complex situations. As far as I know, no other programming language has anything remotely like this.</p></blockquote>
<p>In addition to simply killing the linked process, the link can also function as a kind of signal to a system process that a group of processes have died, so that appropriate action can be taken, such as restarting a process group.</p>
<p>Like Armstrong, I cannot think of another system that works quite this way.  The closest analogy I can think of is a distributed transaction.  But distributed transactions have quite a bit more overhead, because they&#8217;re all about providing serializable access to shared data, which Erlang just doesn&#8217;t allow.</p>
<p>Armstrong says that the idea of links was inspired by the &#8216;C wire&#8217; in early telephone exchanges:</p>
<blockquote><p> The C wire went back to the exchange and through all the electromechanical relays involved in setting up a call. If anything went wrong, or if either partner terminated the call, then the C wire was grounded. Grounding the C wire caused a knock-on effect in the exchange that freed all resources connected to the C line.</p></blockquote>
<p>Armstrong says that the links feature encourages a worker/supervisor style of programming which is "<a href="http://delivery.acm.org/10.1145/1240000/1238850/supp/Erlang.pdf?key1=1238850&amp;key2=4635221121&amp;coll=GUIDE&amp;dl=GUIDE&amp;CFID=61517297&amp;CFTOKEN=84428823" title="Slideshow for Armstrong's HOPL talk">not possible in a single threaded language.</a>"</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37819&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37819" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=%22Let%20It%20Crash%22%20Programming&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F05%2F19%2F37819" id="akst_email_37819" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/05/19/37819/feed</wfw:commentRss>
		</item>
		<item>
		<title>Covariant and Contravariant Subtyping In the .NET 2.0 CLR</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/05/14/37818</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/05/14/37818#comments</comments>
		<pubDate>Wed, 14 May 2008 20:54:08 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[General Software Development]]></category>

		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/05/14/37818</guid>
		<description><![CDATA[Danny Thorpe used to say that he was very much interested in things that the .NET CLR did which C# did not support. Examples include unmanaged Win32 exports and exception filters. One thing which had previously escaped my notice is covariant and contravariant subtyping of generic types, which was apparently introduced along with generics in [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dannythorpe.com/">Danny Thorpe</a> used to say that he was very much interested in things that the .NET CLR did which C# did not support. Examples include unmanaged Win32 exports and exception filters. One thing which had previously escaped my notice is <a href="http://research.microsoft.com/~akenn/generics/FOOL2007.pdf" title="On Decidability of Nominal Subtyping with Variance">covariant and contravariant subtyping of generic types</a>, which was apparently introduced along with generics in the 2.0 CLR. C# does not presently have a syntax for this, although <a href="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx" title="Eric Lippert's posts on covariance and contravariance">the team is talking about it</a>. Of course, some would question whether adding such support is such a good idea.  Steve Yegge proposes that <a href="http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html" title="Dynamic Languages Strike Back">dynamic languages are a better solution to the problem</a>.  Since I, when thinking about covariance and contravariance, have a hard time remembering which is which, and since I suspect that many programmers don&#8217;t understand them at all, I can sympathize with his position.</p>
<p>On an unrelated point, I enjoyed the Steve Yegge blog post that I referenced earlier.  There&#8217;s a lot of good stuff referenced there, and not just for users of dynamic languages.  He cites work on, for example, how to <a href="http://research.sun.com/self/papers/pldi94.ps.gz">make virtual method calls (nearly) as fast as static method calls</a>, it least in places where it counts. From a paper published in 1994.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37818&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37818" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Covariant%20and%20Contravariant%20Subtyping%20In%20the%20.NET%202.0%20CLR&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F05%2F14%2F37818" id="akst_email_37818" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/05/14/37818/feed</wfw:commentRss>
		</item>
		<item>
		<title>Embarcadero</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/05/09/37817</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/05/09/37817#comments</comments>
		<pubDate>Fri, 09 May 2008 13:38:23 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[Databases]]></category>

		<category><![CDATA[InterBase]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/05/09/37817</guid>
		<description><![CDATA[The Embarcadero deal seems, from my outsider&#8217;s point of view, to be a great deal for CodeGear and for Embarcadero.  There are so many different ways that the two companies&#8217; products can work together that it just makes a great deal of sense to me. It&#8217;s less clear to me how it makes sense [...]]]></description>
			<content:encoded><![CDATA[<p>The Embarcadero deal seems, from my outsider&#8217;s point of view, to be a great deal for CodeGear and for Embarcadero.  There are so many different ways that the two companies&#8217; products can work together that it just makes a great deal of sense to me. It&#8217;s less clear to me how it makes sense for Borland, but that&#8217;s their problem.  I&#8217;m curious about one thing, though.  Embarcadero is, at present, a database tools vendor.  With their purchase of CodeGear, they are acquiring two fine databases: InterBase and Blackfish SQL.  Thus far, they&#8217;ve said very little about their intentions for these products, at least relative to what they&#8217;ve said about other CodeGear tools.  Again, it seems like a great fit for Embarcadero&#8217;s product line; there&#8217;s lots of ways this could make sense.  But I&#8217;d be interested to know what their plans are.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37817&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37817" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Embarcadero&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F05%2F09%2F37817" id="akst_email_37817" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/05/09/37817/feed</wfw:commentRss>
		</item>
		<item>
		<title>If You Use OnUpdate, Your Code Must Be Perfect</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/05/05/37816</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/05/05/37816#comments</comments>
		<pubDate>Mon, 05 May 2008 15:04:13 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/05/05/37816</guid>
		<description><![CDATA[I've never particularly liked the idea of OnUpdate events. ]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve never particularly liked the idea of OnUpdate events.  They have always seemed kind of inelegant to me, but I haven&#8217;t talked about it much since I don&#8217;t really have a compelling argument against them, save for "bad smells."  Today, though, I was using RAD Studio and saw an access violation error in the IDE.  This was immediately followed by the following error, which repeated over and over again.  The stack dump tells the story:</p>
<blockquote><p>[20A635EB]{coreide100.bpl} DocModul.AnyModuleModified (Line 3466, "DocModul.pas" + 10) + $41<br />
[20A635E5]{coreide100.bpl} DocModul.AnyModuleModified (Line 3466, "DocModul.pas" + 10) + $3B<br />
<strong>[00419D8B]{bds.exe} AppMain.TAppBuilder.FileSaveAllActionUpdate (Line 4067, "ui\AppMain.pas" + 1) + $0</strong><br />
[200401A7]{rtl100.bpl  } Classes.TBasicAction.SetOnExecute (Line 11109, "common\Classes.pas" + 9) + $9<br />
[201513B1]{vcl100.bpl  } Forms..TScrollBox + $231<br />
[2004009D]{rtl100.bpl  } Classes.TBasicAction.Destroy (Line 11048, "common\Classes.pas" + 2) + $5<br />
[2013D8C7]{vcl100.bpl  } Controls.TControl.ScaleConstraints (Line 4033, "Controls.pas" + 12) + $7<br />
[2015E854]{vcl100.bpl  } Forms.DoPosition (Line 6778, "Forms.pas" + 44) + $2<br />
[2015E86E]{vcl100.bpl  } Forms.DoPosition (Line 6778, "Forms.pas" + 44) + $1C<br />
[2015E8DC]{vcl100.bpl  } Forms.DoAlign (Line 6795, "Forms.pas" + 0) + $4<br />
[201631AA]{vcl100.bpl  } Clipbrd.TClipboard.AssignPicture (Line 386, "Clipbrd.pas" + 7) + $14<br />
[201632F9]{vcl100.bpl  } Clipbrd.TClipboard.SetAsHandle (Line 430, "Clipbrd.pas" + 0) + $9<br />
[20162637]{vcl100.bpl  } Forms.TCustomFormHelper.WriteGlassFrameBottom (Line 8945, "Forms.pas" + 2) + $0<br />
[2016291F]{vcl100.bpl  } Forms.TApplicationHelper.GetEnumAllWindowsOnActivateHint (Line 9087, "Forms.pas" + 0) + $3<br />
[0042297A]{bds.exe     } bds.bds (Line 195, "" + 7) + $7</p></blockquote>
<p>Note the line in bold.  Because this is an OnUpdate event, it&#8217;s going to repeat forever.  The user is trapped.  There is no chance to save your work, or to exit the IDE normally.  You have to end task.  Sure, this is a secondary error; it&#8217;s almost certainly the consequence of the preceding access violation, rather than a defect in the OnUpdate event itself.  But because that event is not robust enough to handle the consequences of the previous error, the user is trapped.</p>
<p>My conclusion is that OnUpdate event handlers are dangerous if they do not detect anything that could possibly go wrong with the references they use, and exit gracefully in that case.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37816&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37816" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=If%20You%20Use%20OnUpdate%2C%20Your%20Code%20Must%20Be%20Perfect&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F05%2F05%2F37816" id="akst_email_37816" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/05/05/37816/feed</wfw:commentRss>
		</item>
		<item>
		<title>New Delphi Blog</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/05/02/37815</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/05/02/37815#comments</comments>
		<pubDate>Fri, 02 May 2008 14:47:16 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/05/02/37815</guid>
		<description><![CDATA[ MelanderBlog is the home of Anders Melander, who, among other things, developed the TGIFImage component included with Delphi 2007. This site includes a number of useful Delphi components.
]]></description>
			<content:encoded><![CDATA[<p> <a href="http://melander.dk/">MelanderBlog</a> is the home of Anders Melander, who, among other things, developed the TGIFImage component included with Delphi 2007. This site includes a number of <a href="http://melander.dk/download/">useful Delphi components</a>.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37815&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37815" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=New%20Delphi%20Blog&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F05%2F02%2F37815" id="akst_email_37815" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/05/02/37815/feed</wfw:commentRss>
		</item>
		<item>
		<title>Stupid PageControl Tricks</title>
		<link>http://blogs.teamb.com/craigstuntz/2008/05/01/37814</link>
		<comments>http://blogs.teamb.com/craigstuntz/2008/05/01/37814#comments</comments>
		<pubDate>Thu, 01 May 2008 18:26:36 +0000</pubDate>
		<dc:creator>Craig Stuntz</dc:creator>
		
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://blogs.teamb.com/craigstuntz/2008/05/01/37814</guid>
		<description><![CDATA[Most of the user interface for our Delphi applications is generated dynamically, at runtime.  When we display this dynamically-generated user interface in a page control, we don&#8217;t generate the user interface for each page until you first go to it.  This is for performance reasons, as there is some overhead to this, mostly [...]]]></description>
			<content:encoded><![CDATA[<p>Most of the user interface for our Delphi applications is generated dynamically, at runtime.  When we display this dynamically-generated user interface in a page control, we don&#8217;t generate the user interface for each page until you first go to it.  This is for performance reasons, as there is some overhead to this, mostly due to database access.</p>
<p>When we enabled XP themes for our applications, I started noticing a flashing on the screen the first time you went to each tab in the page control.  A little testing demonstrated that the gradient background of the tab was being rendered before the controls were created.</p>
<p>This turned out to be a fairly difficult problem to solve.  When the user changes tabs, I need to figure out to which tab they are changing, and create the controls for that tab if they are not already created.  In the TPageControl.OnChanging event, I don&#8217;t know to which tab the user is changing.  Unfortunately, both the TPageControl.OnChange and the TTabSheet.OnShow event occur after the background of the tab has already been painted.  I needed a way to render the controls, if necessary, in between these events, but after the tab to which the user is changing is already known.</p>
<p>After some rooting around in the VCL source code, I came up with the following solution.</p>
<blockquote>
<pre><code><strong>type</strong>
  TChangeToPageEvent = <strong>procedure </strong>(Sender: TObject; <strong>const </strong>APageIndex: Integer) <strong>of object</strong>;
  TChangeToEventPageControl = <strong>class</strong>(TPageControl)
  <strong>private</strong>
    FOnChangeToPage: TChangeToPageEvent;
    <strong>procedure </strong>DoOnChangeToPage(<strong>const </strong>APageIndex: Integer);
  <strong>protected</strong>
    <strong>procedure </strong>Change; <strong>override</strong>;
  <strong>public</strong>
    <strong>property </strong>OnChangeToPage: TChangeToPageEvent <strong>read </strong>FOnChangeToPage <strong>write </strong>FOnChangeToPage;
  <strong>end</strong>;

<em>{ TChangeToEventPageControl }</em>

<strong>procedure </strong>TChangeToEventPageControl.Change;
<strong>begin</strong>
  DoOnChangeToPage(TabIndex);
  <strong>inherited</strong>;
<strong>end</strong>;

<strong>procedure </strong>TChangeToEventPageControl.DoOnChangeToPage(<strong>const </strong>APageIndex: Integer);
<strong>begin</strong>
  <strong>if </strong>Assigned(FOnChangeToPage) <strong>then begin</strong>
    FOnChangeToPage(Self, APageIndex);
  <strong>end;</strong>
<strong>end</strong>;</code></pre>
</blockquote>
<p>Since I also create the page control itself dynamically, I don&#8217;t even have to install this on the component palette to make it work.  Handling the OnChangeToPage event allows me to create the controls when the page to which the user is changing is known, but before the tab itself renders.</p>
<p class="akst_link"><a href="http://blogs.teamb.com/craigstuntz/?p=37814&amp;akst_action=share-this"  title="Post to del.icio.us, etc." id="akst_link_37814" class="akst_share_link" rel="nofollow">Share This</a> | <a href="mailto:?subject=Stupid%20PageControl%20Tricks&body=Have you seen this? http%3A%2F%2Fblogs.teamb.com%2Fcraigstuntz%2F2008%2F05%2F01%2F37814" id="akst_email_37814" class="akst_share_email" rel="nofollow">Email this page to a friend</a></p>]]></content:encoded>
			<wfw:commentRss>http://blogs.teamb.com/craigstuntz/2008/05/01/37814/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
