<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Delphi Haven</title>
	<atom:link href="http://delphihaven.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://delphihaven.wordpress.com</link>
	<description>Just another Delphi programming port of call on the internet</description>
	<lastBuildDate>Wed, 01 Feb 2012 02:46:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='delphihaven.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Delphi Haven</title>
		<link>http://delphihaven.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://delphihaven.wordpress.com/osd.xml" title="Delphi Haven" />
	<atom:link rel='hub' href='http://delphihaven.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Fixing TThreadedQueue&#8230;? (Or in other words: TMonitor&#8230; again!)</title>
		<link>http://delphihaven.wordpress.com/2012/01/30/fixing-tthreadedqueue-or-in-other-words-tmonitor-again/</link>
		<comments>http://delphihaven.wordpress.com/2012/01/30/fixing-tthreadedqueue-or-in-other-words-tmonitor-again/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 07:11:24 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[TMonitor]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1927</guid>
		<description><![CDATA[Probably out of masochism or something, I&#8217;ve been looking at TMonitor again. For anyone who doesn&#8217;t recall the earlier episodes, TMonitor is the &#8216;new&#8217; (and rather low-level) threading device introduced in D2009. Alas, but it proved buggy as hell, as well as slow. Given the publicity however, it received some love for XE2 RTM. So, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1927&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Probably out of masochism or something, I&#8217;ve been looking at TMonitor again. For anyone who doesn&#8217;t recall the earlier episodes, TMonitor is the &#8216;new&#8217; (and rather low-level) threading device introduced in D2009. Alas, but it proved buggy as hell, as well as slow. Given the publicity however, it received some love for XE2 RTM. So, all right in the end? Er no, since Darian Miller on <a href="http://stackoverflow.com/a/8175071">StackOverflow</a> quickly tweaked one of the test projects that demonstrated its brokeness in XE and&#8230; found it still broken in XE2!</p>
<p>More exactly, the test project in question uses the TThreadedQueue class. Having experimented a bit more with TMonitor and found it seemingly OK, I thought I&#8217;d investigate the TThreadedQueue implementation. My initial idea was to test its logic distinct from TMonitor&#8217;s by replacing use of TMonitor with calls to equivalent Windows APIs (a monitor combines a critical section and a &#8216;conditional variable&#8217;, and the Windows API acquired a condition variable primitive in Vista). However, on inspecting the code, I found it using the (to me) rather tricky-to-comprehend 3 parameter overload of TMonitor.Wait &#8211; and in my usage, I&#8217;ve stuck to the simpler, 2 parameter overload. This made me think: if I just rewrote TThreadedQueue similarly, would that fix the problem? I think it has, but I would be grateful if anyone else could verify: </p>
<p>1. Download the problem project from the Windows QC client &#8211; browse to report number 101114, and get the DPR from the &#8216;attachments&#8217; tab.</p>
<p>2. Open the project in the IDE, and add a new unit to it.</p>
<p>3. Copy the code for TThreadedQueue from System.Generics.Collections.pas. As it is almost completely self-contained, you need only System.SyncObjs in the new unit&#8217;s uses clause.</p>
<p>4. In the copied class definition, remove FQueueNotEmpty and FQueueNotFull. Everything else in the interface stays the same however.</p>
<p>5. Remove the lines constructing and freeing FQueueNotEmpty and FQueueNotFull in Create and Destroy.</p>
<p>6. Change the implementation of the substantive PopItem variant to this:</p>
<p><pre class="brush: delphi;">
function TThreadedQueue&lt;T&gt;.PopItem(var AQueueSize: Integer; var AItem: T): TWaitResult;
begin
  AItem := Default(T);
  TMonitor.Enter(FQueueLock);
  try
    while (FQueueSize = 0) and not FShutDown do
      if not TMonitor.Wait(FQueueLock, FPopTimeout) then Exit(wrTimeout);
    if FShutDown then Exit(wrAbandoned);   
    Result := wrSignaled;                                                  
    AItem := FQueue[FQueueOffset];
    if FQueueSize = Length(FQueue) then
      TMonitor.PulseAll(FQueueLock);
    Dec(FQueueSize);
    Inc(FQueueOffset);
    Inc(FTotalItemsPopped);
    if FQueueOffset = Length(FQueue) then
      FQueueOffset := 0;
  finally
    AQueueSize := FQueueSize;
    TMonitor.Exit(FQueueLock);
  end;
end;
</pre></p>
<p>The main thing here is that we are now using the simpler variant of Wait. As an aside, it&#8217;s OK to &#8216;pulse&#8217; as early as we do, since waiting threads only get notified once we&#8217;ve exited the monitor.</p>
<p>7. Change the implementation of the substantive PushItem overload to this:</p>
<p><pre class="brush: delphi;">
function TThreadedQueue&lt;T&gt;.PushItem(const AItem: T; var AQueueSize: Integer): TWaitResult;
begin
  TMonitor.Enter(FQueueLock);
  try
    while (Length(FQueue) = FQueueSize) and not FShutDown do
      if not TMonitor.Wait(FQueueLock, FPushTimeout) then Exit(wrTimeout);
    if FShutDown then Exit(wrAbandoned);
    Result := wrSignaled;
    if FQueueSize = 0 then TMonitor.PulseAll(FQueueLock);
    FQueue[(FQueueOffset + FQueueSize) mod Length(FQueue)] := AItem;
    Inc(FQueueSize);
    Inc(FTotalItemsPushed);
  finally
    AQueueSize := FQueueSize;
    TMonitor.Exit(FQueueLock);
  end;
end;
</pre></p>
<p>8. Change DoShutdown to this:</p>
<p><pre class="brush: delphi;">
procedure TThreadedQueue&lt;T&gt;.DoShutDown;
begin
  FShutDown := True;
  TMonitor.PulseAll(FQueueLock);
end;
</pre></p>
<p>I&#8217;ve removed the locking around setting FShutdown since I don&#8217;t see what good it does (no one will be trying to set it to False).</p>
<p>9. Rerun the problem project: hopefully, it will now work (meaning, it will count up to 1000 without crashing), notwithstanding the fact we haven&#8217;t actually fixed the bug in TMonitor itself&#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1927/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1927/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1927/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1927/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1927/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1927/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1927/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1927/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1927/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1927/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1927/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1927/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1927/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1927/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1927&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2012/01/30/fixing-tthreadedqueue-or-in-other-words-tmonitor-again/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>
	</item>
		<item>
		<title>Two FireMonkey nasties</title>
		<link>http://delphihaven.wordpress.com/2012/01/20/two-firemonkey-nasties/</link>
		<comments>http://delphihaven.wordpress.com/2012/01/20/two-firemonkey-nasties/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 18:57:34 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[XE2]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1914</guid>
		<description><![CDATA[As the title says, here&#8217;s two little FireMonkey nasties I&#8217;ve got round to QC&#8217;ing that may be of interest to someone starting to play around with the framework: TBitmap.LoadFromFile does not raise an exception when the file does not exist &#8211; instead, it just silently returns (see QC 102636). TFmxObject.Children (which is equivalent to TWinControl.Controls [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1914&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As the title says, here&#8217;s two little FireMonkey nasties I&#8217;ve got round to QC&#8217;ing that may be of interest to someone starting to play around with the framework:</p>
<ol>
<li>TBitmap.LoadFromFile does not raise an exception when the file does not exist &#8211; instead, it just silently returns (see <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=102636">QC 102636</a>).</li>
<li>TFmxObject.Children (which is equivalent to TWinControl.Controls in the the VCL) always returns nil on an out-of-range index rather than raising an exception. Combined with the fact the &#8216;as&#8217; operator accepts a nil source, this causes typos to generate nasty, generic access violations rather than exceptions that tell you what the error actually is (see <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=102747">QC 102747</a>).</li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1914/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1914/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1914/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1914&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2012/01/20/two-firemonkey-nasties/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>
	</item>
		<item>
		<title>Mac troubles redux</title>
		<link>http://delphihaven.wordpress.com/2012/01/20/mac-troubles-redux/</link>
		<comments>http://delphihaven.wordpress.com/2012/01/20/mac-troubles-redux/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 15:45:02 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[XE2]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1910</guid>
		<description><![CDATA[Not long after I posted previously about an anonymous blogger having problems with running Delphi applications on OS X Lion &#8211; the error message was ‘You cannot open the application test01.app because the Classic environment is no longer supported’, which in itself didn&#8217;t make any sense &#8211; some helpful hints were posted in a comment: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1910&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Not long after I posted previously about an anonymous blogger having problems with running Delphi applications on OS X Lion &#8211; the error message was ‘You cannot open the application test01.app because the Classic environment is no longer supported’, which in itself didn&#8217;t make any sense &#8211; some helpful hints were posted in a comment:</p>
<blockquote><p>For what it’s worth, I run applications built with XE2 on OSX Lion just fine. Other people do too.</p>
<p>I think it’s unlikely that Carbon APIs would cause this. This error normally occurs for a OS9 application, i.e. something is probably making the loader think it is not a OSX app. They have very different executable formats. This is guesswork, but makes more sense than an old API somehow drawn in – I don’t see how Embarcadero could have done that, given they provide translations of the Apple-provided headers / APIs and were probably working with those same translations themselves.</p>
<p>Some googling would have turned up threads like this: <a href="http://forums.digitalspy.co.uk/showthread.php?p=39579653" rel="nofollow">http://forums.digitalspy.co.uk/showthread.php?p=39579653</a> where other new apps, in this case iTunes itself (!) gives this error. The solutions imply it’s due to corruption of some sort: possibly of the app, the app bundle, permissions, or even the OS.</p>
<p>Things to try would be:<br />
- Clean and rebuild the app (and completely remove it from where it’s located on OSX, to be sure to make the IDE moves everything across again.)<br />
- Open the app bundle and compare it to a working app. What’s different? Can he execute the program located in the bundle from the command line? If not, what error does it give?<br />
- Reinstall the remote debugger. Maybe it’s this thats corrupted, not even his app…? It’s impossible to know from his post when this error occurs (running from the IDE, i.e. debugging? Running the app normally on OSX? …?)<br />
- Open Disk Utility and verify the disk, and check / fix file permissions.</p>
<p>After that, if he still has problems, I’ll admit it’s more complicated. The next appropriate move would be to post on the Embarcadero forums or open a support request.</p></blockquote>
<p>Thanks to David M for the advice.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1910/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1910&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2012/01/20/mac-troubles-redux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>
	</item>
		<item>
		<title>Anyone want to help out Mr Hater&#8230;?</title>
		<link>http://delphihaven.wordpress.com/2012/01/19/anyone-want-to-help-out-mr-hater/</link>
		<comments>http://delphihaven.wordpress.com/2012/01/19/anyone-want-to-help-out-mr-hater/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 00:25:48 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[XE2]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1903</guid>
		<description><![CDATA[Poor Mr Hater is having trouble running FireMonkey applications and/or the remote debugger (it&#8217;s unclear what) on OS X Lion. Would any XE2-user-with-a-Mac have a suggestion? The error message reported (&#8216;You cannot open the application test01.app because the Classic environment is no longer supported&#8217;) doesn&#8217;t make any sense in itself, since the &#8216;Classic&#8217; environment was [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1903&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Poor Mr Hater is <a href="http://delphihaters.blogspot.com/2012/01/delphi-xe2-osx-lion.html">having trouble</a> running FireMonkey applications and/or the remote debugger (it&#8217;s unclear what) on OS X Lion. Would any XE2-user-with-a-Mac have a suggestion? The error message reported (&#8216;You cannot open the application test01.app because the Classic environment is no longer supported&#8217;) doesn&#8217;t make any sense in itself, since the &#8216;Classic&#8217; environment was the emulator that ran OS 9 applications compiled for PowerPC, and XE2 has as much chance compiling for OS 9 and PowerPC as it has targeting CP/M on a Motorola 68000.</p>
<p>In fact, in the main, XE2&#8242;s RTL and FMX sources keep well away from legacy Mac APIs. Despite some (probably unintentional) misinformation around, the frame of an FMX form is a Cocoa window, not a Carbon one (&#8216;Carbon&#8217; was/is the API Apple provided to allow C and C++ applications to cross compile for OS 9 and OS X, &#8216;Cocoa&#8217; the &#8216;modern&#8217; Objective-C and OS X-only API). As for the RTL, this delegates to the POSIX layer as much as possible, and failing that CoreFoundation, which is C-based but OS X specific API layer. There is however one exception &#8211; due to OS X&#8217;s apparently incomplete implementation of POSIX threading (it doesn&#8217;t support unnamed semaphores), the Carbon &#8216;Multiprocessing Services&#8217; API is used instead for TSemaphore, TEvent and TMonitor. This then brings in TCriticalSection and a few other things, which are based on TMonitor when targeting OS X. While the RTL team should probably be at least investigating an alternative to the Carbon API here <a href="http://developer.apple.com/library/mac/#documentation/Carbon/Reference/Multiprocessing_Services/Reference/reference.html">pretty sharpish</a>, surely use of an API only recently marked &#8216;deprecated&#8217; (&#8216;v10.7&#8242; = Lion) wouldn&#8217;t have caused Mr Hater&#8217;s problem&#8230;?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1903/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1903/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1903/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1903/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1903/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1903/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1903/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1903/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1903/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1903/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1903/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1903/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1903/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1903/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1903&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2012/01/19/anyone-want-to-help-out-mr-hater/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>
	</item>
		<item>
		<title>Nice post on writing a custom FireMonkey control</title>
		<link>http://delphihaven.wordpress.com/2012/01/16/nice-post-on-writing-a-custom-firemonkey-control/</link>
		<comments>http://delphihaven.wordpress.com/2012/01/16/nice-post-on-writing-a-custom-firemonkey-control/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 08:33:40 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[XE2]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1898</guid>
		<description><![CDATA[Just a quick post to say if you&#8217;re interested in the basic mechanics of custom control creation in the FireMonkey framework, you may want to check out this article by Mike Sutton on his MonkeyStyler blog.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1898&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Just a quick post to say if you&#8217;re interested in the basic mechanics of custom control creation in the FireMonkey framework, you may want to check out <a href="http://monkeystyler.com/blog/entry/my-first-firemonkey-custom-control-tbitmapspeedbutton">this article</a> by Mike Sutton on his MonkeyStyler blog.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1898/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1898/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1898/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1898/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1898/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1898/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1898/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1898/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1898/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1898/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1898/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1898/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1898/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1898/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1898&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2012/01/16/nice-post-on-writing-a-custom-firemonkey-control/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>
	</item>
		<item>
		<title>XE2 update for my image metadata reading/writing library (CCR Exif)</title>
		<link>http://delphihaven.wordpress.com/2012/01/16/xe2-update-for-my-image-metadata-readingwriting-library-ccr-exif/</link>
		<comments>http://delphihaven.wordpress.com/2012/01/16/xe2-update-for-my-image-metadata-readingwriting-library-ccr-exif/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 23:23:28 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[CCR Exif]]></category>
		<category><![CDATA[XE2]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1886</guid>
		<description><![CDATA[I was going to get round to it eventually, though having an explicit request prompted me to actually do it: updating my open source image metadata reading/writing library (CCR Exif) to properly support XE2. The updates I&#8217;ve just posted to Google Code has it cross compiling for each of Delphi XE2&#8242;s three DCC-targeting platforms, Win32, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1886&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I was going to get round to it eventually, though having an explicit request prompted me to actually do it: updating my open source image metadata reading/writing library (CCR Exif) to properly support XE2. The updates I&#8217;ve just posted to Google Code has it cross compiling for each of Delphi XE2&#8242;s three DCC-targeting platforms, Win32, Win64 and OS X; it should also still compile back to D2006, though at least D2007, and preferably D2009 are preferred. On the downside, iOS <em>isn&#8217;t</em> supported because the code remains as Delphi-specific as ever (and no, FPC 2.6.0 doesn&#8217;t help much). Also, there aren&#8217;t any FireMonkey demos as yet, though the console ones all cross compile if you have XE2 and add OS X as a target platform.</p>
<p>In practical terms, Win64 took as long as it took to add &#8216;Win64&#8242; as a target for each of the demos; OS X was somewhat longer for a mixture of reasons, primarily because the code had some entanglement with the VCL graphics classes, and there&#8217;s no &#8216;clean&#8217; way for the same code to work with both VCL and FMX on that score. By far the biggest <del>waste of time</del> effort was managing project files across an array of Delphi versions though, with battling Subversion a close second, i.e. not actual coding at all. As I wanted to make running the demos as newbie-friendly as possible, I&#8217;ve ended up with separate project files for D2006, D2007, D2009-10 and XE+ &#8211; just open the appropriate project group located at the top of the trunk and do a Project|Compile All. If compiling under D2007 or later, executables will then be outputted in a sub-directory off the Bin folder next to the individual projects, and DCUs in a &#8216;DCUs&#8217; folder off of the main trunk.</p>
<p>Anyhow, the Google Code page is <a href="http://code.google.com/p/ccr-exif/">here</a>; if using the <strong>File|Open From Version Control&#8230;</strong> command in the XE or XE2 IDE, the URL to enter is <strong><a href="http://ccr-exif.googlecode.com/svn/trunk/">http://ccr-exif.googlecode.com/svn/trunk/</a></strong>; choose either <strong>Console Demos (XE+).groupproj</strong> or <strong>VCL Demos (XE+).groupproj</strong> as appropriate when prompted.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1886/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1886/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1886/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1886/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1886/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1886/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1886/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1886/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1886/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1886/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1886/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1886/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1886/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1886/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1886&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2012/01/16/xe2-update-for-my-image-metadata-readingwriting-library-ccr-exif/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>
	</item>
		<item>
		<title>Running console applications on Lin&#8230; er, OS X</title>
		<link>http://delphihaven.wordpress.com/2012/01/14/running-console-applications-on-lin-er-os-x/</link>
		<comments>http://delphihaven.wordpress.com/2012/01/14/running-console-applications-on-lin-er-os-x/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 20:54:19 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[XE2]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1862</guid>
		<description><![CDATA[Here&#8217;s a few small small OS X (or more generally, Unix and Unix-y) console application tips. All of them are pretty trivial, but I easily forget such things, so they&#8217;re for my own future benefit really&#8230; If a application isn&#8217;t on the system PATH, then you always need to provide a path when running the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1862&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a few small small OS X (or more generally, Unix and Unix-y) console application tips. All of them are pretty trivial, but I easily forget such things, so they&#8217;re for my own future benefit really&#8230;</p>
<ul>
<li>If a application isn&#8217;t on the system PATH, then you <em>always n</em>eed to provide a path when running the program on the command line. Happily, relative paths are acceptable, and the symbol for &#8216;the current directory&#8217; (i.e., a single full stop) is the same on Unix and Windows. For example, say you have a console program called <strong>MyUtil</strong> that has been put in <strong>~/Applications</strong>. If in a Terminal window you go into that folder, the command for running the program will involve prefixing its name with a full stop and a forward slash:</li>
</ul>
<pre>  cd ~/Applications
  ./myutil</pre>
<ul>
<li>There are numerous &#8216;standard&#8217; locations to put console applications where they will be globally available &#8212; on my iMac, the system path (with no changes to it on my part) is composed of <strong>/opt/local/bin</strong>, <strong>opt/local/sbin</strong>, <strong>/usr/bin</strong>, <strong>/usr/sbin</strong>, <strong>/sbin</strong>, <strong>/usr/local/bin</strong> and <strong>/usr/X11/bin</strong>! Of the main Linux-y stuff I&#8217;ve installed, Wine has dumped a load of things in <strong>/opt/local/bin</strong> and Mono has liberally fly-tipped <strong>/usr/bin</strong>. Since out of the root directories, only <strong>/opt</strong> isn&#8217;t hidden by default in Finder (well, at least for me), I&#8217;ve put things of my own in <strong>/opt/local/bin</strong>. This still requires getting past the equivalent of a UAC prompt, though that isn&#8217;t a bad thing IMO.</li>
<li>When distributing a Delphi-produced console application, remember there is one dependency you can&#8217;t avoid &#8211; <strong>libcgunwind.1.0.dylib</strong>. This must be placed in the same directory as the executable. However, it is only 25KB. The much bigger, and program-specific, <strong>.rsm</strong> file the compiler produces should <strong>not</strong> be required &#8211; this is just for debugging.</li>
<li>When the user passes a parameter to a console application that contains a wildcard, the command-line interpreter will expand it before the application gets a chance to do anything. For example, say the command <strong>myutil *.jpg</strong> is entered, where <strong>MyUtil</strong> is a console application written in Delphi; inside of the application, <strong>ParamCount</strong> will return the number of *.jpg files in the current directory, <strong>ParamStr(1)</strong> the first *.jpg file, <strong>ParamStr(2)</strong> the second and so on.</li>
<li>If you want to prevent wildcard auto-expansion, wrap the parameter in quotes, just as you would wrap a parameter that contains one or more spaces in quotes:</li>
</ul>
<pre>  myutil "*.jpg"</pre>
<ul>
<li><strong>ParamStr(0)</strong> on OS X will return whatever was typed by the user to start the program. If that was <strong>./</strong><strong>myutil</strong> , then <strong>./myutil</strong> will be returned (you won&#8217;t notice this in a FireMonkey application, since a graphical OS X application is &#8216;bundled&#8217;, and so never run directly by the user). If you want a path, you can use <strong>GetModuleName(0)</strong> instead (as you can on Windows in fact). This however is likely to return the executable&#8217;s path concatenated with whatever ParamStr(0) returns, meaning both a superfluous <strong>./</strong> could be embedded <em>and</em> the &#8216;wrong&#8217; casing used (on Windows, ParamStr(0) will return the file name with the case of the actual EXE file &#8211; MyUtil.exe not myutil.exe). To fix both, pass whatever GetModuleName returns to <strong>ExpandFileNameCase</strong>:</li>
</ul>
<p><pre class="brush: delphi;">
  function GetExecutableName: string;
  var
    MatchedCase: TFilenameCaseMatch;
  begin
    Result := ExpandFileNameCase(GetModuleName(0), MatchedCase);
  end;
</pre></p>
<p style="padding-left:30px;">While unnecessary, this extra handling is harmless when targeting Windows, so you don&#8217;t need to IFDEF it when targeting both platforms.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1862/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1862/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1862/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1862/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1862/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1862/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1862/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1862/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1862/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1862/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1862/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1862/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1862/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1862/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1862&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2012/01/14/running-console-applications-on-lin-er-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>
	</item>
		<item>
		<title>Writing Delphi console applications that call a Cocoa API</title>
		<link>http://delphihaven.wordpress.com/2012/01/09/writing-delphi-console-applications-that-call-a-cocoa-api/</link>
		<comments>http://delphihaven.wordpress.com/2012/01/09/writing-delphi-console-applications-that-call-a-cocoa-api/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 07:38:40 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[tips]]></category>
		<category><![CDATA[XE2]]></category>
		<category><![CDATA[OS X]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1856</guid>
		<description><![CDATA[Just a quick tip for anyone struggling with calling a Cocoa (i.e., Objective-C) API in a Delphi console application: if you&#8217;re getting &#8216;class cannot be found&#8217; errors on the simplest of calls, that&#8217;s because the relevant Cocoa framework hasn&#8217;t been loaded, and therefore, hasn&#8217;t had a chance to register its classes with your application. A [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1856&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Just a quick tip for anyone struggling with calling a Cocoa (i.e., Objective-C) API in a Delphi console application: if you&#8217;re getting &#8216;class cannot be found&#8217; errors on the simplest of calls, that&#8217;s because the relevant Cocoa framework hasn&#8217;t been loaded, and therefore, hasn&#8217;t had a chance to register its classes with your application. A quick way to fix this is to make a dummy call at the top of the DPR to one of the string &#8216;constant&#8217; loading routines in the Macapi.Foundation unit, e.g. NSDefaultRunLoopMode:</p>
<p><pre class="brush: delphi;">
uses 
  System.SysUtils, Macapi.Foundation;
begin
  NSDefaultRunLoopMode;
  //actually do stuff...
</pre></p>
<p>Once done, there is nevertheless a second thing you&#8217;ll need to do, which is to set up an Objective-C/Cocoa &#8216;auto-release pool&#8217;. This probably sounds more grand than in actually is &#8211; just create an instance of NSAutoRelease pool at the head of your code, and &#8216;drain&#8217; it at its foot:</p>
<p><pre class="brush: delphi;">
program CocoaConsoleTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Macapi.Foundation;
var
  Pool: NSAutoreleasePool;
  Host: NSHost;
begin
  NSDefaultRunLoopMode; //just something to ensure the Cocoa Foundation framework is loaded
  Pool := TNSAutoreleasePool.Create;
  try
    Host := TNSHost.Wrap(TNSHost.OCClass.currentHost);
    WriteLn('This computer is called ' + UTF8ToUnicodeString(Host.localizedName.UTF8String));
  finally
    Pool.drain;
  end;
end.
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1856/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1856/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1856/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1856/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1856/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1856/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1856/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1856/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1856/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1856/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1856/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1856/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1856/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1856/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1856&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2012/01/09/writing-delphi-console-applications-that-call-a-cocoa-api/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>
	</item>
		<item>
		<title>Programmatically taking a screenshot on OS X</title>
		<link>http://delphihaven.wordpress.com/2012/01/02/programmatically-taking-a-screenshot-on-os-x/</link>
		<comments>http://delphihaven.wordpress.com/2012/01/02/programmatically-taking-a-screenshot-on-os-x/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 21:56:10 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[XE2]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1839</guid>
		<description><![CDATA[Browsing Embarcadero&#8217;s FireMonkey forum, I noticed an unanswered question about programmatically taking a screenshot on OS X. Having previously figured out how to paste a graphic from the OS X clipboard to a FireMonkey TBitmap (see here), I thought doing a screenshot couldn&#8217;t be any harder. As it turned out, it was perhaps a bit more convoluted, and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1839&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Browsing Embarcadero&#8217;s FireMonkey forum, I noticed an unanswered question about programmatically taking a screenshot on OS X. Having previously figured out how to paste a graphic from the OS X clipboard to a FireMonkey TBitmap (<a href="http://delphihaven.wordpress.com/2011/10/06/copying-and-pasting-the-contents-of-a-firemonkey-tbitmap/">see here</a>), I thought doing a screenshot couldn&#8217;t be any harder. As it turned out, it was perhaps a bit more convoluted, and certainly quite different to doing such a thing on Windows. Nonetheless, the process is fairly straightforward once you have all the various pieces to fit together.</p>
<p>In essence, there are two problems to solve: taking the actual screenshot, and getting the image taken into a TBitmap. With respect to the second step, the general approach must be to write the image data to a memory stream, which can then be read by a TBitmap. This was the method I used in the clipboard case, though the specifics in the screenshot one are quite different.</p>
<p>To actually take a screenshot in the first place, the CGWindowListCreateImage API function can be used. This is part of the Core Graphics API layer, which like Core Foundation has a straight C interface which tries to be as object oriented as is reasonably possible, to the extent a purely procedural interface can be. As a result, what CGWindowListCreateImage returns is an opaque pointer (CGImageRef) to an object that needs releasing after we&#8217;ve done with it. Unfortunately, there is no CFImage &#8216;method&#8217; to directly extract the image bytes however: instead, we must create a CGDataConsumer object, to pass to CGImageDestination object, which should then have the CFImage &#8216;added&#8217; to it before being &#8216;finalised&#8217;. The last step will cause the bitmap bytes to be written to the data consumer, which we connect to a TMemoryStream via a procedural callback. Small mercies there&#8217;s no need to write a Cocoa-style delegate class too, eh?</p>
<p>To see this all in practice, create a new FireMonkey HD application, and add to the form a TButton and a suitable sized TImageControl. Caption the button &#8216;Take Screenshot&#8217;, then head for the form&#8217;s PAS file. Here, add the following as the implementation section&#8217;s uses clause:</p>
<p><pre class="brush: delphi;">
uses
  Macapi.CoreFoundation, Macapi.CocoaTypes, Macapi.CoreGraphics, Macapi.ImageIO;
</pre></p>
<p>First thing we&#8217;ll implement is the code to output the image data held by a CGImageRef to a TStream:</p>
<p><pre class="brush: delphi;">
function PutBytesCallback(Stream: TStream; NewBytes: Pointer;
  Count: LongInt): LongInt; cdecl;
begin
  Result := Stream.Write(NewBytes^, Count);
end;

procedure ReleaseConsumerCallback(Dummy: Pointer); cdecl;
begin
end;

procedure WriteCGImageToStream(const AImage: CGImageRef; AStream: TStream;
  const AType: string = 'public.png'; AOptions: CFDictionaryRef = nil);
var
  Callbacks: CGDataConsumerCallbacks;
  Consumer: CGDataConsumerRef;
  ImageDest: CGImageDestinationRef;
  TypeCF: CFStringRef;
begin
  Callbacks.putBytes := @PutBytesCallback;
  Callbacks.releaseConsumer := ReleaseConsumerCallback;
  ImageDest := nil;
  TypeCF := nil;
  Consumer := CGDataConsumerCreate(AStream, @Callbacks);
  if Consumer = nil then RaiseLastOSError;
  try
    TypeCF := CFStringCreateWithCharactersNoCopy(nil, PChar(AType), Length(AType),
      kCFAllocatorNull); //wrap the Delphi string in a CFString shell
    ImageDest := CGImageDestinationCreateWithDataConsumer(Consumer, TypeCF, 1, AOptions);
    if ImageDest = nil then RaiseLastOSError;
    CGImageDestinationAddImage(ImageDest, AImage, nil);
    if CGImageDestinationFinalize(ImageDest) = 0 then RaiseLastOSError;
  finally
    if ImageDest &lt;&gt; nil then CFRelease(ImageDest);
    if TypeCF &lt;&gt; nil then CFRelease(TypeCF);
    CGDataConsumerRelease(Consumer);
  end;
end;
</pre></p>
<p>When extracting image data, we need to request a specific graphic type via an appropriate &#8216;Uniform Type Identifier&#8217;. PNG is an appropriate default since it will definitely be available, and is lossless.</p>
<p>Now we need to implement the routine to actually take the screenshot:</p>
<p><pre class="brush: delphi;">
procedure TakeScreenshot(Dest: TBitmap);
var
  Screenshot: CGImageRef;
  Stream: TMemoryStream;
begin
  Stream := nil;
  ScreenShot := CGWindowListCreateImage(CGRectInfinite,
    kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageDefault);
  if ScreenShot = nil then RaiseLastOSError;
  try
    Stream := TMemoryStream.Create;
    WriteCGImageToStream(ScreenShot, Stream);
    Stream.Position := 0;
    Dest.LoadFromStream(Stream);
  finally
    CGImageRelease(ScreenShot);
    Stream.Free;
  end;
end;
</pre></p>
<p>As the number of arguments passed to CGWindowListCreateImage indicates, the API is quite flexible. We&#8217;ll just take a straight screenshot however.</p>
<p>If you now try to compile the code, you&#8217;ve find it barfs at CGRectInfinite &#8211; while all the functions and types we require are translated by the stock Macapi.* units, the CGRectInfinite constant is missing for some reason. So, add it like this:</p>
<p><pre class="brush: delphi;">
{$IF NOT DECLARED(CGRectInfinite)}
const
  CGRectInfinite: CGRect = (origin: (x: -8.98847e+30; y: -8.98847e+307);
    size: (width: 1.79769e+308; height: 1.79769e+308));
{$IFEND}
</pre></p>
<p>Lastly, handle the button&#8217;s OnClick event as the following, where imgDest is the name of the image control:</p>
<p><pre class="brush: delphi;">
procedure TfrmMacScreenshot.btnTakeScreenshotClick(Sender: TObject);
begin
  TakeScreenshot(imgDest.Bitmap);
end;
</pre></p>
<p>Run the application, and clicking the button should output a screenshot to the control:</p>
<p><a href="http://delphihaven.files.wordpress.com/2012/01/screenshot.jpg"><img class="aligncenter size-medium wp-image-1840" title="Screenshot" src="http://delphihaven.files.wordpress.com/2012/01/screenshot.jpg?w=300&#038;h=211" alt="" width="300" height="211" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1839/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1839&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2012/01/02/programmatically-taking-a-screenshot-on-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>

		<media:content url="http://delphihaven.files.wordpress.com/2012/01/screenshot.jpg?w=300" medium="image">
			<media:title type="html">Screenshot</media:title>
		</media:content>
	</item>
		<item>
		<title>Playing around with TVirtualMethodInterceptor</title>
		<link>http://delphihaven.wordpress.com/2011/12/18/playing-around-with-tvirtualmethodinterceptor/</link>
		<comments>http://delphihaven.wordpress.com/2011/12/18/playing-around-with-tvirtualmethodinterceptor/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 07:21:16 +0000</pubDate>
		<dc:creator>Chris Rolliston</dc:creator>
				<category><![CDATA[XE2]]></category>

		<guid isPermaLink="false">http://delphihaven.wordpress.com/?p=1826</guid>
		<description><![CDATA[Beyond bug fixes, one of the few things new to XE1 was TVirtualMethodInterceptor, a class for hooking virtual method calls made against an arbitrary object. Some months ago I had a quick try of it. Finding Barry Kelly&#8217;s example just a little too simple and abstract, I wrote my own &#8211; a (very) basic logger. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1826&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Beyond bug fixes, one of the few things new to XE1 was TVirtualMethodInterceptor, a class for hooking virtual method calls made against an arbitrary object. Some months ago I had a quick try of it. Finding <a href="http://blog.barrkel.com/2010/09/virtual-method-interception.html">Barry Kelly&#8217;s example</a> just a little too simple and abstract, I wrote my own &#8211; a (very) basic logger. The interface went like this:</p>
<p><pre class="brush: delphi;">
uses
  SysUtils, Classes, TypInfo, RTTI;

type
  IVirtualMethodLogger = interface
    procedure StopLogging(ObjectStillAlive: Boolean = True);
  end;

function LogVirtualMethodCalls(Obj: TObject; Output: TTextWriter;
  OwnOutput: Boolean = False): IVirtualMethodLogger; overload;
function LogVirtualMethodCalls(Obj: TObject; const LogFile: string;
  Append: Boolean = True): IVirtualMethodLogger; overload;
</pre></p>
<p>And the implementation like this:</p>
<p><pre class="brush: delphi;">
type
  TVirtualMethodLogger = class(TInterfacedObject, IVirtualMethodLogger)
  strict private
    FInterceptor: TVirtualMethodInterceptor;
    FObject: TObject;
    FOwnOutput: Boolean;
    FOutput: TTextWriter;
  public
    constructor Create(Obj: TObject; Output: TTextWriter;
      OwnOutput: Boolean);
    destructor Destroy; override;
    procedure StopLogging(ObjectStillAlive: Boolean = True);
  end;

constructor TVirtualMethodLogger.Create(Obj: TObject; Output: TTextWriter;
  OwnOutput: Boolean);
begin
  inherited Create;
  FObject := Obj;
  FOutput := Output;
  FOwnOutput := OwnOutput;
  FInterceptor := TVirtualMethodInterceptor.Create(Obj.ClassType);
  FInterceptor.OnBefore :=
    procedure(Instance: TObject; Method: TRttiMethod;
      const Args: TArray&lt;TValue&gt;; out DoInvoke: Boolean; out Result: TValue)
    begin
      Output.Write(DateTimeToStr(Now));
      Output.WriteLine(' %s.%s called with %d argument(s)',
        [Obj.ClassName, Method.Name, Length(Args)]);
    end;
  FInterceptor.OnException :=
    procedure(Instance: TObject; Method: TRttiMethod;
      const Args: TArray&lt;TValue&gt;; out RaiseException: Boolean;
      AException: Exception; out Result: TValue)
    begin
      Output.WriteLine('Exception raised (' + AException.ClassName +
        '): ' + AException.Message);
    end;
  FInterceptor.Proxify(Obj);
end;

destructor TVirtualMethodLogger.Destroy;
begin
  StopLogging;
  inherited Destroy;
end;

procedure TVirtualMethodLogger.StopLogging(ObjectStillAlive: Boolean = True);
begin
  if FInterceptor = nil then Exit;
  try
    if ObjectStillAlive then
    {$IF RTLVersion &gt;= 23}
      FInterceptor.Unproxify(FObject);
    {$ELSE}
      PPointer(FObject)^ := FInterceptor.OriginalClass;
    {$IFEND}
    FreeAndNil(FInterceptor);
    FOutput.Flush;
  finally
    if FOwnOutput then FOutput.Free;
  end;
end;

function LogVirtualMethodCalls(Obj: TObject; Output: TTextWriter;
  OwnOutput: Boolean = False): IVirtualMethodLogger;
begin
  Result := TVirtualMethodLogger.Create(Obj, Output, OwnOutput);
end;

function LogVirtualMethodCalls(Obj: TObject; const LogFile: string;
  Append: Boolean = True): IVirtualMethodLogger;
begin
  Result := TVirtualMethodLogger.Create(Obj, TStreamWriter.Create(LogFile, Append), True);
end;
</pre></p>
<p>The idea was then to use it with a VCL form:</p>
<p><pre class="brush: delphi;">
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, VMLog;

type
  TForm1 = class(TForm)
    btnShowMessage: TButton;
    btnRaiseException: TButton;
    procedure btnShowMessageClick(Sender: TObject);
    procedure btnRaiseExceptionClick(Sender: TObject);
  strict private
    FLogger: IVirtualMethodLogger;
  public
    constructor Create(AOwner: TComponent); override;
    procedure MsgProc; virtual;
    procedure BadProc; virtual;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TForm1.Create(AOwner: TComponent);
begin
  FLogger := LogVirtualMethodCalls(Self, ChangeFileExt(ParamStr(0), '.log'), False);
  inherited;
end;

procedure TForm1.MsgProc;
begin
  ShowMessage('Hello virtual method logging world');
end;

procedure TForm1.btnShowMessageClick(Sender: TObject);
begin
  MsgProc;
end;

procedure TForm1.BadProc;
begin
  raise EProgrammerNotFound.Create('Dozy, dozy...');
end;

procedure TForm1.btnRaiseExceptionClick(Sender: TObject);
begin
  BadProc;
end;
</pre></p>
<p>Unfortunately, this didn&#8217;t work as expected: the application just hung!</p>
<p>Motivated more recently to look at it again, I found the problem &#8211; the ordinary life of a VCL form involves frequent calls to virtual methods that have untyped parameters (in particular, DefaultHandler and Dispatch), and TVirtualMethodInterceptor doesn&#8217;t handle these properly. Since TVirtualMethodInterceptor already filters out various things, the easiest fix is just to have it filter out such methods too.</p>
<p>To do this, take a copy of Rtti.pas (XE1) or System.Rtti.pas (XE2), open it up, and add the following helper function immediately before the implementation for TVirtualMethodInterceptor.CreateProxyClass:</p>
<p><pre class="brush: delphi;">
function HasUntypedParameter(AMethod: TRttiMethod): Boolean;
var
  Param: TRttiParameter;
begin
  for Param in AMethod.GetParameters do
    if Param.ParamType = nil then Exit(True);
  Exit(False);
end;
</pre></p>
<p>Next, amend TVirtualMethodInterceptor.CreateProxyClass itself. Specifically, immediately after </p>
<p><pre class="brush: delphi;">
    if not m.HasExtendedInfo then
      Continue;
</pre></p>
<p>add</p>
<p><pre class="brush: delphi;">
    if HasUntypedParameter(m) then
      Continue;
</pre></p>
<p>This wil now allow the class to at least run when hooking a form. Nonetheless, you should keep in mind that my demo won&#8217;t actually log that much, even if you have the form do lots more things. This is due to TVirtualMethodInterceptor relying upon extended RTTI, and RTTI only being generated for public and published methods by default. Since virtual methods (especially in the VCL) tend to have protected visibility, TVirtualMethodInterceptor simply won&#8217;t be able to hook a good fair few.</p>
<p>PS: I&#8217;ve QCed the bug (see report no. <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=101873">101873</a>).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/delphihaven.wordpress.com/1826/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/delphihaven.wordpress.com/1826/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/delphihaven.wordpress.com/1826/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/delphihaven.wordpress.com/1826/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/delphihaven.wordpress.com/1826/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/delphihaven.wordpress.com/1826/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/delphihaven.wordpress.com/1826/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/delphihaven.wordpress.com/1826/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/delphihaven.wordpress.com/1826/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/delphihaven.wordpress.com/1826/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/delphihaven.wordpress.com/1826/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/delphihaven.wordpress.com/1826/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/delphihaven.wordpress.com/1826/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/delphihaven.wordpress.com/1826/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=delphihaven.wordpress.com&amp;blog=7665935&amp;post=1826&amp;subd=delphihaven&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://delphihaven.wordpress.com/2011/12/18/playing-around-with-tvirtualmethodinterceptor/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ba053e37e0fc166ee8dc393c18abc384?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">CR</media:title>
		</media:content>
	</item>
	</channel>
</rss>
