{"id":2118,"date":"2013-11-07T20:14:47","date_gmt":"2013-11-07T08:14:47","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=2118"},"modified":"2013-11-07T21:07:51","modified_gmt":"2013-11-07T09:07:51","slug":"creation-stories","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/2118\/","title":{"rendered":"Creation Stories"},"content":{"rendered":"<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\"> 3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>In the beginning there was <del>The Word<\/del> a HWND.  But not all gifts of creation can be relied upon, as I just learned.  Or rather, remembered.<\/p>\n<p><!--more--><\/p>\n<p>As regular readers will know, I am currently polishing up my <strong>Smoketest<\/strong> framework for release (don&#8217;t worry, this post won&#8217;t take long and then I can get back to that job).<\/p>\n<p>I made a recent change that I was particularly pleased with.  It was a trivial thing, but one of those small things that makes a big difference.<\/p>\n<p>Previously the GUI console would indicate the currently executing test with a particular icon, replaced once the test was complete with another icon indicating the test result.  This was fine, but on longer running tests was&#8230; well.. a bit boring.  So I animated it.<\/p>\n<p>Drawing on an experience from many years ago and combining that with message based thread synchronization, I opted to implement a motile thread <sup>*1<\/sup>  which would provide the beating heart of my animation.  This thread would simply pump out messages at the rate of 12 per second, incrementing a frame counter.<\/p>\n<p><sup>*1<\/sup> &#8211; <em>my own term &#8211; and a specific class in my threading library &#8211; for a lightweight, fire-and-forget thread that just keeps churning away on it&#8217;s allocated, usually trivial task indefinitely.  When I devised the class I purloined the name from a superb science fiction novel (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Commonwealth_Saga\">Pandora&#8217;s Star<\/a>) that I was reading at the time.<\/em><\/p>\n<p>Upon receiving the message my console UI would update the icons of any currently running test(s) to the image for the frame indicated in the message.<\/p>\n<p>And it all worked beautifully:<\/p>\n<figure id=\"attachment_2119\" aria-describedby=\"caption-attachment-2119\" style=\"width: 320px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Very-Pretty.gif?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Very-Pretty.gif?resize=320%2C240&#038;ssl=1\" alt=\"Animation working well\" width=\"320\" height=\"240\" class=\"size-full wp-image-2119\" \/><\/a><figcaption id=\"caption-attachment-2119\" class=\"wp-caption-text\">Animation working well<\/figcaption><\/figure>\n<p>Things didn&#8217;t go so well when I rebuilt the test project (in this particular case for my Bonjour components &#8211; are you reading this Stefan ? :)) for Delphi 7.<\/p>\n<figure id=\"attachment_2120\" aria-describedby=\"caption-attachment-2120\" style=\"width: 320px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Not-so-hot.gif?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Not-so-hot.gif?resize=320%2C240&#038;ssl=1\" alt=\"Oh.  Dear.  Oh.  Dear.\" width=\"320\" height=\"240\" class=\"size-full wp-image-2120\" \/><\/a><figcaption id=\"caption-attachment-2120\" class=\"wp-caption-text\">Oh.  Dear.  Oh.  Dear.<\/figcaption><\/figure>\n<p>This problem has been bugging me for a couple of weeks now but I had a bit of a gap in my schedule to spend some time looking into it, and fortunately the problem and the solutions turned out to be very simple.<\/p>\n<p>I was creating my animation beat thread in the FormCreate event of my main form and passing the form window handle at that point.<\/p>\n<p>In Delphi 2010 and later this was fine.  In Delphi 7 (and 2006 and possibly other versions though I didn&#8217;t check) the thread would happily run and pump out the messages as it should, but the<strong> Application.ProcessMessage()<\/strong> method would never receive them.<\/p>\n<p>No doubt a fair few people out there are jumping up and down and pointing and shouting <strong>I KNOW WHAT&#8217;S WRONG I KNOW WHAT&#8217;S WRONG<\/strong>.  And fortunately it didn&#8217;t take me long to arrive at the answer myself.<\/p>\n<p>I remembered that over the years and various <strong>Delphi<\/strong> versions the order in which events occur during form creation has changed on different occasions.  Also, the various conditions that result in window handles being created and subsequently re-created has also changed.<\/p>\n<p>The reason that my animation messages were not being received was that the window handle to which they were being sent no longer existed because my console form window (the underlying HWND) had been destroyed and re-created at some point after providing the <strong>Handle<\/strong> to the thread in the <strong>FormCreate()<\/strong> event.<\/p>\n<p>But only in these <em>earlier<\/em> versions of <strong>Delphi<\/strong>.<\/p>\n<p>Having realised the problem, the solution was very simple: Move the code which assigned the <strong>HWND<\/strong> to the animation thread to an override of the form&#8217;s <strong>CreateHandle<\/strong> method.  Then no matter if, when or how many times my form&#8217;s <strong>HWND<\/strong> was re-created, the animation thread would always be sure to be posting it&#8217;s messages to the right window:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  procedure TSmoketestConsole.CreateHandle;\r\n  begin\r\n    inherited;\r\n    FPS.Handle := self.Handle;\r\n  end;\r\n<\/pre>\n<p>And hey presto, my oh-so-pretty little animation works in all versions of Delphi from the venerable 7 onward.<\/p>\n<figure id=\"attachment_2121\" aria-describedby=\"caption-attachment-2121\" style=\"width: 320px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Thats-Better.gif?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Thats-Better.gif?resize=320%2C240&#038;ssl=1\" alt=\"All is once more right with the world.  Phew.\" width=\"320\" height=\"240\" class=\"size-full wp-image-2121\" \/><\/a><figcaption id=\"caption-attachment-2121\" class=\"wp-caption-text\">All is once more right with the world.  Phew.<\/figcaption><\/figure>\n<p>Apologies for the <strong>Screen-o-matic<\/strong> water-mark on these files by the way. I&#8217;ll be taking the time to look for a (Mac) tool for capturing such video vignettes but for now the free version of this did the job, and the watermark is the price I had to pay.  Hey ho.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\"> 3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span>In the beginning there was The Word a HWND. But not all gifts of creation can be relied upon, as I just learned. Or rather, remembered.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[4],"tags":[292],"class_list":["post-2118","post","type-post","status-publish","format-standard","hentry","category-delphi","tag-delphi"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-ya","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=2118"}],"version-history":[{"count":4,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2118\/revisions"}],"predecessor-version":[{"id":2125,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2118\/revisions\/2125"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=2118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=2118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=2118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}