<?xml version="1.0" encoding="UTF-8"?>
<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/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DaVinci Unlimited Software &#187; code</title>
	<atom:link href="http://www.davinciunltd.com/tag/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.davinciunltd.com</link>
	<description>Jim McKeeth's blog on creative and innovative Delphi programming.</description>
	<lastBuildDate>Wed, 09 Nov 2011 10:39:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Crashing Like VB</title>
		<link>http://www.davinciunltd.com/2007/11/crashing-like-vb/</link>
		<comments>http://www.davinciunltd.com/2007/11/crashing-like-vb/#comments</comments>
		<pubDate>Wed, 28 Nov 2007 10:27:20 +0000</pubDate>
		<dc:creator>Jim McKeeth</dc:creator>
				<category><![CDATA[CodeRage]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[]]></category>
		<category><![CDATA[crash]]></category>
		<category><![CDATA[exceptions]]></category>
		<category><![CDATA[VB]]></category>
		<category><![CDATA[vista]]></category>

		<guid isPermaLink="false">http://www.davinciunltd.com/2007/11/crashing-like-vb/</guid>
		<description><![CDATA[I always thought Delphi&#8217;s global exception handler was a great feature.  It allows your program to continue after an otherwise unhandled exception would have caused it to terminate.  Typically in a serious application you would assign your own global exception handler, or used one of the great 3rd part exception handlers like madExcept [...]]]></description>
			<content:encoded><![CDATA[<p>I always thought Delphi&#8217;s global exception handler was a great feature.  It allows your program to continue after an otherwise unhandled exception would have caused it to terminate.  Typically in a serious application you would assign your own global exception handler, or used one of the great 3rd part exception handlers like <a href="http://www.madshi.net/madExceptDescription.htm">madExcept</a> or <a href="http://www.dimusware.com/products/excmagic/index.html">Exceptional Magic</a> (I love that name!)  They both provide a nice dialog, stack trace, logging and reporting.</p>
<p>Well it turns out that if you want to be <a href="http://download.microsoft.com/download/8/e/4/8e4c929d-679a-4238-8c21-2dcc8ed1f35c/Windows%20Vista%20Software%20Logo%20Spec%201.1.doc" title="Windows Vista Software Logo Spec 1.1.doc">Microsoft Windows Vista Logo certified</a>, then you need to crash your application on certain exceptions.</p>
<blockquote><p>Applications must handle only exceptions that are known and expected, and Windows Error Reporting must not be disabled.  If a fault (such as an Access Violation) is injected into an application, the application must allow Windows Error Reporting to report this crash.  (from requirement <em>3.2  Resilient Software: Eliminate Application Failures</em>)</p></blockquote>
<p>Microsoft&#8217;s rational for this requirement is the ISV will receive the error report Microsoft collects for them. I guess most software developers don&#8217;t have access to tools like we do in Delphi to catch exceptions and log them for us.</p>
<p>So short of tossing out the Forms unit and writing everything from scratch, how can you get around the usefulness of the global exception handler.</p>
<p>My first thought was to create a custome application exception handler by placing a TApplicationEvents on your main form and assigning the OnException event.  In the event include the line</p>
<pre lang="Delphi">  raise e;</pre>
<p>This will pass an exception up to the operating system and terminate your application, at least when I tested it in Delphi 2007.  When I tried it in Delphi 7, it didn&#8217;t work right.</p>
<p>A more elegant and involved solution:</p>
<p>First you need a couple global variables:</p>
<pre lang="delphi">var
  GlobalExcept: Exception;
  GlobalExceptAddr: Pointer;</pre>
<p>And a global exception handler:</p>
<pre lang="Delphi">procedure TForm1.ApplicationException(Sender: TObject; E: Exception);
begin
  if E is EAccessViolation then
  begin
    // Keep the exception object from being destroyed!
    AcquireExceptionObject;
    GlobalExcept := e;
    GlobalExceptAddr := ExceptAddr;
    Application.Terminate;
  end;
end;</pre>
<p>The rest of the magic happens in the project file (DPR)</p>
<pre lang="delphi">begin
  GlobalExcept := nil;
  GlobalExceptAddr := nil;
  try
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
  Application.Run;
  finally
    if Assigned( GlobalExcept ) then
    begin
      raise GlobalExcept at GlobalExceptAddr;
    end;
  end;
end.</pre>
<p>And you can [<a href="/download/CrashLikeVB.zip">download the code</a>].</p>
<p><a href="http://groups.google.com/group/borland.public.delphi.non-technical/browse_thread/thread/861ffdef8f23b7be" title="Read the thread on Google Groups.">Thanks to Jeremi Reda for asking this question in borland.public.delphi.non-technical.</a></p>
<p>I didn&#8217;t cover this in my CodeRage II session on Exceptional Exceptions, but there is a lot of other cool stuff, like <code>AcquireExceptionObject</code>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davinciunltd.com/2007/11/crashing-like-vb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

