<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3339459875755088113</id><updated>2011-11-27T16:48:28.264-07:00</updated><category term='CodeRage'/><category term='Personal Outlook'/><category term='Delphi'/><category term='Mac'/><category term='About Rob'/><category term='RTTI'/><category term='XML'/><category term='SLCDUG'/><category term='DelphiLive'/><category term='VDUG'/><category term='Component Development'/><category term='Packages'/><category term='DBX'/><category term='Quality'/><title type='text'>Rob’s Technology Corner</title><subtitle type='html'>My blog typically about Delphi Programming.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-2284062423777763461</id><published>2011-09-23T08:17:00.000-06:00</published><updated>2011-09-23T08:23:49.486-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeRage'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>See you at CodeRage</title><content type='html'>I have never seen so many Delphi Events as we are seeing right now. &lt;br /&gt;&lt;br /&gt;There is&amp;nbsp;definitely&amp;nbsp;a buzz regarding the new &lt;a href="http://www.embarcadero.com/products/delphi"&gt;Delphi XE2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.delphilive.com/"&gt;DelphiLive&lt;/a&gt;&amp;nbsp;in San Jose&amp;nbsp;has completed and it was a great event. &lt;br /&gt;&lt;br /&gt;Half the&amp;nbsp;&lt;a href="http://www.embarcadero.com/world-tour"&gt;Delphi World Tour&lt;/a&gt;&amp;nbsp;dates have past, with a several more to go.&lt;br /&gt;In Utah the Delphi World Tour represented one of the largest &amp;nbsp;Delphi Event in Years.&lt;br /&gt;&lt;br /&gt;Next Up is &lt;a href="http://www.embarcadero.com/coderage"&gt;CodeRage&lt;/a&gt;&amp;nbsp; Oct 17-21, 2011. &amp;nbsp; &amp;nbsp;It a FREE, virtual conference. &amp;nbsp; &amp;nbsp; For those who are confused about the idea of a virtual conference.... think of of it as 50 back to back webinars in 5 Days. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;My team goes to training room with loads of junk food. &amp;nbsp; &amp;nbsp;Where we discuss the sessions as they occur. &amp;nbsp; &amp;nbsp; &amp;nbsp;It really for good team building. &lt;br /&gt;&lt;br /&gt;I will be sharing 4 sessions at CodeRage this year. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Learning Magic Tricks: The Beginners Guide to RTTI&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Learn what RTTI is and how to use it. This session is designed for those that have heard of RTTI, but don't know where to start.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Practical Magic: Why would I use Delphi RTTI?&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Attendees are shown several practical examples of how the RTTI in Delphi works.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Magic Unleashed: A Deep Dive into the Delphi RTTI&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;In this session, we pull back the covers and explore the internals of how RTTI.pas and TypInfo.pas work inside of Delphi exposing all of the RTTI options you have to use in your applications.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Exploring the Delphi Debugger&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;This session explores how to use the Delphi Debugger to find those difficult to find problems. We explore the little known features of the debugger that can make your life easier when real problems arise.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;All of the RTTI sessions are back to back, allowing for Q/A after each. &amp;nbsp; &amp;nbsp;With three sessions I will be able to provide more information than I have ever been able to do before.&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-2284062423777763461?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/2284062423777763461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/09/see-you-at-coderage.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2284062423777763461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2284062423777763461'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/09/see-you-at-coderage.html' title='See you at CodeRage'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-385072395962321626</id><published>2011-09-06T15:36:00.000-06:00</published><updated>2011-09-06T15:36:14.092-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>XE2 and Registration Headaches.</title><content type='html'>&lt;div&gt;Today&amp;nbsp;I hit the registration limit on XE2.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I installed it on the following machines.&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Laptop (Primary for DelphiLive Presentation)&lt;/li&gt;&lt;li&gt;Laptop (Backup for DelphiLive Presentation)&lt;/li&gt;&lt;li&gt;Desktop (Home)&lt;/li&gt;&lt;li&gt;MacMini, Windows VM&lt;/li&gt;&lt;li&gt;Desktop &amp;nbsp;(Work)&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Registered in in that order. &amp;nbsp; I ran in to the registration Limit with #5. &amp;nbsp; &amp;nbsp;I am the only person who uses these machines.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I think no big deal, I will request a&amp;nbsp;registration&amp;nbsp;limit increase. &amp;nbsp; &amp;nbsp;I requested the increase and walked away from my machine for meeting. &amp;nbsp; &amp;nbsp; Thinking I can wait 14 days to register no big deal.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then I did the following.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1. File|New VCL Application&lt;/div&gt;&lt;div&gt;2. Ctrl-F9&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then the following dialog appears.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-UazZB3-kBQY/TmaNi8svCzI/AAAAAAAAUvA/zbFZXeA-fTs/s1600/NotLicensed.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-UazZB3-kBQY/TmaNi8svCzI/AAAAAAAAUvA/zbFZXeA-fTs/s1600/NotLicensed.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have never been a fan of activation, but I have not been against it... Until Now!&lt;/div&gt;&lt;div&gt;Now that I can see that the 14 day grace does not just cripple the application on&amp;nbsp;start-up, it annoys the developer and reduces&amp;nbsp;their&amp;nbsp;productivity.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The good news is that support did respond and the activation limit has been increased. &amp;nbsp; &amp;nbsp; But this is just a headache that paying customers should not have to deal with. &amp;nbsp; &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-385072395962321626?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/385072395962321626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/09/xe2-and-registration-headaches.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/385072395962321626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/385072395962321626'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/09/xe2-and-registration-headaches.html' title='XE2 and Registration Headaches.'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-UazZB3-kBQY/TmaNi8svCzI/AAAAAAAAUvA/zbFZXeA-fTs/s72-c/NotLicensed.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-2592680541294666355</id><published>2011-08-25T22:41:00.001-06:00</published><updated>2011-08-26T00:08:07.326-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac'/><title type='text'>New Mac and Rad Studio XE2</title><content type='html'>&lt;i&gt;Note: I was given permission to blog about the Rad Studio XE2 Beta.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Today my first &lt;a href="http://www.apple.com/macosx/"&gt;Mac OSX&lt;/a&gt; computer arrived at my home. &amp;nbsp; I have only used a Mac when working&lt;br /&gt;on Sound and Lights at &lt;a href="http://www.centerpointtheatre.org/"&gt;local theatre&lt;/a&gt;. &amp;nbsp; I have spent about 10 hours total time working on a Mac in the last 10 years.   So I would guess this as close to a new user experience as one my expect.&lt;br /&gt;&lt;br /&gt;The primary reason I bought the Mac is because &lt;a href="http://www.embarcadero.com/world-tour"&gt;Rad Studio XE2&lt;/a&gt; supports writing applications for this platform. &amp;nbsp; &amp;nbsp;I like to make sure I stay on top of the various Delphi technologies so I had to buy one. &lt;br /&gt;&lt;br /&gt;I opened the box and hooked up the various cables. &amp;nbsp; &amp;nbsp;Turned it on and I saw a little diagram asking me to turn on my touch pad or mouse. &amp;nbsp; Well I turned on the touch pad and nothing happened. &amp;nbsp; After trying various combinations&amp;nbsp;I gave up and called support. &amp;nbsp; After having to power of the Mac twice we were able to get the wireless keyboard and mouse to work. &amp;nbsp; &amp;nbsp; &amp;nbsp;Things were not going well, and I was a bit worried I had made a mistake but things turned around.&lt;br /&gt;&lt;br /&gt;I had installed the latest Rad Studio XE2 Beta version on my home computer, which is a Windows 7 machine. &amp;nbsp; &lt;br /&gt;Then I performed the following steps:&lt;br /&gt;1. File|New Firemonkey HD Application.&lt;br /&gt;2. I then right Clicked on Target platform and added OSx&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-OoyQU1_c__s/TlcbcPqdvTI/AAAAAAAAUug/yd43N4OxZ5o/s1600/TargetPlatform.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-OoyQU1_c__s/TlcbcPqdvTI/AAAAAAAAUug/yd43N4OxZ5o/s1600/TargetPlatform.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;I knew I had to install something on the Mac but I did not know where it was or how to do it.&lt;br /&gt;I opened the Help file and found it had a Huge amount of information that pointed me in the right direction.&lt;br /&gt;From the little I did read I was very very pleased with the depth of coverage.&lt;br /&gt;&lt;br /&gt;3. I Installed the Platform Assistant on the Mac according to the instructions.&lt;br /&gt;4. I launched the platform&amp;nbsp;assistant&amp;nbsp;clicking on the "paserver.command" in &lt;br /&gt;"Developer" section of finder.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-4O-gN7-cE1I/TlcbvlCsNqI/AAAAAAAAUuk/AIgh-rO9ezA/s1600/PALaunch.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-4O-gN7-cE1I/TlcbvlCsNqI/AAAAAAAAUuk/AIgh-rO9ezA/s1600/PALaunch.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-HfCVYBlGV8A/Tlcb1a5QdpI/AAAAAAAAUuo/KkZK-Ath29I/s1600/PARunning.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-HfCVYBlGV8A/Tlcb1a5QdpI/AAAAAAAAUuo/KkZK-Ath29I/s1600/PARunning.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;5. Then in back in Delphi, I right clicked on the "OS X" Target Platform and selected "Assign Remote Profile"&lt;br /&gt;6. On the "Select Remote Profile for 'OS X' Platform" dialog I pressed "Add..."&lt;br /&gt;7. I walked through the Wizard and Added Information about my Mac.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-8GaK1hYOR4I/Tlcb9RgWm1I/AAAAAAAAUus/BquvmLGiVOs/s1600/ProfileWizard1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-8GaK1hYOR4I/Tlcb9RgWm1I/AAAAAAAAUus/BquvmLGiVOs/s1600/ProfileWizard1.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-DBUN5uvweiE/TlccFaxP7yI/AAAAAAAAUuw/kF2hdHeJSOQ/s1600/ProfileWizard2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-DBUN5uvweiE/TlccFaxP7yI/AAAAAAAAUuw/kF2hdHeJSOQ/s1600/ProfileWizard2.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;8. &amp;nbsp;Then finally I selected the new profile that was created.&lt;br /&gt;9. &amp;nbsp;I then pressed the run button.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-eJpuATDhjjQ/TlcdVMWRqNI/AAAAAAAAUu4/AFJSosoWnK4/s1600/RunningApp.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-eJpuATDhjjQ/TlcdVMWRqNI/AAAAAAAAUu4/AFJSosoWnK4/s1600/RunningApp.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The application appeared on the Mac as expected. &lt;br /&gt;&lt;br /&gt;I must say the out of the box experience with Delphi and the Mac looks very polished, it was very easy to setup. &amp;nbsp;I spent more time trying to get the wireless mouse and keyboard to work than getting Rad Studio configured and my first App running.&lt;br /&gt;&lt;br /&gt;Now that I have a basic app running it's time to really explore how FireMonkey integrates will both Windows and OS X.&lt;br /&gt;&lt;br /&gt;For more information check out the &lt;a href="http://www.embarcadero.com/world-tour"&gt;Rad Studio XE World Tour&lt;/a&gt; or the &lt;a href="http://www.delphilive.com/"&gt;Delphi Live&lt;/a&gt; conference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-2592680541294666355?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/2592680541294666355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/08/new-mac-and-rad-studio-xe2.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2592680541294666355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2592680541294666355'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/08/new-mac-and-rad-studio-xe2.html' title='New Mac and Rad Studio XE2'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-OoyQU1_c__s/TlcbcPqdvTI/AAAAAAAAUug/yd43N4OxZ5o/s72-c/TargetPlatform.jpg' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-3783432373171531640</id><published>2011-06-15T00:15:00.000-06:00</published><updated>2011-06-15T12:13:41.127-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>THtmlWriter - First Look</title><content type='html'>I wanted my build process to automatically generate a web page with what was changed in the given build. &amp;nbsp; Basically I had to query our Internal Bug Tracking system and produce a web page.&amp;nbsp;Allowing me to take a&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;snapshot of bug tracking system as it looked liked when the build was produced.&lt;/div&gt;&lt;br /&gt;This was going to be a simple console application that our build could run. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;So I&amp;nbsp;decided&amp;nbsp;to try&amp;nbsp;&lt;a href="http://code.google.com/p/delphihtmlwriter/"&gt;THtmlWriter&lt;/a&gt;&amp;nbsp;written by&amp;nbsp;&lt;a href="http://www.nickhodges.com/"&gt;Nick Hodges&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;I spent more time reviewing the code of&amp;nbsp;&lt;a href="http://code.google.com/p/delphihtmlwriter/"&gt;THtmlWriter&lt;/a&gt;&amp;nbsp;than I did actually using it.&lt;br /&gt;&lt;br /&gt;It was very easy to use, and will most likely use it in future&lt;br /&gt;&lt;br /&gt;If you need to produce HTML from Delphi application it's worth looking at this.&lt;br /&gt;&lt;br /&gt;So here is my&amp;nbsp;+1 Vote for&amp;nbsp;&lt;a href="http://code.google.com/p/delphihtmlwriter/"&gt;THtmlWriter&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-3783432373171531640?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/3783432373171531640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/06/i-wanted-my-build-process-to.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3783432373171531640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3783432373171531640'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/06/i-wanted-my-build-process-to.html' title='THtmlWriter - First Look'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-5507564981374530593</id><published>2011-06-07T12:34:00.000-06:00</published><updated>2011-06-07T12:34:53.103-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Component Development'/><title type='text'>Application -vs- Component Developer</title><content type='html'>During Interviews I have &amp;nbsp;heard the following from candidates. &lt;br /&gt;"I am Application developer, I use components, I don't build them."&lt;br /&gt;&lt;br /&gt;I typically have thought well I have found another "point and click" developer who is not familiar with OOP. &amp;nbsp; Since I have been at my component no&amp;nbsp;candidate&amp;nbsp;who has said this has been hired.&lt;br /&gt;&lt;br /&gt;Recently I ran into an exception (outside of an Interview) a Delphi Developer who was very familiar with OOP but had still not built a component.    I realized that there an artificial barrier into component development, that many might see. &amp;nbsp; &amp;nbsp;In a future blog postI will confront this&amp;nbsp;artificial barrier head on and show how easy it is to do component&amp;nbsp;development. &amp;nbsp;This&amp;nbsp;post is show some of the arguments of why we would want to do component development as an application developer.&lt;br /&gt;&lt;br /&gt;In 2007 we converted our application from BDE to DBX.    We had written an &lt;a href="http://robstechcorner.blogspot.com/2009/09/coderage-iv-bde-to-dbx.html"&gt;application that converted&lt;/a&gt; all TQuery components to &lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/presentations/DelphiLive/DBX/Components/dbxQuery.pas"&gt;TDbxQuery&lt;/a&gt; components. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;The process of conversion to the 3 component model of DBX (TSqlQuery -&amp;gt; TProvider -&amp;gt; TClientDataset) was going to be error prone. &amp;nbsp; It was also going to take an insane amount of time that we were not willing to spend.&lt;br /&gt;&lt;br /&gt;So we spent a few days creating a component that looked like and behaved like TQuery but internally used the 3 Component DBX model. &amp;nbsp;It was similar to TSimpleDateset but had properties and functions that matched existing &amp;nbsp;TQuery&amp;nbsp;functionality&amp;nbsp;that we used. &amp;nbsp;This allowed for a search and replace of instances of TQuery with TdbxQuery. &amp;nbsp; This allowed us to complete this conversion in less time that if we had just used the built in components. &amp;nbsp; &amp;nbsp; Since we maintained the component we were able to expose any functionality of the 3 components model that we needed.&lt;br /&gt;&lt;br /&gt;During this process we realized we had hundreds of &amp;nbsp;TDBGrid components. &amp;nbsp; &amp;nbsp; So we decided to help our application for the long term. &amp;nbsp; We replaced TDBGrid with TDwsGrid. &amp;nbsp; &amp;nbsp;Initially&amp;nbsp;the code looked something like this. &amp;nbsp; &amp;nbsp;It basically offered nothing over TDbGrid.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;TDwsGrid = class(TCustomDBGrid)&lt;br /&gt;   published&lt;br /&gt;    property Align;&lt;br /&gt;    property Anchors;&lt;br /&gt;    property BiDiMode;&lt;br /&gt;    property BorderStyle;&lt;br /&gt;    property Color;&lt;br /&gt;    property Columns stored False; &lt;br /&gt;    property Constraints;&lt;br /&gt;    property Ctl3D;&lt;br /&gt;    property DataSource;&lt;br /&gt;    property DefaultDrawing;&lt;br /&gt;    property DragCursor;&lt;br /&gt;    property DragKind;&lt;br /&gt;    property DragMode;&lt;br /&gt;    property Enabled;&lt;br /&gt;    property FixedColor;&lt;br /&gt;    property Font;&lt;br /&gt;    property ImeMode;&lt;br /&gt;    property ImeName;&lt;br /&gt;    property Options;&lt;br /&gt;    property ParentBiDiMode;&lt;br /&gt;    property ParentColor;&lt;br /&gt;    property ParentCtl3D;&lt;br /&gt;    property ParentFont;&lt;br /&gt;    property ParentShowHint;&lt;br /&gt;    property PopupMenu;&lt;br /&gt;    property ReadOnly;&lt;br /&gt;    property ShowHint;&lt;br /&gt;    property TabOrder;&lt;br /&gt;    property TabStop;&lt;br /&gt;    property TitleFont;&lt;br /&gt;    property Visible;&lt;br /&gt;    property OnCellClick;&lt;br /&gt;    property OnColEnter;&lt;br /&gt;    property OnColExit;&lt;br /&gt;    property OnColumnMoved;&lt;br /&gt;    property OnDrawColumnCell;&lt;br /&gt;    property OnDblClick;&lt;br /&gt;    property OnDragDrop;&lt;br /&gt;    property OnDragOver;&lt;br /&gt;    property OnEditButtonClick;&lt;br /&gt;    property OnEndDock;&lt;br /&gt;    property OnEndDrag;&lt;br /&gt;    property OnEnter;&lt;br /&gt;    property OnExit;&lt;br /&gt;    property OnKeyDown;&lt;br /&gt;    property OnKeyPress;&lt;br /&gt;    property OnKeyUp;&lt;br /&gt;    property OnMouseActivate;&lt;br /&gt;    property OnMouseDown;&lt;br /&gt;    property OnMouseEnter;&lt;br /&gt;    property OnMouseLeave;&lt;br /&gt;    property OnMouseMove;&lt;br /&gt;    property OnMouseUp;&lt;br /&gt;    property OnMouseWheel;&lt;br /&gt;    property OnMouseWheelDown;&lt;br /&gt;    property OnMouseWheelUp;&lt;br /&gt;    property OnStartDock;&lt;br /&gt;    property OnStartDrag;&lt;br /&gt;    property OnTitleClick;&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The other day I had a look at this component, it now does the following.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sorts the Grid based on Click of column Title&lt;/li&gt;&lt;li&gt;Persists Column positions and sizing to a configuration file.&lt;/li&gt;&lt;li&gt;Ability to Export to Excel.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;It's not a huge amount functionality but it allowed us to add this to many screens without how having to place this code to do this in every place we used TDbGrid. &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When explaining this to application only developer one might expect a response of. &amp;nbsp;"Well why not buy a 3rd party control that does that?" &amp;nbsp;&amp;nbsp;My answer &amp;nbsp;"We did just that, when we had the budget we purchased a &lt;a href="http://www.tmssoftware.com/site/vdsub.asp"&gt;TMS Subscription&lt;/a&gt; and now use &lt;a href="http://www.tmssoftware.com/site/dbadvgrd.asp"&gt;TDBAdvGrid&lt;/a&gt; in many places." &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But the experience previously learned still applied to 3rd party component packages. &amp;nbsp; We now are in the processed of &amp;nbsp;creating, our new component which now looks like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush:delphi"&gt;TdwsAdvDbGrid = class(TAdvDBGrid)&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Allowing us to add additional functionality to TAdvDBGrid if we need it. &amp;nbsp; Granted for now we don't need to add anything. &amp;nbsp; But the lesson learned from the previous experience has shown the value.&lt;br /&gt;&lt;br /&gt;This does not just apply to additional functionality, it also applies to common custom settings.&lt;br /&gt;Say for example every time you use a TEdit you need to change the Font to comply with a standard&lt;br /&gt;you have set. &amp;nbsp; Instead of doing the tedious mistake ridden work of doing this. &amp;nbsp; Instead create a TMyEdit then use that instead of TEdit. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Classes, Controls, StdCtrls;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TMyEdit = class(TEdit)&lt;br /&gt;  public&lt;br /&gt;    constructor Create(AOwner : TComponent); override;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;procedure Register;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;{ TMyEdit }&lt;br /&gt;&lt;br /&gt;constructor TMyEdit.Create(AOwner: TComponent);&lt;br /&gt;begin&lt;br /&gt;  inherited;&lt;br /&gt;  Font.Name := 'My Crazy Font';&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So basically&amp;nbsp;a developer should be able to do both, application and component development. &amp;nbsp; &amp;nbsp;Taking the time to learn component development will only help you in your your abilities to create great applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-5507564981374530593?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/5507564981374530593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/06/application-vs-component-developer.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5507564981374530593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5507564981374530593'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/06/application-vs-component-developer.html' title='Application -vs- Component Developer'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-5026027154987229859</id><published>2011-06-02T19:34:00.004-06:00</published><updated>2011-06-07T12:37:16.811-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Component Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Packages'/><title type='text'>Runtime/Designtime what?  Delphi Packages</title><content type='html'>To most Delphi developers a package is typically where you would place components so that you can drop them on your forms.&lt;br /&gt;&lt;br /&gt;So one might assume that a 3rd Party Component developer would know how packages work. &amp;nbsp; &amp;nbsp;Well over the years I have seen several of these developers make basic mistakes when it comes to Delphi packages.&lt;br /&gt;&lt;br /&gt;The application I work on is built with runtime packages. &amp;nbsp;We currently have to deploy&amp;nbsp;208 packages. &lt;br /&gt;Management of Packages and having the built correctly is paramount for us. &amp;nbsp; &amp;nbsp;Not all packages involve components, but the most common mistakes happen at that level.&lt;br /&gt;&lt;br /&gt;This blog post is my attempt to help developers understand one area of packages, that I typically see mistakes. &lt;br /&gt;&lt;br /&gt;A package is just a collection of units that are complied together into a BPL.&lt;br /&gt;&lt;br /&gt;Here is the package sources for brand new package with a single unit.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;package Package2;             &lt;br /&gt;&lt;br /&gt;{$R *.res}&lt;br /&gt;{$ALIGN 8}&lt;br /&gt;{$ASSERTIONS ON}&lt;br /&gt;{$BOOLEVAL OFF}&lt;br /&gt;{$DEBUGINFO ON}&lt;br /&gt;{$EXTENDEDSYNTAX ON}&lt;br /&gt;{$IMPORTEDDATA ON}&lt;br /&gt;{$IOCHECKS ON}&lt;br /&gt;{$LOCALSYMBOLS ON}&lt;br /&gt;{$LONGSTRINGS ON}&lt;br /&gt;{$OPENSTRINGS ON}&lt;br /&gt;{$OPTIMIZATION ON}&lt;br /&gt;{$OVERFLOWCHECKS OFF}&lt;br /&gt;{$RANGECHECKS OFF}&lt;br /&gt;{$REFERENCEINFO ON}&lt;br /&gt;{$SAFEDIVIDE OFF}&lt;br /&gt;{$STACKFRAMES OFF}&lt;br /&gt;{$TYPEDADDRESS OFF}&lt;br /&gt;{$VARSTRINGCHECKS ON}&lt;br /&gt;{$WRITEABLECONST OFF}&lt;br /&gt;{$MINENUMSIZE 1}&lt;br /&gt;{$IMAGEBASE $400000}&lt;br /&gt;{$IMPLICITBUILD ON}&lt;br /&gt;&lt;br /&gt;requires&lt;br /&gt;  rtl;&lt;br /&gt;&lt;br /&gt;contains&lt;br /&gt;  Unit13 in 'Unit13.pas';&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There are two key sections &lt;b&gt;requires&lt;/b&gt; and &lt;b&gt;contains&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;Contains is the list of units that your package contains. &amp;nbsp;&amp;nbsp; &amp;nbsp;Requires is the list of other packages your package needs &amp;nbsp;to compile. &amp;nbsp; For example say you have a &amp;nbsp;&lt;b&gt;pkgBaseBall.bpl&lt;/b&gt; that contains a unit called &lt;b&gt;baseball.pas.&lt;/b&gt;&lt;br /&gt;Then you create a new packages called &lt;b&gt;pkgSports.bpl&lt;/b&gt;&amp;nbsp;that contains a unit called &lt;b&gt;sports.pas &lt;/b&gt;which listed &lt;b&gt;baseball.pas&lt;/b&gt; in it's uses clause. &amp;nbsp; &amp;nbsp;You will need to add &lt;b&gt;pkgBaseBall &lt;/b&gt;to the requires clause the package named &lt;b&gt;pkgSports.bpl&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Key Files involved in package development.&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;*.DPROJ - &lt;/b&gt;XML File in MSBUILD format that contains project options and files.&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;*&lt;/b&gt;&lt;/span&gt;.DPK&lt;/b&gt; - Main source code of the package. &amp;nbsp; (It's the code listed above)&lt;/li&gt;&lt;li&gt;&lt;b&gt;*.BPL &lt;/b&gt;- Compiled Binary&amp;nbsp;&lt;/li&gt;&lt;li&gt;*.&lt;b&gt;DCP &lt;/b&gt;- Delphi Compiled Package, contains information about he interface section of the contained units.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-Ixo0qOqqyjE/TegjbUcROBI/AAAAAAAAUsU/n2sOYiNBXfw/s1600/PackageOptions.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="222" src="http://1.bp.blogspot.com/-Ixo0qOqqyjE/TegjbUcROBI/AAAAAAAAUsU/n2sOYiNBXfw/s320/PackageOptions.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Package Types&lt;/b&gt;&lt;br /&gt;There are 3 basic types of &amp;nbsp;Packages.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Designtime only&lt;/li&gt;&lt;li&gt;Runtime only&lt;/li&gt;&lt;li&gt;Designtime and runtime&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-AwiI95DmBsA/Td56adBlJhI/AAAAAAAAUsE/iHGHDP67kmo/s1600/Project+Options.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="254" src="http://4.bp.blogspot.com/-AwiI95DmBsA/Td56adBlJhI/AAAAAAAAUsE/iHGHDP67kmo/s320/Project+Options.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;Runtime Packages&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;When creating a Delphi you have the option to build with runtime packages. &amp;nbsp; This option is found in the project options.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;If you build with packages you must distribute the packages (.BPL files) your application uses.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;strong style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-size: 14px; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Most Delphi application that I have seen are build without runtime packages. &amp;nbsp; &amp;nbsp;Typically these developers tend to not realize the impact bad&amp;nbsp;package design can cause on application that uses runtime packages.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;When building with runtime packages the list of package you must distribute is semi-colon delimited list next to the check box for Build with run time packages in the project options. &amp;nbsp; &amp;nbsp; The only files you need to&amp;nbsp;distribute&amp;nbsp;for applications build with runtime packages is the BPLs. &amp;nbsp; &amp;nbsp;The other key package files do not need to be distributed.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Runtime packages should never &lt;b&gt;contain &lt;/b&gt;or &lt;b&gt;require &lt;/b&gt;designtime code.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;b&gt;Designtime Packages&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Designtime packages are where you place your design time code. &amp;nbsp; This includes&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Property Editors&lt;/span&gt;&lt;/li&gt;&lt;li style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Component Editors&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Open Tool Experts&lt;/span&gt;&lt;/li&gt;&lt;li style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;References to other packages that are design time.&lt;/span&gt;&lt;/li&gt;&lt;li style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Component Registration "i.e. the Register method."&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Designtime packages should never &lt;b&gt;contain &lt;/b&gt;runtime code.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;b&gt;Designtime and Runtime&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;This is the lazy developer package. &amp;nbsp; I don't want to create and maintain two packages, so I will just use one.&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;This seems easy at first, but if not done carefully it leads to the most common mistake I run into. &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Then write some code&amp;nbsp;&amp;nbsp;that &lt;b&gt;requires &lt;/b&gt;a designtime only package. &amp;nbsp; &amp;nbsp;This in effect makes&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;your package &lt;/span&gt;designtime&lt;span class="Apple-style-span" style="font-size: 14px;"&gt; only regardless of your package type selection. &amp;nbsp; &amp;nbsp; &amp;nbsp;It's easy to do any property or component editor will &lt;/span&gt;&lt;b style="font-size: 14px;"&gt;require &lt;/b&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;DesignIDE which is design time package that you can't&amp;nbsp;distribute.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;b&gt;The Rules&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;The summary version of common mistakes.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;"&lt;i&gt;Runtime&lt;/i&gt;" Packages should never &lt;b&gt;contain&lt;/b&gt; Design time Code&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;"&lt;i&gt;Designtime&lt;/i&gt;" Packages should never &lt;b&gt;contain&lt;/b&gt; Runtime Code.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;"&lt;i&gt;Designtime and Runtime&lt;/i&gt;" Packages should never &lt;b&gt;Require&lt;/b&gt; "&lt;i&gt;Designtime&lt;/i&gt;" &amp;nbsp;Packages. &amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;"&lt;i&gt;Runtime&lt;/i&gt;" Packages should never &lt;b&gt;Require&lt;/b&gt; "&lt;i&gt;Designtime&lt;/i&gt;" &amp;nbsp;Packages. &amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Avoid "&lt;i&gt;Runtime&lt;/i&gt;" Packages that &amp;nbsp;&lt;b&gt;require&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;"&lt;i&gt;Designtime and Runtime&lt;/i&gt;" Packages&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;Avoid the use of "&lt;i&gt;Designtime and Runtime&lt;/i&gt;" Packages.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Why do I care?&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;If an application builds with runtime packages, and someone screws this up you will find that application requiring deployment of design time packages to work. If you do deploy the runtime package, you may run into a a runtime error&amp;nbsp;"Application is not licensed to use this feature" &amp;nbsp;This is because your using files that you should&amp;nbsp;not be&amp;nbsp;distributing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-5026027154987229859?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/5026027154987229859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/06/runtimedesigntime-what-delphi-packages.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5026027154987229859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5026027154987229859'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/06/runtimedesigntime-what-delphi-packages.html' title='Runtime/Designtime what?  Delphi Packages'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-Ixo0qOqqyjE/TegjbUcROBI/AAAAAAAAUsU/n2sOYiNBXfw/s72-c/PackageOptions.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-8349619900084368697</id><published>2011-05-31T08:29:00.002-06:00</published><updated>2011-05-31T09:48:27.013-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Quality'/><title type='text'>Find Text in Delphi - Evolution of a Feature</title><content type='html'>Every application goes through evolution, where a feature is completely rewritten to be better. &lt;br /&gt;&lt;br /&gt;Understanding how a given Feature is used is important before undertaking the rewrite, to know how your going to impact your user base. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;The case I am going to point out today is the difference between the Delphi 2007 and XE find text mechanism. &amp;nbsp; &amp;nbsp;The XE version changes are frustrating at best. &amp;nbsp; &amp;nbsp;Do see what I am talking about&lt;br /&gt;do the following in both IDE's.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;File| New VCL Application&lt;/li&gt;&lt;li&gt;File| New Form &amp;nbsp;(So you have two blank forms open)&lt;/li&gt;&lt;li&gt;Navigate to the code of one of the forms&lt;/li&gt;&lt;li&gt;Ctrl-Home (Move to top of unit)&lt;/li&gt;&lt;li&gt;Ctrl-F &amp;nbsp;(Delphi 2007 Dialog - Delphi XE it's at the bottom)&lt;/li&gt;&lt;li&gt;Enter "Form" as the search word&amp;nbsp;&lt;/li&gt;&lt;li&gt;Press Enter (First Match is found in uses)&lt;/li&gt;&lt;li&gt;Press F3 (Second Match Found)&lt;/li&gt;&lt;li&gt;Press Ctrl-Home (Go back to top of document)&lt;/li&gt;&lt;li&gt;Steps change from here on out....&lt;/li&gt;&lt;li&gt;Delphi 2007&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Press F3 (Finds First Match Again)&lt;/li&gt;&lt;li&gt;Change to second unit's source code&lt;/li&gt;&lt;li&gt;Ctrl-Home&lt;/li&gt;&lt;li&gt;Press F3 (Finds First Match in 2nd Unit)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Delphi XE&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Press F3 (Nothing happens, Argh the search window says "Form" nothing is found. &lt;a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=80696"&gt;QC: 80696&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Ctrl-F &amp;nbsp;( Text changes to "Unit" &lt;a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=92388"&gt;QC: 92388&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Retype : "Form"&amp;nbsp;&lt;/li&gt;&lt;li&gt;Press Enter&lt;/li&gt;&lt;li&gt;Change to second unit's source code&lt;/li&gt;&lt;li&gt;Ctrl-Home&lt;/li&gt;&lt;li&gt;Press F3&amp;nbsp;(Nothing happens , Argh. &amp;nbsp; Note: The search window at bottom is not visible)&lt;/li&gt;&lt;li&gt;Ctrl-F&amp;nbsp;( Text shows "Unit" )&lt;/li&gt;&lt;li&gt;Retype : "Form"&amp;nbsp;&lt;/li&gt;&lt;li&gt;Press Enter&amp;nbsp;(Finds First Match in 2nd Unit)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Update:&lt;/b&gt; &amp;nbsp;If I restart Delphi and the Press F3 and nothing happens step works. &amp;nbsp; &amp;nbsp;Something is causing it to break just don't know what it is.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's also bad if you search on a term don't find it and want to use the Find in Files functionality. &amp;nbsp; But, I think &amp;nbsp;I made my point with the steps above.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have heard the arguments about the new find method being better. &amp;nbsp; &amp;nbsp;Personally I could care less if it's a dialog or at the bottom of the form. &amp;nbsp; &amp;nbsp;The new method is even entered it as bug in QC: &lt;a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=80695"&gt;80695&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;What I do care about, is that the functionality works for me and not against me. &amp;nbsp; &amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;So as evolution occurs in your application, take a moment to realize the use case scenario of the existing&amp;nbsp;functionality. &amp;nbsp; That way you impact your users for the better and not for the worse.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-8349619900084368697?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/8349619900084368697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/05/find-text-in-delphi-evolution-of.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8349619900084368697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8349619900084368697'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/05/find-text-in-delphi-evolution-of.html' title='Find Text in Delphi - Evolution of a Feature'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-480912054331142972</id><published>2011-05-14T19:21:00.001-06:00</published><updated>2011-05-14T19:22:55.310-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Quality'/><title type='text'>The Joel Test The Evolution of a Team.</title><content type='html'>Every place I have worked has had a different staff hiring and/or contractor selection process. &amp;nbsp; &amp;nbsp; &amp;nbsp; When I started working with my current employer the process was simple. &amp;nbsp; Come in for one interview, after reviewing the resumes, and a brief conversation with each&amp;nbsp;candidate a decision was made.&lt;br /&gt;&lt;br /&gt;A bit later I became the one in charge of doing the hiring. &amp;nbsp; &amp;nbsp; I followed the same basic model for awhile, then I was bitten. &amp;nbsp; &amp;nbsp;I had a few bad apples. &amp;nbsp; &amp;nbsp; &amp;nbsp;I then read &amp;nbsp;&lt;a href="http://www.amazon.com/gp/product/1590598385/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=1590598385"&gt;Smart and Gets Things Done: Joel Spolsky's Concise Guide to Finding the Best Technical Talent&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1590598385&amp;amp;camp=217145&amp;amp;creative=399349" style="border: none !important; margin: 0px !important;" width="1" /&gt;, which talks about the &lt;a href="http://www.joelonsoftware.com/articles/fog0000000043.html"&gt;Joel Test&lt;/a&gt;&amp;nbsp;so I took the test from my point of view of my team. &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Do you use Source Control? (YES)&lt;/li&gt;&lt;li&gt;Can you make a Build in one Step? (NO)&lt;/li&gt;&lt;li&gt;Do you make Daily Builds? (NO)&lt;/li&gt;&lt;li&gt;Do you have a Bug Database? (YES)&lt;/li&gt;&lt;li&gt;Do you fix bugs before writing new Code? (NO)&lt;/li&gt;&lt;li&gt;Do you have an up-to-date schedule? (NO)&lt;/li&gt;&lt;li&gt;Do you have a spec? (NO)&lt;/li&gt;&lt;li&gt;Do Programmers have quiet working conditions? (NO)&lt;/li&gt;&lt;li&gt;Do you have the best tools money can Buy? (YES)&lt;/li&gt;&lt;li&gt;Do you have testers? (YES)&lt;/li&gt;&lt;li&gt;Do new&amp;nbsp;candidates&amp;nbsp;write code during their Interview? (NO)&lt;/li&gt;&lt;li&gt;Do you do hallway&amp;nbsp;usability&amp;nbsp;testings? (NO)&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;So our test was a 4 out of 12. &amp;nbsp; &amp;nbsp;I wish I remember how long ago I did that, but things have changed since then and even our YES answers have became better. &amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Do you use Source Control? (YES)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Can you make a Build in one Step? (YES)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Do you make Daily Builds? (YES) -&lt;/li&gt;&lt;li&gt;Do you have a Bug Database? (YES)&lt;/li&gt;&lt;li&gt;Do you fix bugs before writing new Code? (YES) &amp;nbsp;&lt;/li&gt;&lt;li&gt;Do you have an up-to-date schedule? (YES)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Do you have a spec? (YES)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Do Programmers have quiet working conditions? (NO)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Do you have the best tools money can Buy? (YES)&lt;/li&gt;&lt;li&gt;Do you have testers? (YES)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Do new&amp;nbsp;candidates&amp;nbsp;write code during their Interview? (YES)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Do you do hallway&amp;nbsp;usability&amp;nbsp;testings? (YES) &amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;New Score 11 of 12, not perfect but much better.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The quality and the output of our team has increased dramatically in the past few years. &amp;nbsp; &amp;nbsp;Some of that is attributable to doing the things on that list.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do you use Source Control?&lt;/b&gt;&lt;br /&gt;When I started we were using Visual Source Safe, we have improved in this area by switching to Subversion.&lt;br /&gt;We never used branching before, now it's common to branch. &amp;nbsp; &amp;nbsp;We have built a one button deploy of our software using &lt;a href="http://www.finalbuilder.com/"&gt;FinalBuilder&lt;/a&gt;. &amp;nbsp; When we select the option to deploy to production which automatically tags the revision number that was used to build the software. &amp;nbsp; &amp;nbsp;We are currently investigating Mercurial or GIT but we have not decided on which and need to find a logical break to switch.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Can you make a Build in one Step?&amp;nbsp;&lt;/b&gt;&lt;b&gt;&amp;nbsp;Do you make Daily Builds?&lt;/b&gt;&lt;br /&gt;We purchased &lt;a href="http://www.finalbuilder.com/"&gt;FinalBuilder&lt;/a&gt; several years ago which helped made this a reality. &amp;nbsp; &amp;nbsp;Our first build script was triggered as needed. &amp;nbsp; It was run on an old desktop machine. &amp;nbsp;We then step it up on a timer and it ran every hour, then our speed of our build decreased and we had to run it every two hours. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;Our initial design was that we built and then deployed in the same script. &amp;nbsp; &amp;nbsp;That was a mistake, as we had to rebuild the application&amp;nbsp;every time&amp;nbsp;we change where we wanted to deploy &amp;nbsp;For example Development, Test, QA, Production. &amp;nbsp; &amp;nbsp; So the scripts were changed to build and the deploy to a staging directory. &amp;nbsp; Then we could deploy to any of the 4&amp;nbsp;environments. &amp;nbsp; This insured that the exact same binary that was tested was moved into Production. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;We then invested in&amp;nbsp;&lt;a href="http://www.finalbuilder.com/finalbuilder-server.aspx"&gt;FinalBuilder Server&lt;/a&gt;&amp;nbsp;which allowed us to start the build every time someone&amp;nbsp;committed.&lt;br /&gt;This improved our turn around time for our testing team, but the builds where still quite long. &amp;nbsp; So we took some time to&amp;nbsp;analyze&amp;nbsp;what was slow, fixed some problem areas of our scripts and invested in better hardware&lt;br /&gt;for the build. &amp;nbsp; &amp;nbsp;Our builds now take 10 minutes to complete, instead of the 2 hours.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do you have a Bug Database?&lt;/b&gt;&lt;br /&gt;Our first bug database when I arrived was a single table Delphi application that stored a limited single description of a problem, who it was assigned to and if it had been resolved. &amp;nbsp; &amp;nbsp; &amp;nbsp;Since then we adopted&lt;br /&gt;an Bug Tracking database that another team had built. &amp;nbsp; It's web based and has nearly everything we&lt;br /&gt;need. &amp;nbsp; &amp;nbsp;We have used the &lt;a href="http://tortoisesvn.net/"&gt;TortoiseSVN&lt;/a&gt;&amp;nbsp;bugtraq properties to &lt;a href="http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-dug-bugtracker.html"&gt;Integrate our Bug database with SVN&lt;/a&gt;.&lt;br /&gt;We also track new development in our Bug Tracking Database. &amp;nbsp; This allows to to tie development&lt;br /&gt;requests&amp;nbsp;regardless of type to the actual code that implemented them.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do you fix bugs before writing new Code? &amp;nbsp;&lt;/b&gt;&lt;br /&gt;We don't fix &lt;b&gt;all&lt;/b&gt; of the bugs in the application before we write new code. &amp;nbsp;However, if we want to write new code in a specific area, we find the existing bugs in that area and fix them before&amp;nbsp;heading off.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do you have an up-to-date schedule?&lt;/b&gt;&lt;br /&gt;We try to be agile in our process. &amp;nbsp; We hold daily stand-ups, and do iterations. &amp;nbsp; Our planning of what occurs in each iteration is working as expected. &amp;nbsp; &amp;nbsp;As we have refined our process our ability to know how long&lt;br /&gt;something is going to take has improved dramatically. &amp;nbsp; We still are not&amp;nbsp;accurate, 100% of the time but things&lt;br /&gt;balance out more often that not.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do you have a spec?&amp;nbsp;&lt;/b&gt;&lt;br /&gt;We did not have&amp;nbsp;specifications&amp;nbsp;for the longest time. &amp;nbsp; But last year we completed a several month project to develop business rules for all areas or software covered. &amp;nbsp; &amp;nbsp;This is useful as the business desires to change an area they update the existing documentation. &amp;nbsp; It really helps to find the dependencies and test all downstream code. &amp;nbsp; &amp;nbsp;It also gives direction on what is needed to the software developer. &amp;nbsp; We don't spend time with UI specification, unless it's critical. &amp;nbsp; Business rules is usually more than enough here.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do Programmers have quiet working conditions?&lt;/b&gt;&lt;br /&gt;This actually has become worse since I started, our cubical sizes have shrunk. &amp;nbsp; I have no control on cubical sizes, so I have focused on what I can control. &amp;nbsp; &amp;nbsp;Many of the developers now where headphones to attempt to get quiet working conditions. &amp;nbsp; I personally own two pairs of&amp;nbsp;&lt;a href="http://www.amazon.com/gp/product/B0002D03ZW/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=B0002D03ZW"&gt;Audio-Technica ATHM40FS Precision Studio Headphones&lt;/a&gt;, one for work and the other for home. &amp;nbsp; &amp;nbsp;They use a 1/4" Jack so if your trying to use your 1/8" Jack &amp;nbsp;you will need an adapter. &amp;nbsp; &amp;nbsp;It's my only way to find a quiet working&amp;nbsp;environment, but they do work, I can't hear the phone ring when they are on :-)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do you have the best tools money can Buy?&lt;/b&gt;&lt;br /&gt;When I arrived we had Delphi 3 and Delphi 7 was was the latest version. &amp;nbsp; They quickly upgraded, so I have always felt like I had the best tools. &amp;nbsp; But since that time we have turned to Maintenance for all of favorite tools, so we have access to the latest tools. &amp;nbsp; It also make budgeting easier. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do you have testers?&lt;/b&gt;&lt;br /&gt;When I first arrived we had a loose group of super users who tested as part of there responsibility. &amp;nbsp; &amp;nbsp;We still have these testers, but we also now have a formal team of people dedicated to the QA of the product. &amp;nbsp; This really took some time to change, but the&amp;nbsp;benefits&amp;nbsp;are huge.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do new&amp;nbsp;candidates&amp;nbsp;write code during their Interview?&lt;/b&gt;&lt;br /&gt;This is what really was the&amp;nbsp;genesis&amp;nbsp;of this blog post. &amp;nbsp; &amp;nbsp; Although team fit/personality is part of the equation it's&lt;br /&gt;not nearly as important as being able to code. &amp;nbsp;If your hiring a developer on just an Interview your bound to find "Bad Apples"&lt;br /&gt;&lt;br /&gt;Recently we hired two Contractors, we had over 20 applications and they all looked like qualified Delphi developers. &amp;nbsp; We sent out a written interview. With some SQL questions, we also had two simple coding questions. &amp;nbsp; They both could have been answered with little work in less than 8 lines of code. &amp;nbsp; &amp;nbsp;I was amazed by the number or 30+ lines of code answers.&lt;br /&gt;&lt;br /&gt;This quickly reduced the pool of&amp;nbsp;candidates&amp;nbsp;below 10. &amp;nbsp; &amp;nbsp;&amp;nbsp;We then did some actual Interviews reducing the pool of&amp;nbsp;candidate&amp;nbsp;even more. &amp;nbsp; &amp;nbsp;Then we sent them off on a 3 hour coding assignment, with full access to the Internet.&lt;br /&gt;&lt;br /&gt;Some people&amp;nbsp;familiar&amp;nbsp;with the process call it brutal, but I have yet to select someone who has poor coding skills but is great in an interview again.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Do you do hallway&amp;nbsp;usability&amp;nbsp;testings?&amp;nbsp;&lt;/b&gt;&lt;br /&gt;We could do more to promote this, but it's common for a developer to pull someone at random to come look at something to see how they react.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;In summary&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;This took quite a bit of time to implement, it was not an over night process. &amp;nbsp; &amp;nbsp;But each individual step along the path has improved our team. &amp;nbsp; &amp;nbsp;It's something I would encourage each development team to consider.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B0002D03ZW&amp;amp;camp=217145&amp;amp;creative=399349" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-480912054331142972?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/480912054331142972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/05/joel-test-evolution-of-team.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/480912054331142972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/480912054331142972'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/05/joel-test-evolution-of-team.html' title='The Joel Test The Evolution of a Team.'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-4679012392377337978</id><published>2011-02-14T07:20:00.000-07:00</published><updated>2011-02-14T07:20:39.799-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Happy 16th Birthday - Delphi</title><content type='html'>Happy 16th Birthday - Delphi!&lt;br /&gt;&lt;br /&gt;Thank you again, to all&amp;nbsp;those&amp;nbsp;involved with Delphi.&lt;br /&gt;&lt;br /&gt;Last month I was able to go to San&amp;nbsp;Francisco&amp;nbsp;to talk as a Rad Studio customer to talk to &lt;a href="http://www.embarcadero.com/"&gt;Embarcadero&lt;/a&gt;&amp;nbsp;sales team. &amp;nbsp; &amp;nbsp;Where I was able to meet most of the &lt;a href="http://www.embarcadero.com/company/executive-team"&gt;executive team&lt;/a&gt;&amp;nbsp;and hear some directions and plans.&amp;nbsp;&amp;nbsp;&amp;nbsp;From the small little bits I learned there I can insure you that the direction of Delphi is in good hands. &amp;nbsp; &amp;nbsp;Some of this has been hinted at during &lt;a href="http://delphi.org/"&gt;Jim's&lt;/a&gt; Podcast's with &lt;a href="http://blogs.embarcadero.com/abauer/"&gt;Allen Bauer&lt;/a&gt;,&amp;nbsp;episodes&amp;nbsp;&lt;a href="http://delphi.org/2011/01/44-allen-bauer/"&gt;44&lt;/a&gt;, and &lt;a href="http://delphi.org/2011/02/45-allen-bauer/"&gt;45&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Last year I posted a &amp;nbsp;&lt;a href="http://robstechcorner.blogspot.com/2010/02/happy-15th-birthday-delphi-my-delphi.html"&gt;Happy Birthday Delphi&lt;/a&gt;&amp;nbsp;message. &amp;nbsp; &amp;nbsp;At the end of that message I asked for Delphi to find it's self back into the entry level market. &amp;nbsp; &amp;nbsp; I please with the directions that have been taken. &amp;nbsp; &amp;nbsp; The &lt;a href="http://www.embarcadero.com/products/delphi/starter"&gt;Delphi Starter Edition&lt;/a&gt; has been released with a price point that opens the entry level market again. &amp;nbsp; I have also learned that the academic pricing is available for the product that is 90% of the list of the original product. &amp;nbsp;For a student this means that the professional edition can be purchased for around $100 USD which is the same price as the starter edition, and for labs I think it can be even cheaper.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-4679012392377337978?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/4679012392377337978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/02/happy-16th-birthday-delphi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4679012392377337978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4679012392377337978'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/02/happy-16th-birthday-delphi.html' title='Happy 16th Birthday - Delphi'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-4287730373505644260</id><published>2011-02-10T10:23:00.001-07:00</published><updated>2011-02-10T13:49:20.208-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Windows 64Bit OS - Directory Layout</title><content type='html'>Short and sweet, as I had someone ask me about this today...&lt;br /&gt;&lt;br /&gt;The \windows\system32\ directory on 64 bit version of &amp;nbsp;Windows does not contain 32 bit files it contains 64 bit&amp;nbsp;files. &amp;nbsp; &amp;nbsp;The 32 bit files are stored in \windows\SysWOW64&lt;br /&gt;&lt;br /&gt;WOW stands for "Windows on Windows"&lt;br /&gt;&lt;br /&gt;Go figure, the 32 bit files are in a directory with 64 in it, and the 64 bit files are in a directory with 32 in it.&lt;br /&gt;&lt;br /&gt;According to the&amp;nbsp;road map&amp;nbsp;the next version of Delphi should be able to produce 64bit applications so it's important to know this detail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-4287730373505644260?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/4287730373505644260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/02/windows-64bit-os-directory-layout.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4287730373505644260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4287730373505644260'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/02/windows-64bit-os-directory-layout.html' title='Windows 64Bit OS - Directory Layout'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-6523393883240616113</id><published>2011-01-07T22:30:00.000-07:00</published><updated>2011-01-07T22:30:08.464-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Job Openings @ State of Utah</title><content type='html'>I work for the Department of Technology Services for the State of Utah.&lt;br /&gt;I am assigned to work at the Department of Workforce Services.&lt;br /&gt;&lt;br /&gt;We recently have opened up a few new State Employee based position, which is really a rare thing.&lt;br /&gt;&lt;br /&gt;All Jobs at the State of Utah can be located here: &amp;nbsp;&lt;a href="https://statejobs.utah.gov/"&gt;https://statejobs.utah.gov/&lt;/a&gt;&lt;br /&gt;These are all Full-Time positions with work being performed in Salt Lake City, Utah.&lt;br /&gt;&lt;br /&gt;Benefits are good, we work Monday-Thursday for ten hours a day, so you always have&lt;br /&gt;a long weekend. &amp;nbsp; We have a good&amp;nbsp;working environment. &amp;nbsp; We also have excellent Benefits&lt;br /&gt;which include (not a complete list) medical, dental, and life insurance. &amp;nbsp;1.5% employer contribution into 401(k). &amp;nbsp; Annual, Sick and Holiday Leave. &amp;nbsp;Finally last but not least a Pension with 4 years to become vested.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;On my team I have two openings for Delphi Developers. &amp;nbsp; &lt;/b&gt;&amp;nbsp;&amp;nbsp;We currently have 10 People on my team, we practice agile techniques development.&lt;br /&gt;&lt;br /&gt;My team currently uses the following&amp;nbsp;technologies.&lt;br /&gt;&lt;br /&gt;Languages:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Rad Studio XE Enterprise (under maintenance so we always have the latest version)&lt;span class="Apple-style-span" style="color: #666666; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 15px;"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Delphi Win32 2007, XE &amp;nbsp;(Primary Development Tool)&lt;/li&gt;&lt;li&gt;Delphi Prism XE &amp;nbsp; &amp;nbsp;(Secondary Development Tool)&lt;/li&gt;&lt;li&gt;C++ Builder 2007 &amp;amp; XE (Limited)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Visual Studio C++ Express (Limited)&lt;/li&gt;&lt;li&gt;C# (Limited) typically using Sharp Develop&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Databases&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Oracle 10g (Project underway to move to 11g)&lt;/li&gt;&lt;li&gt;Sybase (Limited)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Tools&amp;nbsp;(list not complete)&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Subversion&lt;/li&gt;&lt;li&gt;Final Builder&lt;/li&gt;&lt;li&gt;Test Complete&lt;/li&gt;&lt;li&gt;Toad&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Libraries (list not complete)&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;JCL&amp;nbsp;&lt;/li&gt;&lt;li&gt;Envision Imaging Library&lt;/li&gt;&lt;li&gt;TMS Components&lt;/li&gt;&lt;li&gt;Rave Reports&amp;nbsp;&lt;/li&gt;&lt;li&gt;Gnostice eDocEngine&lt;/li&gt;&lt;li&gt;Turbopower Abbrevia&lt;/li&gt;&lt;li&gt;Turbopower LockBox&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Delphi Job details listed here:&lt;/b&gt;&lt;br /&gt;&lt;a href="https://statejobs.utah.gov/JobAnnouncement.jsp?rid=22780"&gt;https://statejobs.utah.gov/JobAnnouncement.jsp?rid=22780&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;On our web team we also have two openings for C# Developers details listed here:&lt;br /&gt;&lt;a href="https://statejobs.utah.gov/JobAnnouncement.jsp?rid=22817"&gt;https://statejobs.utah.gov/JobAnnouncement.jsp?rid=22817&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We also have a Versta Developer opening which is a framework based on Java.&lt;br /&gt;&lt;a href="https://statejobs.utah.gov/JobAnnouncement.jsp?rid=22806"&gt;https://statejobs.utah.gov/JobAnnouncement.jsp?rid=22806&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If someone wants to be considered for multiple positions they need to apply for each&lt;br /&gt;as they are under different hiring managers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-6523393883240616113?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/6523393883240616113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2011/01/job-openings-state-of-utah.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6523393883240616113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6523393883240616113'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2011/01/job-openings-state-of-utah.html' title='Job Openings @ State of Utah'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-7741512491736779824</id><published>2010-10-12T11:25:00.000-06:00</published><updated>2010-10-12T11:25:47.131-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>No Commercial Version of RAVE for Delphi XE</title><content type='html'>Where I work our product is very tied to Nevrona's Rave Reports. &amp;nbsp; &amp;nbsp;We are based around the NDR file format and concept. &amp;nbsp; &amp;nbsp;Since the release of XE our emails to Nevrona and being ignored we still don't have an XE version of RAVE Reports.&lt;br /&gt;&lt;br /&gt;XE is a&amp;nbsp;compelling&amp;nbsp;upgrade for us and as such we have decided to try to upgrade RAVE &amp;nbsp;to XE. &amp;nbsp; &amp;nbsp; &amp;nbsp;We do have the&amp;nbsp;commercial&amp;nbsp;8.0 release.&lt;br /&gt;&lt;br /&gt;I don't know about Embarcadero's agreement is with Nevrona but I don't think it's in the best&amp;nbsp;interest&amp;nbsp;of either party to keep bundling RAVE to with Embarcadero. &amp;nbsp; &amp;nbsp;From Embarcadero's point of view they are shipping a product that points to a company that all but appears dead. &amp;nbsp; &amp;nbsp; From Nevrona's Point of view they may be able make revenue on a product from those that need to upgrade Delphi versions. &amp;nbsp; Maybe returning a revenue stream that they have lost because most users just use the free version. I know they can't be making much money now. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;I actually would like to see RAVE become open source. &amp;nbsp; I know my team would be at the very least committing changes to keep it updated to the latest compilers.&lt;br /&gt;&lt;br /&gt;As for our long term roadmap, I don't have a clue.... Research begins now... Looking for Reporting solution that can temporary file that can then be printed, exported to Excel, specified pages of the report can be converted to an image. &amp;nbsp; (We use TIFF but I can convert from about any format)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-7741512491736779824?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/7741512491736779824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/10/no-commercial-version-of-rave-for.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7741512491736779824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7741512491736779824'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/10/no-commercial-version-of-rave-for.html' title='No Commercial Version of RAVE for Delphi XE'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-7839494936430811291</id><published>2010-09-12T11:44:00.001-06:00</published><updated>2010-09-12T11:47:32.747-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VDUG'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeRage'/><category scheme='http://www.blogger.com/atom/ns#' term='About Rob'/><title type='text'>CodeRage - Audio/Recording Equipment</title><content type='html'>I was just accepted to do two &lt;a href="http://www.embarcadero.com/coderage5"&gt;CodeRage&lt;/a&gt; Sessions, I am excited about both of them.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Building Robust Applications with Customized Exception Management&lt;/li&gt;&lt;li&gt;Continuous Integration with DUnit and FinalBuilder&lt;/li&gt;&lt;/ul&gt;I hope everyone gets a chance to attend some of the sessions, the exact dates and times of my sessions are not known yet.   The conference is scheduled for October 4-8, 2010.&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_IkAwJdQc39w/TI0KcaRRIDI/AAAAAAAAQGs/PuqSBwgMTw0/s1600/IMG_6303.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="133" src="http://2.bp.blogspot.com/_IkAwJdQc39w/TI0KcaRRIDI/AAAAAAAAQGs/PuqSBwgMTw0/s200/IMG_6303.JPG" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;What I used in the past and will still&lt;br /&gt;use to monitor broadcast audio&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Right after I graduated from high school, I attended university as a theater major.  That lasted about 2 years before dropping out to become a full time Delphi programmer. :-)   But my love for Theater is still in my life.  I volunteer at our &lt;a href="http://www.rodgersmemorial.com/"&gt;local theater&lt;/a&gt;, building sets, running shows, and many other things. &amp;nbsp;As such, I developed an appreciation for quality sound.&lt;br /&gt;&lt;br /&gt;One of the things I observed in my past recordings was my audio quality was not what I wanted it to be. &amp;nbsp; &amp;nbsp; I also don't have a huge budget to turn my office office into a studio, but I did make some investments to try to improve the quality of the sound. &amp;nbsp;About $280 later this this is what i have:&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_IkAwJdQc39w/TI0KfvfboII/AAAAAAAAQG0/DZzZZZMa2yg/s1600/IMG_6304.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/_IkAwJdQc39w/TI0KfvfboII/AAAAAAAAQG0/DZzZZZMa2yg/s320/IMG_6304.JPG" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The New setup&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A new microphone&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/B0002CZW0Y?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B0002CZW0Y"&gt;Nady MPF-6  6-Inch Clamp On Microphone Pop Filter&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=peakbizsoluti-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B0002CZW0Y" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/B0002D080C?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B0002D080C"&gt;Samson C01 Large Diaphragm Vocal Condenser Microphone&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=peakbizsoluti-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B0002D080C" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/B0002M3OVI?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B0002M3OVI"&gt;On Stage DS7200B Adjustable Desk Microphone Stand, Black&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/B000LQLDM2?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000LQLDM2"&gt;Samson SP01 Shockmount Spider Mount for Condenser Mics&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;A new mixer and headphones&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/B000J5XS3C?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000J5XS3C"&gt;Behringer Xenyx 802 Premium 8-Input 2-Bus Mixer with Xenyx Mic Preamps and British EQs&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=peakbizsoluti-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B000J5XS3C" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/B0002D03ZW?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B0002D03ZW"&gt;Audio Technica ATHM40FS Precision Studio Headphones&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=peakbizsoluti-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B0002D03ZW" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;USB Audio Interface&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/B000KW2YEI?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000KW2YEI"&gt;Behringer UCA202 U-Control Audio Interface&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;And the cables needed to hook it all up.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/B000068O16?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000068O16"&gt;Hosa CPR201 Dual 1/4 To Dual RCA Cable 3.25 Ft&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=peakbizsoluti-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B000068O16" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/B000165DSM?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B000165DSM"&gt;XLR male to XLR female Microphone Cable - 15 feet&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;I have now done some test recordings, and I really pleased with the quality of my voice. &amp;nbsp;If I were only doing an audio podcast I would have a near perfect setup. But with a good microphone comes some problems, related to the&amp;nbsp;acoustics&amp;nbsp;of the room, &amp;nbsp;I now can hear the keyboard, mouse, the&amp;nbsp;squeaky&amp;nbsp;chair, the fan on the computer, and a slight echo. &amp;nbsp;I also can hear the kids if they are talking in the room next door. &amp;nbsp;To get the audio in my office where I would want it would be another $400-$700 not something I am going to spend any time soon.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So some tricks I have learned: &amp;nbsp; A laptop keyboard is much quieter than my desktop keyboard so I most likely will be presenting on it instead of my desktop. &amp;nbsp;&amp;nbsp;Strategic&amp;nbsp;placement of hung blankets helps with the Echo of room which reduces other noises. &amp;nbsp; &amp;nbsp;I suspect some WD-40 on the chair will help with the&amp;nbsp;squeak or I will just switch chairs. &amp;nbsp; &amp;nbsp; If I am recording noise reduction will remove most of the noise from the computer fan. &amp;nbsp;This but it won't help with the live&amp;nbsp;presentations,&amp;nbsp;so I might pull out the longer cables I have. to isolate the computer, as I still need it even if I am not typing 100% of the time on it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Overall I hope that future live and recorded sessions of mine will have better audio for everyone. &amp;nbsp; &amp;nbsp;Even if I am the only one that may notice the difference in the end .&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-7839494936430811291?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/7839494936430811291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/09/coderage-audiorecording-equipment.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7839494936430811291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7839494936430811291'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/09/coderage-audiorecording-equipment.html' title='CodeRage - Audio/Recording Equipment'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_IkAwJdQc39w/TI0KcaRRIDI/AAAAAAAAQGs/PuqSBwgMTw0/s72-c/IMG_6303.JPG' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-530611465422539310</id><published>2010-08-31T13:29:00.000-06:00</published><updated>2010-08-31T13:29:37.997-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='VDUG'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>Rad Studio XE - DelphiLive</title><content type='html'>At &lt;a href="http://www.delphilive.com/"&gt;DelphiLive&lt;/a&gt; last week it was fairly obvious that &lt;a href="http://www.embarcadero.com/"&gt;Embarcadero&lt;/a&gt; was close to shipping RAD Studio. &amp;nbsp; When there I took a &lt;a href="http://picasaweb.google.com/LovePhotoStore/DelphiLive2010#"&gt;few photos&lt;/a&gt;, and &lt;a href="http://delphi.org/"&gt;Jim&lt;/a&gt; wanted to play with the Camera so he took more :-) &amp;nbsp; I have recordings of the keynote session that I will be posting in the next day or two on the VDUG site.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well &lt;a href="http://www.embarcadero.com/products/rad-studio"&gt;RAD Studio XE&lt;/a&gt; was released yesterday, and I am really impressed as SA/Maint Customer I received the keys and the download the same day. &amp;nbsp; &amp;nbsp;I was able to get the full product installed today. &amp;nbsp; In past releases I have had to wait a few weeks to get the product, so this is very welcome change.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://3.bp.blogspot.com/_IkAwJdQc39w/TH1PowYwT6I/AAAAAAAAPsU/sUhK6aRodc4/s1600/RadStudioMenu.JPG" imageanchor="1" style="clear: right; display: inline !important; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_IkAwJdQc39w/TH1PowYwT6I/AAAAAAAAPsU/sUhK6aRodc4/s320/RadStudioMenu.JPG" /&gt;&lt;/a&gt;I had an Windows XP Machine and I bit shocked by the menu bloat, and I did not even install &lt;a href="http://www.embarcadero.com/products/interbase-smp"&gt;InterBase&lt;/a&gt; or &lt;a href="http://www.installaware.com/"&gt;Installaware.&lt;/a&gt; &amp;nbsp; &amp;nbsp;But it does highlight some of the new editions the the RAD Studio Line. &amp;nbsp; For Delphi and C++ Developers they get to look forward to &lt;a href="http://smartbear.com/development-tools/performance-profiling/"&gt;Automated QA&lt;/a&gt;, and &lt;a href="http://www.raize.com/devtools/codesite/"&gt;CodeSite&lt;/a&gt;. &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;For&amp;nbsp;&lt;a href="http://www.embarcadero.com/products/delphi"&gt;Delphi&lt;/a&gt;, &lt;a href="http://www.embarcadero.com/products/cbuilder"&gt;C++ Builder&lt;/a&gt;,&amp;nbsp;and&amp;nbsp;&lt;a href="http://www.embarcadero.com/products/delphi-prism"&gt;Delphi Prism&lt;/a&gt;&amp;nbsp;developers&amp;nbsp;&amp;nbsp;they get&amp;nbsp;&lt;a href="http://subversion.apache.org/"&gt;Subversion&lt;/a&gt;&amp;nbsp;Integration,&amp;nbsp;&lt;a href="http://www.finalbuilder.com/home.aspx"&gt;FinalBuilder&lt;/a&gt;. &amp;nbsp; Rave Reports is still the product, since we depend on it I am happy as it appears that &lt;a href="http://www.nevrona.com/"&gt;Nevrona&lt;/a&gt; is all but a dead company. &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://www.embarcadero.com/products/delphi-prism"&gt;Delphi Prism&lt;/a&gt;&amp;nbsp;now integrates into both &lt;a href="http://www.microsoft.com/visualstudio/en-us"&gt;Visual Studio 2010&lt;/a&gt; but also &lt;a href="http://monodevelop.com/"&gt;MonoDevelop&lt;/a&gt;. &amp;nbsp; There is even an install for&amp;nbsp;&lt;a href="http://www.embarcadero.com/products/delphi-prism"&gt;Delphi Prism&lt;/a&gt;&amp;nbsp;to install with&amp;nbsp;&amp;nbsp;&lt;a href="http://monodevelop.com/"&gt;MonoDevelop&lt;/a&gt;&amp;nbsp;on a &lt;a href="http://www.apple.com/mac/"&gt;MAC&lt;/a&gt;. &amp;nbsp; &amp;nbsp;To round out the Menu &lt;a href="http://www.embarcadero.com/products/radphp"&gt;RadPHP&lt;/a&gt;&amp;nbsp;(Formerly&amp;nbsp;Delphi for PHP) is now included in the&amp;nbsp;&lt;a href="http://www.embarcadero.com/products/rad-studio"&gt;RAD Studio XE&lt;/a&gt;&amp;nbsp;&amp;nbsp;product line.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are a few other new items bundled with&amp;nbsp;&lt;a href="http://www.embarcadero.com/products/rad-studio"&gt;RAD Studio XE&lt;/a&gt;&amp;nbsp;that don't create menu items (Thank you for not doing that!)&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.scootersoftware.com/"&gt;Beyond Compare&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.nsoftware.com/ipworks/"&gt;IP*Works components&lt;/a&gt;&amp;nbsp;(&lt;a href="http://www.indyproject.org/index.en.aspx"&gt;Indy&lt;/a&gt; is still there!)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.remobjects.com/oxfuscator.aspx"&gt;RemObjects Oxfuscator&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;And I would not be surprised if I missed something else that is bundled. &amp;nbsp; &amp;nbsp; &amp;nbsp; Of course my next questions and potential blog posts are what is under the covers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-530611465422539310?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/530611465422539310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/08/rad-studio-xe-delphilive.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/530611465422539310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/530611465422539310'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/08/rad-studio-xe-delphilive.html' title='Rad Studio XE - DelphiLive'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_IkAwJdQc39w/TH1PowYwT6I/AAAAAAAAPsU/sUhK6aRodc4/s72-c/RadStudioMenu.JPG' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-2374254867299084699</id><published>2010-08-23T20:26:00.000-06:00</published><updated>2010-08-23T20:26:53.781-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='VDUG'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>DelphiLive - I am here!</title><content type='html'>I am now at &lt;a href="http://www.delphilive.com/"&gt;DelphiLive&lt;/a&gt;, &amp;nbsp;I ran into the guys at &lt;a href="http://www.remobjects.com/"&gt;RemObjects&lt;/a&gt;. &amp;nbsp; Today waiting for the conference to get underway we took a little trip to&amp;nbsp;Cupertino to visit Apple and had lunch. &amp;nbsp; &lt;a href="http://blogs.remobjects.com/blogs/mh"&gt;Marc&lt;/a&gt; nearly sold me on an iPad his with 3G support was used quite a bit as we navigated the streets. &amp;nbsp; &amp;nbsp; One of the things we talked about was &lt;a href="http://www.remobjects.com/tv"&gt;RemObjects TV&lt;/a&gt;, which really looks good. &amp;nbsp;BTW I found out that some of the &lt;a href="http://www.vdug.org/"&gt;VDUG &lt;/a&gt;videos don't work on iPad and that &lt;a href="http://www.delphi.org/"&gt;Jim&lt;/a&gt; re-encodes the Camtasia results to make it work on iPad.&amp;nbsp;&amp;nbsp; They guys at RemObjects are all carrying Flip Ultra HD Video Cameras, and I suspect we will get all sorts of good material from it. &amp;nbsp; &amp;nbsp;I am carrying a Kodak Zi8 and Digtal Rebel T1i so I have a couple of options to gather and share what is going on here.&lt;br /&gt;&lt;br /&gt;Looking forward to the keynote&amp;nbsp;tomorrow!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-2374254867299084699?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/2374254867299084699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/08/delphilive-i-am-here.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2374254867299084699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2374254867299084699'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/08/delphilive-i-am-here.html' title='DelphiLive - I am here!'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-5137999972845217964</id><published>2010-06-03T12:46:00.002-06:00</published><updated>2010-06-03T12:48:10.030-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='VDUG'/><category scheme='http://www.blogger.com/atom/ns#' term='Personal Outlook'/><title type='text'>Personal Outlook #2</title><content type='html'>&lt;b&gt;Virtual Meetings&lt;/b&gt;&lt;br /&gt;I enjoy attending virtual events, it's a good way to learn and share information. &amp;nbsp; It's one of the reason's I started the &lt;a href="http://www.vdug.org/"&gt;Virtual Delphi Users Group&lt;/a&gt;. &amp;nbsp; I am always on the watch for good virtual events. &amp;nbsp;I have multiple computers every place I code. &amp;nbsp; With a virtual event I typically start it on a secondary computer and stay coding. &amp;nbsp; If I hear something&amp;nbsp;interesting&amp;nbsp;I look at the second machine to see the details. &amp;nbsp; On occasion something really good is covered and I never get back to coding.&lt;br /&gt;&lt;br /&gt;For the next &lt;a href="http://www.vdug.org/"&gt;VDUG&lt;/a&gt; meeting we had&amp;nbsp;advertised&amp;nbsp;covering&amp;nbsp;&lt;a href="http://www.embarcadero.com/products/delphi-prism"&gt;Delphi Prism 2011&lt;/a&gt;. &amp;nbsp; &amp;nbsp;I just found this event "&lt;a href="http://edn.embarcadero.com/article/40627"&gt;Extreme Cross-platform .NET with Delphi 2011"" &amp;nbsp;presented by David I&lt;/a&gt;. &amp;nbsp;Which is the week before the &lt;a href="http://www.vdug.org/"&gt;VDUG&lt;/a&gt; Meeting, and was going to cover nearly the same material. &amp;nbsp; Not wanting to just show the same thing, I am going to change the topic a bit. &amp;nbsp; So, I think everyone should attend the event with David I. &amp;nbsp; &lt;br /&gt;&lt;br /&gt;As for the &lt;a href="http://www.vdug.org/"&gt;VDUG&lt;/a&gt; Meeting, I am now working on refining a deeper dive into the Delphi Prism Language&amp;nbsp;Features.&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;With some of the things we have learned trying to keep some of our code cross-compiling with Delphi Win32. &amp;nbsp; &amp;nbsp;When I get the material prepared I will announce the new meeting on the &lt;a href="http://www.vdug.org/"&gt;VDUG&lt;/a&gt; Site.&lt;br /&gt;&lt;br /&gt;Another virtual event I found today that looks&amp;nbsp;interesting&amp;nbsp;is a 3 hour Virtual Conference with &lt;a href="http://www.bzmedia.com/agility/index.htm"&gt;Kent Beck on Continuous Deployment&lt;/a&gt;. &amp;nbsp; &amp;nbsp;Since I have enjoyed many of &lt;a href="http://www.amazon.com/s/?ie=UTF8&amp;amp;tag=peakbizsoluti-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;search-alias=aps&amp;amp;field-keywords=kent%20beck" target="_blank"&gt;his books&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=peakbizsoluti-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;. &amp;nbsp; Most of the time virtual conferences by the media companies are so product specific that if you don't use the product it's a waste of time. &amp;nbsp; But this looks&amp;nbsp;interesting&amp;nbsp;and I think I can apply the topic to our situation. &amp;nbsp;Specifically we&amp;nbsp;currently use &lt;a href="http://www.finalbuilder.com/finalbuilder-server.aspx"&gt;FinalBuilder Server&lt;/a&gt;&amp;nbsp;to monitor our &lt;a href="http://subversion.apache.org/"&gt;SVN&lt;/a&gt;&amp;nbsp;repository for changes, which when detected they are automatically built and deployed to our test&amp;nbsp;environment.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Stackoverflow Code-Golf&lt;/b&gt;&lt;br /&gt;On &lt;a href="http://stackoverflow.com/"&gt;stackoverflow.com&lt;/a&gt;&amp;nbsp;there is a tag called &lt;a href="http://stackoverflow.com/questions/tagged/code-golf"&gt;Code-Golf&lt;/a&gt;&amp;nbsp;that contains challenges to the write the smallest program possible meeting the requirements of the challenge. &amp;nbsp; I took note of &lt;a href="http://stackoverflow.com/questions/2960242/code-golf-all-combinations-for-3-integers"&gt;this question&lt;/a&gt; and &lt;a href="http://stackoverflow.com/questions/2960242/code-golf-all-combinations-for-3-integers/2968130#2968130"&gt;answered it in Delphi&lt;/a&gt;. &amp;nbsp; &amp;nbsp; It shows that you can do cryptic things in Delphi, just like you can in other languages. &amp;nbsp; I think it's a good example of why you should use descriptive variable names and types. &amp;nbsp; &amp;nbsp; &amp;nbsp;The answer was the ugliest code I have ever written.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-5137999972845217964?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/5137999972845217964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/06/personal-outlook-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5137999972845217964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5137999972845217964'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/06/personal-outlook-2.html' title='Personal Outlook #2'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-1631666991310366225</id><published>2010-04-24T00:48:00.001-06:00</published><updated>2010-06-03T12:49:33.509-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='VDUG'/><category scheme='http://www.blogger.com/atom/ns#' term='SLCDUG'/><title type='text'>Virtual Delphi Users Group</title><content type='html'>On April 20th, 2010 &lt;a href="http://www.slcdug.org/"&gt;SLCDUG&lt;/a&gt;&amp;nbsp;conducted an experiment on a virtual meeting. &amp;nbsp; &amp;nbsp; The results were much better than expected. &amp;nbsp; This concept worked! &amp;nbsp;I have work to do to improve the overall experience. &amp;nbsp;We had several minor problems, but overall we can improve.&lt;br /&gt;&lt;br /&gt;One thing I realized needed to improve was it needed &amp;nbsp;to have a central place were we could announce meetings and store recordings. &amp;nbsp; The &lt;a href="http://www.slcdug.org/"&gt;SLCDUG&lt;/a&gt; site is just a blogger account and would not support files of the size the recordings.&lt;br /&gt;&lt;br /&gt;So I setup a new domain and website just for the "&lt;a href="http://vdug.org/"&gt;Virtual Delphi Users Group&lt;/a&gt;" &lt;br /&gt;&lt;br /&gt;Now, I find myself personally using &lt;a href="http://www.delphifeeds.com/"&gt;Delphi Feeds&lt;/a&gt; most of the time so I want the &lt;a href="http://feeds.feedburner.com/VirtualDelphiUsersGroup"&gt;VDUG Feed&lt;/a&gt;&amp;nbsp;listed there, if you want to see it then &lt;a href="http://delphifeeds.uservoice.com/forums/14264-feedback/suggestions/683388-add-the-virtual-delphi-users-group-feed?ref=title"&gt;vote for my submission&lt;/a&gt;.&amp;nbsp; &lt;strong&gt;(UPDATE: It's listed!)&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The replay of the first meeting: &amp;nbsp; &lt;a href="http://vdug.org/2010/04/first-meeting/"&gt;Component Development / Tips &amp;amp; Tricks&lt;/a&gt;&amp;nbsp;has been posted on the the &lt;a href="http://vdug.org/"&gt;new site&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If your&amp;nbsp;interested&amp;nbsp;in sponsoring this group in any way let me know: rlove at peakbiz dot com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-1631666991310366225?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/1631666991310366225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/04/virtual-delphi-users-group.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/1631666991310366225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/1631666991310366225'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/04/virtual-delphi-users-group.html' title='Virtual Delphi Users Group'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-8126162130749574275</id><published>2010-04-14T08:58:00.000-06:00</published><updated>2010-06-03T12:49:33.510-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='VDUG'/><category scheme='http://www.blogger.com/atom/ns#' term='SLCDUG'/><title type='text'>Virtual Delphi Users Group Meeting</title><content type='html'>I will be presenting at a Virtual Delphi Users Group Meeting Next Week.&lt;br /&gt;&lt;br /&gt;Everyone is invited and it's free of charge.&amp;nbsp;&amp;nbsp; It's not going to be a marketing show like a typical Webinar, it just plan free training on Delphi.&lt;br /&gt;&lt;br /&gt;Date: Tuesday April 20, 2010&lt;br /&gt;Time: 6:00 PM MDT (UTC - 6 hours)&lt;br /&gt;&lt;br /&gt;Topics:&lt;br /&gt;&amp;nbsp;&amp;nbsp; Delphi Tips &amp;amp; Tricks - Phil Gilmore&lt;br /&gt;&amp;nbsp;&amp;nbsp; Delphi Component Development - Robert Love&lt;br /&gt;&lt;br /&gt;Pre-Registration is required:  &lt;a href="https://www1.gotomeeting.com/register/512344336"&gt;https://www1.gotomeeting.com/register/512344336&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have more material on Component Development than time will allow, as such I will poll those attending the meeting to decide on the direction to take.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This will be the first of hopefully several, it really depends on participation levels, i.e. don't want to prepare and have nobody show up :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-8126162130749574275?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/8126162130749574275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/04/virtual-delphi-users-group-meeting.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8126162130749574275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8126162130749574275'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/04/virtual-delphi-users-group-meeting.html' title='Virtual Delphi Users Group Meeting'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-1469696853313920375</id><published>2010-04-06T11:46:00.000-06:00</published><updated>2010-04-06T11:46:39.204-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='SLCDUG'/><category scheme='http://www.blogger.com/atom/ns#' term='Personal Outlook'/><title type='text'>Personal Outlook #1</title><content type='html'>&lt;ul&gt;&lt;li&gt;Just Learned about &amp;nbsp;&lt;a href="http://code.google.com/p/asmprofiler/"&gt;AsmProfiler&lt;/a&gt;&amp;nbsp;when reading this&lt;a href="http://stackoverflow.com/questions/2584917/why-aqtime-slows-execution-even-when-profiling-is-not-on-and-can-anything-be-don"&gt; Stackoverflow Question&lt;/a&gt;&amp;nbsp;initial take is that it looks promising. I am going to try it next time I need to profile something.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Recently purchased &lt;a href="http://www.tmssoftware.com/site/vdsub.asp"&gt;TMS VCL&amp;nbsp;Subscription&lt;/a&gt;. &amp;nbsp;I just sent our&amp;nbsp;first contact with support was a feature request yesterday. &amp;nbsp; Early this morning I was sent code implementing the feature as a patch. &amp;nbsp; Talk about fast support!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I am going to bite the bullet and spend the additional money and use&amp;nbsp;&lt;a href="http://www.gotomeeting.com/fec/webinar"&gt;GotoWebinar&lt;/a&gt; for the first &lt;a href="http://www.slcdug.org/"&gt;SLCDUG&lt;/a&gt; Virtual meeting now I just need to get a topic together, and the new virtual meeting format. &amp;nbsp; The date of the meeting will be April 20th, watch the &lt;a href="http://www.slcdug.org/"&gt;SLCDUG website&lt;/a&gt; for details.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.devconnections.com/shows/SP2010VS/default.asp?s=144"&gt;Visual Studio 2010 launching April 12th&lt;/a&gt;, I wonder how long until we see &lt;a href="http://www.embarcadero.com/products/delphi-prism/faq#20"&gt;Delphi Prism for VS 2010&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Homage to&amp;nbsp;&lt;a href="http://blogs.embarcadero.com/nickhodges/"&gt;Nick Hodges&lt;/a&gt;&amp;nbsp;commonly post entries to his blog called&amp;nbsp;&lt;a href="http://blogs.embarcadero.com/nickhodges/2010/02/12/39359"&gt;Random Thoughts on the Passing Scene&lt;/a&gt;&amp;nbsp;in a similar format :-)&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-1469696853313920375?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/1469696853313920375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/04/personal-outlook-1.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/1469696853313920375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/1469696853313920375'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/04/personal-outlook-1.html' title='Personal Outlook #1'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-5969033985051807511</id><published>2010-04-04T13:12:00.001-06:00</published><updated>2010-06-03T12:49:33.510-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='VDUG'/><category scheme='http://www.blogger.com/atom/ns#' term='SLCDUG'/><title type='text'>Virtual User Group Options</title><content type='html'>The &lt;a href="http://www.slcdug.org/"&gt;SLCDUG&lt;/a&gt;&amp;nbsp;(Salt Lake City Delphi Users Group) is going to do some of it's meetings on-line.&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;I started researching many options of what technlogy to use, with the following factors&amp;nbsp;playing into&amp;nbsp;my decision:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Cost, since we don't collect dues the cost needs to be small enough that I can personally handle it if there is not a&amp;nbsp;sponsor&amp;nbsp;willing to pick up the tab. &amp;nbsp;&amp;nbsp;&lt;/li&gt;&lt;li&gt;Options are available to make this more like a local users group meeting than&amp;nbsp;pre-scripted&amp;nbsp;webinar presentation.&amp;nbsp;&lt;/li&gt;&lt;li&gt;We have attendance in the past year at anywhere from 4 people to 50 people. &amp;nbsp; &amp;nbsp;Because&amp;nbsp;our virtual meetings will be available to everyone on the Internet, we need a solution that supports at least 100 people.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I was&amp;nbsp;surprised&amp;nbsp;to find that there is not a ton of un-biased reviews. &amp;nbsp; For example the most compressive review of GoToWebinar was done by a Cisco employee the company that produces Webex. &amp;nbsp; &amp;nbsp;With that in mind I knew&amp;nbsp;I could not depend on others research. &amp;nbsp; So I setup multiple computers in my home all signed up for the trial offers of the following companies and this is what I found in my comparision.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gotomeeting.com/fec/webinar"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;GoToWebinar&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;Price: $99/Month&lt;br /&gt;Max Attendees: 100 @ $99&amp;nbsp;* 500&amp;nbsp;@ $399&amp;nbsp;&amp;nbsp;*&amp;nbsp; 1000&amp;nbsp;@ $499 &lt;br /&gt;OS Supported: Windows, MAC&lt;br /&gt;Trial Length: 30 Days&lt;br /&gt;&lt;b&gt;Pros:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Interface was easy to use.&lt;/li&gt;&lt;li&gt;Control windows are not broadcast&lt;/li&gt;&lt;li&gt;Ability to view only one application instead of the entire desktop.&lt;/li&gt;&lt;li&gt;Support for VOIP and Telephone conferencing for presenters and/or Attendees&lt;/li&gt;&lt;li&gt;May unmute either option quickly via software.&lt;/li&gt;&lt;li&gt;Up to 25 People could be unmuted.&lt;/li&gt;&lt;li&gt;Good registration and Tracking of who&amp;nbsp;attended.&lt;/li&gt;&lt;li&gt;Was able to show a small video clip without slow down.&lt;/li&gt;&lt;li&gt;Ability to share or hide Attendees List&lt;/li&gt;&lt;li&gt;Easy to schedule future meetings&lt;/li&gt;&lt;li&gt;Ability&amp;nbsp;to make someone else the presenter without reconnecting&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Cons:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No support for Web Cams&lt;/li&gt;&lt;li&gt;No Support Linux&lt;/li&gt;&lt;li&gt;Can not be run from a virtual machine&lt;/li&gt;&lt;/ul&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;a href="http://www.webex.com/"&gt;&lt;b&gt;WebEx&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Price: &amp;nbsp;Contact Sales (Scared here as 25 users is $49/Month but I have sent an email request)&lt;br /&gt;Max Attendees: 500 (Meeting Center Product) 3000 (Event Center Product)&lt;br /&gt;OS Supported: Windows, MAC, Solaris, Unix, Linux, 3G Enabled Smart phones (IPhone, Blackberry, Nokia, etc)&lt;br /&gt;Trial Length: 14 Days (Meeting Center) unable to trial Event Center&lt;br /&gt;&lt;b&gt;Pros:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Control windows are not broadcast&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Optional support to allow attendees to chat with each other.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Ability to Share or Hide Attendee List&lt;/li&gt;&lt;li&gt;Ability&amp;nbsp;to make someone else the presenter without reconnecting&lt;/li&gt;&lt;li&gt;Easy way to schedule future meetings&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Cons: (Based on Meeting Center)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No way to register for a meeting.&lt;/li&gt;&lt;li&gt;No way to see reports on who attended after meeting.&lt;/li&gt;&lt;li&gt;Interface seemed to get in the way more than I wanted.&lt;/li&gt;&lt;li&gt;Had Problems starting a 2nd Meeting after first trial meeting.&lt;/li&gt;&lt;li&gt;Users Joining meeting were prompted to join 14 day trial (Our attendees are not&amp;nbsp;their&amp;nbsp;customers!)&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;a href="http://office.microsoft.com/en-us/livemeeting/default.aspx"&gt;LiveMeeting&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Price: &amp;nbsp;$22.50/Month&amp;nbsp;&lt;b&gt;&amp;nbsp;(&lt;/b&gt;$4.50 per user per month min 5 Users)&lt;br /&gt;Initially&amp;nbsp;this was confusing but figured it out. &amp;nbsp;Each&amp;nbsp;Organizer&amp;nbsp;need a license, attendees don't so the&amp;nbsp;minimum&amp;nbsp;license count will work for our situation)&lt;br /&gt;Max attendees: 250 (Can get up to 1250 if you pay $16 per User)&lt;br /&gt;&lt;div&gt;&lt;strong&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;/span&gt;&lt;/strong&gt;OS Supported: Windows, any Java supported OS (Java Version does not support VOIP)&lt;/div&gt;Trial Length: 30 Days (It's all of Microsoft on-line services, not just LiveMeeting)&lt;br /&gt;&lt;b&gt;Pros:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Price is very good.&lt;/li&gt;&lt;li&gt;Ability to Show or Hide Attendee List&lt;/li&gt;&lt;li&gt;Ability to allow Users to Create own Personal Recording&lt;/li&gt;&lt;li&gt;Optional Pre Registration&amp;nbsp;&lt;/li&gt;&lt;li&gt;Embarcadero Uses it for CodeRage so people are familiar with it.&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Organizers are required to use a &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=5c2ca866-4107-4ae5-98d5-76bf1b18ff87&amp;amp;displaylang=en"&gt;Sign In Application&lt;/a&gt;, that reconfigures Outlook.&lt;/li&gt;&lt;li&gt;Most Difficult (As an Organizer) to get setup initially &lt;/li&gt;&lt;li&gt;Web Version does not support VOIP / Clients must Download Live Meeting to get VOIP&lt;/li&gt;&lt;li&gt;Only supports External Phone Conferencing Providers, not provided by Default.&lt;/li&gt;&lt;li&gt;If I allow all attendees to have MIC access, I can't control the Mute.&amp;nbsp;&amp;nbsp; They can unmute themselves at will.&amp;nbsp; You can mute everyone but yourself but they can turn around and unmute immediately. &lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: large;"&gt;&lt;a href="http://www.dimdim.com/"&gt;&lt;strong&gt;DimDim&lt;/strong&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;Price: $75/Month (DimDim Webinar Version)&amp;nbsp;(There is a Free version for 20 or less attendees)&lt;br /&gt;Max Attendees: 1000 &lt;br /&gt;OS Supported: Windows, Mac, and&amp;nbsp;Modern Browser that supports Flash.&lt;br /&gt;Trial Length: 30 Days&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Optional Public Group Chat&lt;/li&gt;&lt;li&gt;Poor Support for Question and Answers, Private Chat was the only option.&lt;/li&gt;&lt;li&gt;Registration Support&lt;/li&gt;&lt;li&gt;Phone or VIOP Support&lt;/li&gt;&lt;li&gt;Price for smaller meetings&lt;/li&gt;&lt;li&gt;Cool count down timer and Registration Widget to embed on site later&lt;/li&gt;&lt;li&gt;Open API for setup of Meetings. (although: Lacked in Meeting API controls)&lt;/li&gt;&lt;li&gt;Will host Recordings&lt;/li&gt;&lt;li&gt;Shared Browsing Feature&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Speed of switching content views.&lt;/li&gt;&lt;li&gt;Only can share whole desktop.&amp;nbsp; Annoying Red box around screen.&lt;/li&gt;&lt;li&gt;No built in Polling&lt;/li&gt;&lt;li&gt;Registration Required Field are not changable (I don't care about phone number but DimDim makes it required)&lt;/li&gt;&lt;li&gt;Several Support Forums, with no clear direction where to go.&amp;nbsp; They&amp;nbsp;were confusing at best.&lt;/li&gt;&lt;li&gt;Recording&amp;nbsp;will&amp;nbsp;not record everything, currently does not support white board or shared browsing&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Common Problems regardless of option:&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Unable to Broadcast PC Audio without setting up, Sound Mix and disabling your Mic or using a second PC/Mixer Board.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/li&gt;&lt;/ul&gt;Right now&amp;nbsp;I am leaning to LiveMeeting because of price, but my favorite is GotoWebinar, its features are far more robust and would go along way in making the session seem more like a local user group meeting.&lt;br /&gt;&lt;br /&gt;I am interested in feedback on those that have experience in using these technologies or other options I did not review.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Update:&amp;nbsp; Added DimDim to the list of products reviewed&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-5969033985051807511?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/5969033985051807511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/04/virtual-user-group-options.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5969033985051807511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5969033985051807511'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/04/virtual-user-group-options.html' title='Virtual User Group Options'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-6684334716380216529</id><published>2010-02-14T01:00:00.004-07:00</published><updated>2010-02-14T01:00:02.734-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='About Rob'/><title type='text'>Happy 15th Birthday Delphi - My Delphi Story</title><content type='html'>&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;On&amp;nbsp;February 14, 1995 the first version of Delphi was released. &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Little did I know how much this would affect my life. &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_IkAwJdQc39w/S3ZY9fhL8hI/AAAAAAAAMgI/rVdRVR2ZXng/s1600-h/180px-Turbo_pascal_30_cover.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/_IkAwJdQc39w/S3ZY9fhL8hI/AAAAAAAAMgI/rVdRVR2ZXng/s200/180px-Turbo_pascal_30_cover.jpg" width="127" /&gt;&lt;/a&gt;I had learned to program using Apple II Basic in grade school. &amp;nbsp; &amp;nbsp;In high school, I was able to enroll in the AP computer science program. &amp;nbsp; At that time it was taught using Turbo Pascal 3.3. &amp;nbsp;&amp;nbsp;I don't really remember when I purchased my first compiler, but I do know that it was TP 5.5. &amp;nbsp; During high school I started writing shareware programs using TP 5.5 for the &lt;a href="http://en.wikipedia.org/wiki/Virtual_Advanced"&gt;VBBS System&lt;/a&gt;. &amp;nbsp; I earned enough money to support my newly formed programming habit. &amp;nbsp; I purchased many of the&amp;nbsp;libraries&amp;nbsp;offered by &lt;a href="http://www.turbopower.com/"&gt;TurboPower&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I graduated from High School in 1992, I enrolled in college with a major in Theater :-) &amp;nbsp; &amp;nbsp;Little did I realize that little habit of mine was going to change the course of my life. &amp;nbsp;While in college I started working&amp;nbsp;as a tech support specialist for &lt;a href="http://en.wikipedia.org/wiki/Prodigy_(online_service)"&gt;Prodigy&lt;/a&gt;&amp;nbsp;after a short period I was promoted helping manage the LAN with both desktop and server support. &amp;nbsp;We were running in an OS/2&amp;nbsp;environment&amp;nbsp;and took my first look at C to help manage many of the things we needed to do. &amp;nbsp; I was successful but I realized I did not like the language, as much as I did with Pascal. &amp;nbsp; During this time, I was fairly active reader of the &lt;a href="http://en.wikipedia.org/wiki/CompuServe"&gt;Compuserve&lt;/a&gt; Forums for both Borland and TurboPower allowing me to learn of a new product. &amp;nbsp;&amp;nbsp;I purchase &lt;a href="http://www.embarcadero.com/products/delphi"&gt;Delphi&lt;/a&gt;&amp;nbsp;the moment it came out, I also started attending the&amp;nbsp;&lt;a href="http://www.slcdug.org/"&gt;Salt Lake City Delphi users group&lt;/a&gt;. &amp;nbsp; &amp;nbsp;At one of the meetings I met, &amp;nbsp;my soon to be future boss, who was looking for a programmer. &amp;nbsp; The company was very small operating out of a home that was converted into an office. &amp;nbsp;I did the programming for an application that manged the bookings for timeshare properties. &amp;nbsp;It was also far enough away from my school that I had to drop out of college.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_IkAwJdQc39w/S3ZWtpQMI-I/AAAAAAAAMgA/wtKfV-gQuX4/s1600-h/Delphi2010.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_IkAwJdQc39w/S3ZWtpQMI-I/AAAAAAAAMgA/wtKfV-gQuX4/s320/Delphi2010.jpg" /&gt;&lt;/a&gt;Wanting to continually improve my programming skills I attended Software and Development West in San Fransisco. &amp;nbsp; There I found the Borland booth, and I ran into the Interbase marketing manager. &amp;nbsp; I told him about the work we had done with the Interbase API to make things faster and avoid the BDE. &amp;nbsp; &amp;nbsp; I told him how we had developed UDFs for InterBase using Delphi. &amp;nbsp; I remember him saying: &amp;nbsp;I did not think you could do that, do you want to come speak about what you have done at our conference. &amp;nbsp; &amp;nbsp;A week or two later I contacted him and said yes to the offer to speak at the conference. &amp;nbsp; &amp;nbsp; I was going to be surprised, I was still a very green&amp;nbsp;programmer and I had never had attended a Borland Conference before. &amp;nbsp; &amp;nbsp;I don't remember much about the conference materials. &amp;nbsp;I do however remember the way I felt during the session I presented. &amp;nbsp;I had written a couple of very large white papers on the subject, so I felt prepared. &amp;nbsp; I also felt very young and scared. When it came time for the question and answers section of &amp;nbsp;my sessions, I was blown away many of the questions were WAY over my head. &amp;nbsp; &amp;nbsp;I don't really know how I scored with the attendees of that session but I do know it took a few years to be accepted to speak at any future conferences. &lt;br /&gt;&lt;br /&gt;The big benefit was I had the conference on my resume, I started looking for a new job one that would allow me to expanding my programming abilities and pay more. &amp;nbsp; &amp;nbsp; I had 5 different job offers, &amp;nbsp;I took a job with a local consulting company which more than doubled my current pay. &amp;nbsp; It was an awesome job because the Delphi market was huge. &amp;nbsp; I worked for so many different clients in the next two years I lost count. &amp;nbsp; I specialized in going into new locations that was experiencing bugs in there code and helping them debug there code and resolve what appeared to be random access violation errors. &amp;nbsp; &amp;nbsp;During this time I took over as the President of the Salt Lake City Delphi users group, which I still do to this day. &lt;br /&gt;&lt;br /&gt;In 1998 my life was changing even more, I had found the love of my life and was married. &amp;nbsp;At the same time I could see the market for&amp;nbsp;Delphi&amp;nbsp;opportunities&amp;nbsp;was starting to dry up, so I took something more stable, or so I thought. &amp;nbsp; I then took two jobs in a row where I was laid off as business directions changed. &amp;nbsp; &amp;nbsp;After the second lay off I decided the consulting&amp;nbsp;business&amp;nbsp;was just as stable and paid more. &amp;nbsp; &amp;nbsp; I had a three clients, the &lt;a href="http://dts.utah.gov/"&gt;State of Utah&lt;/a&gt;,&amp;nbsp;&lt;a href="http://www.borland.com/"&gt;Borland&lt;/a&gt;, and a small&amp;nbsp;embedded&amp;nbsp;software&amp;nbsp;developer. &amp;nbsp;The Borland contract, was awesome I was working with some of the people I had admired over the years. &amp;nbsp; However at one point in 2005 all three clients were asking for my services at least full time at the same time. &amp;nbsp;Instead of refusing work, &amp;nbsp;I tried to keep it up, but after about 4 months I crashed and burned. &amp;nbsp; It took months to fully recover, I was forced to quit all but one of the contracts. &amp;nbsp;The one contract I kept was with the State of Utah, they offered me a full time job, which I accepted and still work there to this day. &lt;br /&gt;&lt;br /&gt;In July of 2008 I finally enrolled in school again to finish that degree that. Schools no longer teach pascal, so I have been using JavaScript, and Java. &amp;nbsp;But after many assignments Delphi it is still my development product of choice. &lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Just imagine the number of&amp;nbsp;people&amp;nbsp;that have been supported by income generated from working with Delphi. &amp;nbsp;Delphi &amp;nbsp;has supported my family from the beginning and hopefully well into the future.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;To the point... I&amp;nbsp;want to wish a happy 15th&amp;nbsp;Birthday to Delphi. &amp;nbsp; &amp;nbsp;I want to thank all of the people behind the product for the dramatic way they have affected my life!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Secondary point of the story:&lt;br /&gt;In 15 years I have personally been responsible for purchases of more than 100 different licenses of Delphi. &amp;nbsp; If I had not been able to afford Turbo Pascal, I would have been forced to go another direction. &amp;nbsp;My entry level&amp;nbsp;investment&amp;nbsp;in 1990's in Turbo Pascal resulted in way over 100k of Delphi revenue stream. &amp;nbsp; &amp;nbsp; &amp;nbsp;It's time to find away back into the entry level market.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-6684334716380216529?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/6684334716380216529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/02/happy-15th-birthday-delphi-my-delphi.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6684334716380216529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6684334716380216529'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/02/happy-15th-birthday-delphi-my-delphi.html' title='Happy 15th Birthday Delphi - My Delphi Story'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_IkAwJdQc39w/S3ZY9fhL8hI/AAAAAAAAMgI/rVdRVR2ZXng/s72-c/180px-Turbo_pascal_30_cover.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-9206297733136252678</id><published>2010-01-28T19:43:00.001-07:00</published><updated>2010-01-28T19:44:42.831-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>An Object Binding Prototype</title><content type='html'>I have been really looking for good ways to keep the different layers of our application bound together.  As such I have been looking at others code, searching out libraries, and building prototypes.&lt;br /&gt;&lt;br /&gt;One such prototype I have built, is fairly simple.  While, I am not sold on using this as a method for binding, I think its worth sharing.  It requires Delphi 2010, and uses the enhanced&lt;br /&gt;RTTI.&lt;br /&gt;&lt;br /&gt;First off the TObjectBinder code can be downloaded from &lt;a href="http://code.google.com/p/robstechcorner/source/browse/branches/rttiwork/ObjBinder.pas"&gt;SVN Repository in my RTTIWork Branch&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Say you have class such as this one:&lt;br /&gt;&lt;pre class="brush:delphi"&gt;TPerson = class(TObject)&lt;br /&gt;  FirstName : String;&lt;br /&gt;  LastName : String;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To use this code all you need to tie this object to your user interface is this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;  // Create Binding with Class you want as the source of the binding&lt;br /&gt;  Binding := TObjectBinder.Create(TPerson);&lt;br /&gt;  // Binding() Parameters&lt;br /&gt;  // First: Property or Field of Class passed to the Constructor&lt;br /&gt;  // Second: Object you want as the destination of the binding.&lt;br /&gt;  // Third:  Property or Field of the Destination you want to bind too&lt;br /&gt;  // Fourth: If the binding is readonly(Optional: Default False)&lt;br /&gt;  // Fifth: ITypeMapping Interface (Optional: Default NIL) more on this later.&lt;br /&gt;  Binding.Binding('FirstName',Edit1,'Text');&lt;br /&gt;  Binding.Binding('LastName',Edit2,'Text');&lt;br /&gt;  // Then there are two key methods you can use after that.&lt;br /&gt;  // Load() takes the contents of the Person and populates&lt;br /&gt;  //        Edit1 and Edit2 Controls&lt;br /&gt;  Binding.Load(Person); // Where Person is an instance of TPerson&lt;br /&gt;  // This takes the contents of Edit1 and Edit2 and Saves it back to the person.&lt;br /&gt;  Binding.Save(Person);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What does this offer, allows you create a list of bindings of any property of any object&lt;br /&gt;to any other property of any object.   It reduces code like this...&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;  Edit1.Text := Person.FirstName;&lt;br /&gt;  Edit2.Text := Person.LastName;&lt;br /&gt;  ...&lt;br /&gt;  Person.FirstName := Edit1.Text;&lt;br /&gt;  Person.LastName := Edit1.Text;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I have buttons that need to be enabled only when the data changes, so I also implemented&lt;br /&gt;&lt;pre class="brush:delphi"&gt;Button1.Enabled := Binding.IsChanged(Person);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Since mappings may need to change data types, I created the following interface&lt;br /&gt;to allow you to specify conversion methods and supply them.  &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;  ITypeMapping = interface&lt;br /&gt;     function SourceToDest(Source : TValue) : TValue;&lt;br /&gt;     function DestToSource(Source : TValue) : TValue;&lt;br /&gt;     function Compare(Source : TValue; Dest : TValue) : Integer;&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Granted, if this was more than a prototype I would have built all of the common conversions&lt;br /&gt;and automatically detected which one to use.&lt;br /&gt;&lt;br /&gt;To take this further, I have a need to dynamically create a form that can edit an unknown object.   Similar to what you can do with an Object Inspector, so this might work well to bind &lt;br /&gt;to those dynamically create controls.   Time to build another prototype :-)&lt;br /&gt;&lt;br /&gt;Special thanks to Cobus Kruger for this &lt;a href="http://sourcecodeadventures.wordpress.com/2009/11/18/inducing-the-great-divide/"&gt;great post &lt;/a&gt;  and another option on doing the same thing. &amp;nbsp;In that solution, I did not like having to name my controls to have to match my model. &amp;nbsp; But the basic idea is very similar, and shows off yet another way to use the RTTI and potentially solve the same problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-9206297733136252678?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/9206297733136252678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2010/01/object-binding-prototype.html#comment-form' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/9206297733136252678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/9206297733136252678'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2010/01/object-binding-prototype.html' title='An Object Binding Prototype'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-5445578446577523134</id><published>2009-10-14T03:33:00.005-06:00</published><updated>2009-10-14T04:09:45.895-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>RTTI &amp; XmlSerial.pas Refactoring  - SVN Changes</title><content type='html'>&lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/xmlserial.pas"&gt;XmlSerial.pas&lt;/a&gt; started as really cool demo of what you can do with RTTI in Delphi 2010. Most of the time demo code is an example that should be looked at learned from and thrown away.&lt;br /&gt;&lt;br /&gt;The problem I face is that I need XmlSerial to be far more than a Demo. I need a fully functional serializer that will inter-op with classes using the &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx"&gt;.NET XmlSerializer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After committing a couple of my refactoring changes to make it more than just a demo. I realized that I did not want to keep committing all of my changes to the SVN&lt;br /&gt;&lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/"&gt;Trunk&lt;/a&gt;.&lt;br /&gt;I really want to keep committing code each day that may not even remotely work. I have some major changes in design planned that will require that for a few days.&lt;br /&gt;&lt;br /&gt;So as such I just created a &lt;a href="http://code.google.com/p/robstechcorner/source/browse/#svn/branches/rttiwork"&gt;branch for my RTTI work&lt;/a&gt; if you want to follow that work, while I refactor to provide an elegant and far more supportable framework. When this work stabilizes I will merge the changes back to Trunk.&lt;br /&gt;&lt;br /&gt;Here are the few things that I intend to do to the code:&lt;br /&gt;&lt;br /&gt;For example, I intend to create an Adapter for XML Parsing to allow current use of TxmlDocument to continue, but also allow for other types of Parsing that may not be DOM based to work. Specifically I am doing this because, I am concerned with the speed and memory footprint that is required by DOM.&lt;br /&gt;&lt;br /&gt;I also want to create a set of adapters and factory that will allow things like TList, Dynamic Arrays and TDataset all to look the same to the serialization engine, so I don't have to write custom code in multiple places. Instead I can just delegate that functionality to a class that will hide the implementation details of how the data is stored. I can see this work being used in a variety of applications outside of XML Serialization.   &lt;br /&gt;&lt;br /&gt;Do you have specific needs for XML Serialization?   I would like to know as now is the time to see if I can address them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-5445578446577523134?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/5445578446577523134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/rtti-xmlserialpas-refactoring-svn.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5445578446577523134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5445578446577523134'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/rtti-xmlserialpas-refactoring-svn.html' title='RTTI &amp; XmlSerial.pas Refactoring  - SVN Changes'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-7267381709595611075</id><published>2009-10-08T17:00:00.005-06:00</published><updated>2009-10-08T17:13:45.674-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>Xml Serialization - Control via Attributes</title><content type='html'>The &lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/xmlserial.pas"&gt;XmlSerial.pas&lt;/a&gt; unit now supports the Attributes.  I had to fix a couple of bugs to get it working, just in case you grabbed the copy I posted earlier today.&lt;br /&gt;&lt;br /&gt;Now you can use 4 Different attributes to control XML serialization process. Specifically  XmlRoot, XmlElement, XmlAttribute, and XmlIgnore.   I modified the original class I used in the &lt;a href="http://robstechcorner.blogspot.com/2009/10/xml-serialization-basic-usage.html"&gt;previous XML serialization post&lt;/a&gt; to use these.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;  [XmlRoot('Person')]&lt;br /&gt;  TPerson = class(TObject)&lt;br /&gt;  private&lt;br /&gt;    FLastName: String;&lt;br /&gt;    FBirthday: TDateTime;&lt;br /&gt;    FMiddleName: String;&lt;br /&gt;    FFirstName: String;&lt;br /&gt;    function GetFullName: String;&lt;br /&gt;   published&lt;br /&gt;   public&lt;br /&gt;     [XmlAttribute('First_Name')]&lt;br /&gt;     property FirstName : String read FFirstName write FFirstName;&lt;br /&gt;     [XmlElement('LAST_NAME')]&lt;br /&gt;     property LastName  : String read FLastName  write FLastName;&lt;br /&gt;     [XmlIgnore]&lt;br /&gt;     property MiddleName : String read FMiddleName write FMiddleName;&lt;br /&gt;     property FullName : String read GetFullName;&lt;br /&gt;     property Birthday : TDateTime read FBirthday write FBirthday;&lt;br /&gt;     procedure Save(FileName : String);&lt;br /&gt;     class function Load(FileName : String) : TPerson;&lt;br /&gt;   end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And now the XML that it outputs and imports is:&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;Person First_Name="John"&gt;&lt;br /&gt;   &amp;lt;LAST_NAME&gt;Doe&amp;lt;/LAST_NAME&gt;&lt;br /&gt;   &amp;lt;Birthday&gt;34744&amp;lt;/Birthday&gt;&lt;br /&gt;&amp;lt;/Person&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So basically this mimics the behavior of the same attributes in the XML .NET Serialization.  Although, it does not support namespaces yet.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-7267381709595611075?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/7267381709595611075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/xml-serialization-control-via.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7267381709595611075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7267381709595611075'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/xml-serialization-control-via.html' title='Xml Serialization - Control via Attributes'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-4908481942746395583</id><published>2009-10-08T07:56:00.008-06:00</published><updated>2009-10-08T17:14:08.338-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>Xml Serialization - Basic Usage</title><content type='html'>This post relates to &lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/xmlserial.pas"&gt;XmlSerial.pas&lt;/a&gt; which provides XML serialization and de-serialization using the new RTTI in Delphi 2010.&lt;br /&gt;&lt;br /&gt;This class has been built to serialize any public and published property or Field.&lt;br /&gt;This was done to mimic the behavior found in the .NET Xml Serialization with the goal of having a set of objects that can serialize in .NET using Delphi Prism and Win32 using Delphi 2010.   The complete goals of what I want to accomplish with &lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/xmlserial.pas"&gt;XmlSerial.pas&lt;/a&gt; look at the source code, I detailed out what still needs to be done.&lt;br /&gt;&lt;br /&gt;There are two ways to work with the Xml Serialization, one depends on a Pointer to the Type Information, the other uses Generics to get it form the type specified as a parameter.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;// Method 1:&lt;br /&gt;var&lt;br /&gt; o : TypeIWantToSerailze;&lt;br /&gt; s : TXmlTypeSerializer;&lt;br /&gt; x : TXmlDocument;&lt;br /&gt; v : TValue;&lt;br /&gt;begin&lt;br /&gt;  s := TXmlTypeSerializer.create(TypeInfo(o));&lt;br /&gt;  x := TXmlDocument.Create(Self); // NEVER PASS NIL!!!&lt;br /&gt;  s.Serialize(x,o);&lt;br /&gt;  x.SaveToFile('FileName.txt');&lt;br /&gt;  v := s.Deserialize(x);&lt;br /&gt;  o := v.AsType&amp;lt;TypeIWantToSerailze&gt;;&lt;br /&gt;  x.free;&lt;br /&gt;  s.free;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;// Method 2:&lt;br /&gt;var&lt;br /&gt; o : TypeIWantToSerailze;&lt;br /&gt; s : TXmlSerializer&amp;lt;TypeIWantToSerailze&gt;;&lt;br /&gt; x : TXmlDocument;&lt;br /&gt;begin&lt;br /&gt;  s := TXmlTypeSerializer&amp;lt;TypeIWantToSerailze&gt;.create;&lt;br /&gt;  x := TXmlDocument.Create(Self); // NEVER PASS NIL!!!&lt;br /&gt;  s.Serialize(x,o);&lt;br /&gt;  x.SaveToFile('FileName.txt');&lt;br /&gt;  o := s.Deserialize(x);&lt;br /&gt;  x.free;&lt;br /&gt;  s.free;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And here is the full code showing how to do this using the generic version.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;unit uPerson;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TPerson = class(TObject)&lt;br /&gt;  private&lt;br /&gt;    FLastName: String;&lt;br /&gt;    FBirthday: TDateTime;&lt;br /&gt;    FMiddleName: String;&lt;br /&gt;    FFirstName: String;&lt;br /&gt;    function GetFullName: String;&lt;br /&gt;   published&lt;br /&gt;   public&lt;br /&gt;     property FirstName : String read FFirstName write FFirstName;&lt;br /&gt;     property LastName  : String read FLastName  write FLastName;&lt;br /&gt;     property MiddleName : String read FMiddleName write FMiddleName;&lt;br /&gt;     property FullName : String read GetFullName;&lt;br /&gt;     property Birthday : TDateTime read FBirthday write FBirthday;&lt;br /&gt;     procedure Save(FileName : String);&lt;br /&gt;     class function Load(FileName : String) : TPerson;&lt;br /&gt;   end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;uses&lt;br /&gt; XmlDoc,&lt;br /&gt; Classes,&lt;br /&gt; XmlSerial;&lt;br /&gt;&lt;br /&gt;{ TPerson }&lt;br /&gt;&lt;br /&gt;function TPerson.GetFullName: String;&lt;br /&gt;begin&lt;br /&gt; result := FFirstName + ' ' + FMiddleName + ' ' + FLastName;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;class function TPerson.Load(FileName: String): TPerson;&lt;br /&gt;var&lt;br /&gt;  lSerialize : TXmlSerializer&amp;lt;TPerson&gt;;&lt;br /&gt;  lOwner : TComponent;&lt;br /&gt;  lDoc   : TxmlDocument;&lt;br /&gt;begin&lt;br /&gt;  lOwner := TComponent.Create(nil);  // Required to make TXmlDocument work!&lt;br /&gt;  try&lt;br /&gt;    lDoc := TXmlDocument.Create(lOwner);  // will be freed with lOwner.Free&lt;br /&gt;    lDoc.LoadFromFile(FileName);&lt;br /&gt;    lSerialize := TXmlSerializer&amp;lt;TPerson&gt;.Create;&lt;br /&gt;    try&lt;br /&gt;      result := lSerialize.Deserialize(lDoc);&lt;br /&gt;    finally&lt;br /&gt;      lSerialize.Free;&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    lOwner.Free;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPerson.Save(FileName: String);&lt;br /&gt;var&lt;br /&gt;  lSerialize : TXmlSerializer&amp;lt;TPerson&gt;;&lt;br /&gt;  lOwner : TComponent;&lt;br /&gt;  lDoc   : TxmlDocument;&lt;br /&gt;begin&lt;br /&gt;  lOwner := TComponent.Create(nil);  // Required to make TXmlDocument work!&lt;br /&gt;  try&lt;br /&gt;    lDoc := TXmlDocument.Create(lOwner);  // will be freed with lOwner.Free&lt;br /&gt;    lSerialize := TXmlSerializer&amp;lt;TPerson&gt;.Create;&lt;br /&gt;    try&lt;br /&gt;      lSerialize.Serialize(lDoc,Self);&lt;br /&gt;      lDoc.SaveToFile(FileName);&lt;br /&gt;    finally&lt;br /&gt;      lSerialize.Free;&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    lOwner.Free;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The project that shows how to use this object.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils,&lt;br /&gt;  Windows,&lt;br /&gt;  XmlSerial,&lt;br /&gt;  Forms,&lt;br /&gt;  uPerson in 'uPerson.pas';&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  P : TPerson;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  Application.Initialize;&lt;br /&gt;  P := TPerson.Create;&lt;br /&gt;  try&lt;br /&gt;   P.FirstName := 'John';&lt;br /&gt;   P.MiddleName := 'C';&lt;br /&gt;   P.LastName := 'Doe';&lt;br /&gt;   P.Birthday := EncodeDate(1995,2,14);&lt;br /&gt;   P.Save('C:\test.xml');&lt;br /&gt;  finally&lt;br /&gt;    P.Free;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  p := TPerson.Load('C:\test.xml');&lt;br /&gt;  try&lt;br /&gt;    writeln(P.FullName);&lt;br /&gt;    Writeln(DateToStr(P.Birthday));&lt;br /&gt;    Readln;&lt;br /&gt;  finally&lt;br /&gt;    p.Free;&lt;br /&gt;  end;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;John C Doe&lt;br /&gt;2/14/1995&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Current output of the XML file, notice the Date, it's something I want to change, if you check the roadmap in the xmlserial.pas source.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml; gutter: false"&gt;&lt;br /&gt;&amp;lt;TPerson&gt;&lt;br /&gt;   &amp;lt;FirstName&gt;John&amp;lt;/FirstName&gt;&lt;br /&gt;   &amp;lt;LastName&gt;Doe&amp;lt;/LastName&gt;&lt;br /&gt;   &amp;lt;MiddleName&gt;C&amp;lt;/MiddleName&gt;&lt;br /&gt;   &amp;lt;Birthday&gt;34744&amp;lt;/Birthday&gt;&lt;br /&gt;&amp;lt;/TPerson&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hopefully this covers enough of how to use this to get you started.&lt;br /&gt;I will show how to customize the behavior using attributes in a future post.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-4908481942746395583?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/4908481942746395583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/xml-serialization-basic-usage.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4908481942746395583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4908481942746395583'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/xml-serialization-basic-usage.html' title='Xml Serialization - Basic Usage'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-3829330674743610371</id><published>2009-10-08T06:05:00.012-06:00</published><updated>2009-10-08T10:58:59.042-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>INI persistence the RTTI way</title><content type='html'>This post is based around the &lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/IniPersist.pas"&gt;IniPersit.pas&lt;/a&gt; code that I just released.&lt;br /&gt;&lt;br /&gt;I commonly create configuration classes to create a common and easy way to access information stored in INI, Registry, or XML.  In these examples I will show how I used the new RTTI and Attributes in Delphi 2010 to provide a new way of creating a configuration class that access information stored in an INI file.&lt;br /&gt;&lt;br /&gt;Lets first start off showing how to use the New Unit, then we can pull back the covers and show how it works.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;unit ConfigSettings;&lt;br /&gt;interface&lt;br /&gt;uses&lt;br /&gt;  IniPersist;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TConfigSettings = class (TObject)&lt;br /&gt;  private&lt;br /&gt;    FConnectString: String;&lt;br /&gt;    FLogLevel: Integer;&lt;br /&gt;    FLogDirectory: String;&lt;br /&gt;    FSettingsFile: String;&lt;br /&gt;  public&lt;br /&gt;    constructor create;&lt;br /&gt;    // Use the IniValue attribute on any property or field&lt;br /&gt;    // you want to show up in the INI File.&lt;br /&gt;    [IniValue('Database','ConnectString','')]&lt;br /&gt;    property ConnectString : String read FConnectString write FConnectString;&lt;br /&gt;    [IniValue('Logging','Level','0')]&lt;br /&gt;    property LogLevel : Integer read FLogLevel write FLogLevel;&lt;br /&gt;    [IniValue('Logging','Directory','')]&lt;br /&gt;    property LogDirectory : String read FLogDirectory write FLogDirectory;&lt;br /&gt;&lt;br /&gt;    property SettingsFile : String read FSettingsFile write FSettingsFile;&lt;br /&gt;    procedure Save;&lt;br /&gt;    procedure Load;&lt;br /&gt;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;uses SysUtils;&lt;br /&gt;&lt;br /&gt;{ TApplicationSettings }&lt;br /&gt;&lt;br /&gt;constructor TConfigSettings.create;&lt;br /&gt;begin&lt;br /&gt;  FSettingsFile := ExtractFilePath(ParamStr(0)) +  'settings.ini';&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TConfigSettings.Load;&lt;br /&gt;begin&lt;br /&gt;// This loads the INI File Values into the properties.&lt;br /&gt;   TIniPersist.Load(FSettingsFile,Self);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TConfigSettings.Save;&lt;br /&gt;begin&lt;br /&gt;// This saves the properties to the INI&lt;br /&gt;   TIniPersist.Save(FSettingsFile,Self);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;program Project13;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils,&lt;br /&gt;  IniPersist,&lt;br /&gt;  ConfigSettings;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  Settings : TConfigSettings;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;    Settings := TConfigSettings.Create;&lt;br /&gt;    try&lt;br /&gt;      Settings.ConnectString := '\\127.0.0.1\DB:2032';&lt;br /&gt;      Settings.LogLevel := 3;&lt;br /&gt;      Settings.LogDirectory := 'C:\Log';&lt;br /&gt;      Settings.Save;&lt;br /&gt;    finally&lt;br /&gt;      Settings.Free;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;    Settings := TConfigSettings.Create;&lt;br /&gt;    try&lt;br /&gt;    Settings.Load;&lt;br /&gt;    WriteLn(Settings.ConnectString);&lt;br /&gt;    Writeln(Settings.LogLevel);&lt;br /&gt;    Writeln(Settings.LogDirectory);&lt;br /&gt;    finally&lt;br /&gt;      Settings.Free;&lt;br /&gt;    end;&lt;br /&gt;    Readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;\\127.0.0.1\DB:2032&lt;br /&gt;3&lt;br /&gt;C:\Log&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Resulting INI File:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;[Database]&lt;br /&gt;ConnectString=\\127.0.0.1\DB:2032&lt;br /&gt;[Logging]&lt;br /&gt;Level=3&lt;br /&gt;Directory=C:\Log&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see by the above code there really is not much too it, if you want a field or a property to be stored in the INI File, you just need to add the IniValue Attribute.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;  TExampleClass = class (TObject)&lt;br /&gt;  private&lt;br /&gt;    FConnectString: String;&lt;br /&gt;  public&lt;br /&gt;    [IniValue('Database','ConnectString')]&lt;br /&gt;    property ConnectString : String read FConnectString write FConnectString;&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The constructor of the INIValue allows you to specify the Section, Name you the field or Property stored in.   It also allows you to specify a default value if the name &amp; section did not exist in the INI File.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;  IniValueAttribute = class(TCustomAttribute)&lt;br /&gt;  private&lt;br /&gt;    FName: string;&lt;br /&gt;    FDefaultValue: string;&lt;br /&gt;    FSection: string;&lt;br /&gt;  published&lt;br /&gt;     constructor Create(const aSection : String;const aName : string;const aDefaultValue : String = '');&lt;br /&gt;     property Section : string read FSection write FSection;&lt;br /&gt;     property Name : string read FName write FName;&lt;br /&gt;     property DefaultValue : string read FDefaultValue write FDefaultValue;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;constructor IniValueAttribute.Create(const aSection, aName, aDefaultValue: String);&lt;br /&gt;begin&lt;br /&gt;  FSection := aSection;&lt;br /&gt;  FName := aName;&lt;br /&gt;  FDefaultValue := aDefaultValue;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So the magic is really contained in TIniPersist&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;  TIniPersist = class (TObject)&lt;br /&gt;  private&lt;br /&gt;    class procedure SetValue(aData : String;var aValue : TValue);&lt;br /&gt;    class function GetValue(var aValue : TValue) : String;&lt;br /&gt;    class function GetIniAttribute(Obj : TRttiObject) : IniValueAttribute;&lt;br /&gt;  public&lt;br /&gt;    class procedure Load(FileName : String;obj : TObject);&lt;br /&gt;    class procedure Save(FileName : String;obj : TObject);&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The load and save methods are nearly identical, so lets take a look at load.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;class procedure TIniPersist.Load(FileName: String; obj: TObject);&lt;br /&gt;var&lt;br /&gt; ctx : TRttiContext;&lt;br /&gt; objType : TRttiType;&lt;br /&gt; Field : TRttiField;&lt;br /&gt; Prop  : TRttiProperty;&lt;br /&gt; Value : TValue;&lt;br /&gt; IniValue : IniValueAttribute;&lt;br /&gt; Ini : TIniFile;&lt;br /&gt; Data : String;&lt;br /&gt;begin&lt;br /&gt; ctx := TRttiContext.Create;&lt;br /&gt; try&lt;br /&gt;   Ini := TIniFile.Create(FileName);&lt;br /&gt;   try&lt;br /&gt;     objType := ctx.GetType(Obj.ClassInfo); &lt;br /&gt;     for Prop in objType.GetProperties do&lt;br /&gt;     begin&lt;br /&gt;       IniValue := GetIniAttribute(Prop);&lt;br /&gt;       if Assigned(IniValue) then&lt;br /&gt;       begin&lt;br /&gt;          Data := Ini.ReadString(IniValue.Section,IniValue.Name,IniValue.DefaultValue);&lt;br /&gt;          Value := Prop.GetValue(Obj);&lt;br /&gt;          SetValue(Data,Value);&lt;br /&gt;          Prop.SetValue(Obj,Value);&lt;br /&gt;       end;&lt;br /&gt;     end;&lt;br /&gt;     for Field in objType.GetFields do&lt;br /&gt;     begin&lt;br /&gt;       IniValue := GetIniAttribute(Field);&lt;br /&gt;       if Assigned(IniValue) then&lt;br /&gt;       begin&lt;br /&gt;          Data := Ini.ReadString(IniValue.Section,IniValue.Name,IniValue.DefaultValue);&lt;br /&gt;          Value := Field.GetValue(Obj);&lt;br /&gt;          SetValue(Data,Value);&lt;br /&gt;          Field.SetValue(Obj,Value);&lt;br /&gt;       end;&lt;br /&gt;     end;&lt;br /&gt;   finally&lt;br /&gt;     Ini.Free;&lt;br /&gt;   end;&lt;br /&gt; finally&lt;br /&gt;   ctx.Free;&lt;br /&gt; end;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So you can see we basically loop through all the properties and field check for an Attribute, if it exists we get the current value which sets the TypeInfo in the TValue object.    Then we assign the string returned from the INI file into the TValue and call SetValue() &lt;br /&gt;&lt;br /&gt;Lets look at the two methods called.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;  class procedure SetValue(aData : String;var aValue : TValue);&lt;br /&gt;  class function GetIniAttribute(Obj : TRttiObject) : IniValueAttribute;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Lets look first at SetValue().   You will see that it depends on the TypeInfo being present in the TValue being passed in.  We check the TValue and perform the conversions required to convert the String to the Correct Type before storing it&lt;br /&gt;into the TValue.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;class procedure TIniPersist.SetValue(aData: String;var aValue: TValue);&lt;br /&gt;var&lt;br /&gt; I : Integer;&lt;br /&gt;begin&lt;br /&gt; case aValue.Kind of&lt;br /&gt;   tkWChar,&lt;br /&gt;   tkLString,&lt;br /&gt;   tkWString,&lt;br /&gt;   tkString,&lt;br /&gt;   tkChar,&lt;br /&gt;   tkUString : aValue := aData;&lt;br /&gt;   tkInteger,&lt;br /&gt;   tkInt64  : aValue := StrToInt(aData);&lt;br /&gt;   tkFloat  : aValue := StrToFloat(aData);&lt;br /&gt;   tkEnumeration:  aValue := TValue.FromOrdinal(aValue.TypeInfo,GetEnumValue(aValue.TypeInfo,aData));&lt;br /&gt;   tkSet: begin&lt;br /&gt;             i :=  StringToSet(aValue.TypeInfo,aData);&lt;br /&gt;             TValue.Make(@i, aValue.TypeInfo, aValue);&lt;br /&gt;          end;&lt;br /&gt;   else raise EIniPersist.Create('Type not Supported');&lt;br /&gt; end;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now lets take a look at GetIniAttribute() the goal of this method is to check to see if a given TRttimember (Field or Property) has the IniValue attribute, and if it does return it, otherwise return NIL.&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;class function TIniPersist.GetIniAttribute(Obj: TRttiObject): IniValueAttribute;&lt;br /&gt;var&lt;br /&gt; Attr: TCustomAttribute;&lt;br /&gt;begin&lt;br /&gt; for Attr in Obj.GetAttributes do&lt;br /&gt; begin&lt;br /&gt;    if Attr is IniValueAttribute then&lt;br /&gt;    begin&lt;br /&gt;      exit(IniValueAttribute(Attr));  // Exit with a parameter new in Delphi 2010&lt;br /&gt;    end;&lt;br /&gt; end;&lt;br /&gt; result := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So all in all, its really not much code, and it make usage simple.  Now granted TIniValue is not all that complex, but this situation could be applied to a variety of other applications.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-3829330674743610371?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/3829330674743610371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/ini-persistence-rtti-way.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3829330674743610371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3829330674743610371'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/ini-persistence-rtti-way.html' title='INI persistence the RTTI way'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-5113980516733916921</id><published>2009-10-08T05:51:00.003-06:00</published><updated>2009-10-08T06:04:48.766-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeRage'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>RTTI - Practical Examples</title><content type='html'>Well it took a lot longer than I wanted to get this code out.&lt;br /&gt;&lt;br /&gt;There were many more rough edges than I wanted, but after some gentle and firm requests I realized I needed to get this out before the rough edges are finished.&lt;br /&gt;&lt;br /&gt;Specifically the &lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/xmlserial.pas"&gt;XmlSerial.pas&lt;/a&gt; has a road map in source code detailing what I still need to get done.&lt;br /&gt;&lt;br /&gt;What is released:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/IniPersist.pas"&gt;IniPersist.pas&lt;/a&gt; Allows easy mapping of properties and fields to an INI File.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/xmlserial.pas"&gt;XmlSerial.pas&lt;/a&gt; Object and Record Serialization and De-serialization to XML&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/ObjDS.pas"&gt;ObjDs.pas&lt;/a&gt;  Read-only mapping of Objects to TClientDataSets.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/rtti/RttiUtils.pas"&gt;RttiUtils.pas&lt;/a&gt;  Things to help with common RTTI needs.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;How to get the code:&lt;br /&gt;  Follow the above links to each unit, or just use &lt;a href="http://code.google.com/p/robstechcorner/source/checkout"&gt;SVN&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;I am now working on some blog posts to show the how to use this code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-5113980516733916921?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/5113980516733916921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/rtti-practical-examples.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5113980516733916921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5113980516733916921'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/10/rtti-practical-examples.html' title='RTTI - Practical Examples'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-4472033879235790147</id><published>2009-09-22T14:25:00.006-06:00</published><updated>2009-09-22T14:30:35.868-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>TValue in Depth</title><content type='html'>TValue is one of the key Types in the new RTTI System.   We already covered some of the basics in the &lt;a href="http://robstechcorner.blogspot.com/2009/09/introduction-to-tvalue.html"&gt;introduction to TValue&lt;/a&gt;.    It's now time to pull back the covers and explorer how it was designed so you can exploit the entire power of TValue.    &lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Before we get too far, lets take a look at the field in the interface of TValue.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;  TValue = record&lt;br /&gt;   ... &lt;br /&gt;  private&lt;br /&gt;    FData: TValueData;&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Since TValue can store data from any type.   I was interested in how this accomplished,  it proved useful&lt;br /&gt;in determining how to store data from various unknown types I knew I would be throwing at it in the future.&lt;br /&gt;&lt;br /&gt;TValueData is defined as:&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;  TValueData = record&lt;br /&gt;    FTypeInfo: PTypeInfo;&lt;br /&gt;    // If interface, then a hard-cast of interface to IInterface.&lt;br /&gt;    // If heap data (such as string, managed record, array, etc.) then IValueData&lt;br /&gt;    // hard-cast to IInterface.&lt;br /&gt;    // If this is nil, then the value hasn't been initialized and is empty.&lt;br /&gt;    FHeapData: IInterface;&lt;br /&gt;    case Integer of&lt;br /&gt;      0: (FAsUByte: Byte);&lt;br /&gt;      1: (FAsUWord: Word);&lt;br /&gt;      2: (FAsULong: LongWord);&lt;br /&gt;      3: (FAsObject: TObject);&lt;br /&gt;      4: (FAsClass: TClass);&lt;br /&gt;      5: (FAsSByte: Shortint);&lt;br /&gt;      6: (FAsSWord: Smallint);&lt;br /&gt;      7: (FAsSLong: Longint);&lt;br /&gt;      8: (FAsSingle: Single);&lt;br /&gt;      9: (FAsDouble: Double);&lt;br /&gt;      10: (FAsExtended: Extended);&lt;br /&gt;      11: (FAsComp: Comp);&lt;br /&gt;      12: (FAsCurr: Currency);&lt;br /&gt;      13: (FAsUInt64: UInt64);&lt;br /&gt;      14: (FAsSInt64: Int64);&lt;br /&gt;      15: (FAsMethod: TMethod);&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It's just a &lt;a href="http://www.delphibasics.co.uk/Article.asp?Name=Records"&gt;variant record&lt;/a&gt;, that takes 24 bytes of memory.&lt;br /&gt;&lt;br /&gt;The key parts are FTypeInfo, and then either FHeapData or one of the variant parts&lt;br /&gt;would be use to store the data.&lt;br /&gt;&lt;br /&gt;Knowing this how this is stored helps in understanding the low level routines to set and access&lt;br /&gt;the data stored in a TValue.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;  TValue = record&lt;br /&gt;    ...&lt;br /&gt;  public&lt;br /&gt;    ...&lt;br /&gt;    // Low-level in&lt;br /&gt;    class procedure Make(ABuffer: Pointer; ATypeInfo: PTypeInfo; out Result: TValue); overload; static;&lt;br /&gt;    class procedure MakeWithoutCopy(ABuffer: Pointer; ATypeInfo: PTypeInfo; out Result: TValue); overload; static;&lt;br /&gt;    class procedure Make(AValue: NativeInt; ATypeInfo: PTypeInfo; out Result: TValue); overload; static;&lt;br /&gt;    &lt;br /&gt;    // Low-level out&lt;br /&gt;    property DataSize: Integer read GetDataSize;&lt;br /&gt;    procedure ExtractRawData(ABuffer: Pointer);&lt;br /&gt;    // If internal data is something with lifetime management, this copies a &lt;br /&gt;    // reference out *without* updating the reference count.&lt;br /&gt;    procedure ExtractRawDataNoCopy(ABuffer: Pointer);&lt;br /&gt;    function GetReferenceToRawData: Pointer;&lt;br /&gt;    function GetReferenceToRawArrayElement(Index: Integer): Pointer;&lt;br /&gt;    ...&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Basically, you can use Make() to place any data with type information into a TValue.&lt;br /&gt;&lt;br /&gt;Here is an example that placed an Integer and TRect in &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses SysUtils, Windows, TypInfo,Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  IntData : Integer;&lt;br /&gt;  IntValue : TValue;&lt;br /&gt;&lt;br /&gt;  RecData : TRect;&lt;br /&gt;  RecValue : TValue;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  IntData := 1234;&lt;br /&gt;  //Granted it's easier to call IntValue := IntData;  but this is an example.&lt;br /&gt;  TValue.Make(@IntData,TypeInfo(Integer),IntValue);&lt;br /&gt;  Writeln(IntValue.ToString);&lt;br /&gt;  RecData.Left := 10;&lt;br /&gt;  RecData.Right := 20;&lt;br /&gt;  TValue.Make(@RecData,TypeInfo(TRect),RecValue);&lt;br /&gt;  Writeln(RecValue.ToString);&lt;br /&gt;  readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;1234&lt;br /&gt;(record)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When dealing with Deserialization issues I realized I had to recreate record structures when I did not know anything but the TypeInfo.   This can be done by calling:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;TValue.Make(nil,TypeInfoVar,OutputTValue);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Extracting data can also be done using the low level routines, here is an example of using ExtractRawData.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses SysUtils, Windows, TypInfo,Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  RecData : TRect;&lt;br /&gt;  RecDataOut : TRect;&lt;br /&gt;  RecValue : TValue;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  RecData.Left := 10;&lt;br /&gt;  RecData.Right := 20;&lt;br /&gt;  TValue.Make(@RecData,TypeInfo(TRect),RecValue);&lt;br /&gt;&lt;br /&gt;  RecValue.ExtractRawData(@RecDataOut);&lt;br /&gt;  Writeln(RecDataOut.Left);&lt;br /&gt;  Writeln(RecDataOut.Right);&lt;br /&gt;&lt;br /&gt;  readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;10&lt;br /&gt;20&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can use things like GetReferenceToRawData() with the SetValue and GetValue on records.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses SysUtils, Windows, TypInfo,Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  RecData : TRect;&lt;br /&gt;  RecValue : TValue;&lt;br /&gt;  Ctx : TRttiContext;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  Ctx := TRttiContext.Create;&lt;br /&gt;  // Create empty record structure&lt;br /&gt;  TValue.Make(nil,TypeInfo(TRect),RecValue);&lt;br /&gt;  // Set the Left and Right Members, using the pointer to the Record&lt;br /&gt;  Ctx.GetType(TypeInfo(TRect)).GetField('Left').SetValue(RecValue.GetReferenceToRawData,10);&lt;br /&gt;  Ctx.GetType(TypeInfo(TRect)).GetField('Right').SetValue(RecValue.GetReferenceToRawData,20);&lt;br /&gt;  // Extract the record to report the results.&lt;br /&gt;  RecValue.ExtractRawData(@RecData);&lt;br /&gt;  Writeln(RecData.Left);&lt;br /&gt;  Writeln(RecData.Right);&lt;br /&gt;  readln;&lt;br /&gt;  Ctx.Free;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;10&lt;br /&gt;20&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;These little examples show how to deal with types that you don't know about at compile time.  However, sometimes you do know the type you will be working with at compile time.   When this is know it becomes much easier to to work with using a the Generic/Parametrized Type functions that TValue Provides:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;    class function From&amp;lt;T&gt;(const Value: T): TValue; static;&lt;br /&gt;    function AsType&amp;lt;T&gt;: T;&lt;br /&gt;    function TryAsType&amp;lt;T&gt;(out AResult: T): Boolean;&lt;br /&gt;    function Cast&amp;lt;T&gt;: TValue; overload;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The following example shows From&amp;lt;T&gt;() IsType&amp;lt;T&gt;() and AsType&amp;lt;T&gt;() in use.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses SysUtils, Windows, TypInfo,Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  RecData : TRect;&lt;br /&gt;  RecDataOut : TRect;&lt;br /&gt;  RecValue : TValue;&lt;br /&gt;begin&lt;br /&gt;  RecData.Left := 10;&lt;br /&gt;  RecData.Right := 20;&lt;br /&gt;&lt;br /&gt;  RecValue := TValue.From&amp;lt;TRect&gt;(RecData);&lt;br /&gt;&lt;br /&gt;  Writeln(RecValue.IsType&amp;lt;TRect&gt;);&lt;br /&gt;&lt;br /&gt;  RecDataOut := RecValue.AsType&amp;lt;TRect&gt;;&lt;br /&gt;&lt;br /&gt;  Writeln(RecDataOut.Left);&lt;br /&gt;  Writeln(RecDataOut.Right);&lt;br /&gt;  readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;TRUE&lt;br /&gt;10&lt;br /&gt;20&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are also other function on TValue that help you with Array Types.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;    function GetArrayLength: Integer;&lt;br /&gt;    function GetArrayElement(Index: Integer): TValue;&lt;br /&gt;    procedure SetArrayElement(Index: Integer; const AValue: TValue);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It should be noted that dynamic arrays that are declared like this are currently not &lt;br /&gt;supported:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;Var&lt;br /&gt;  IntArray : Array of Integer;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But if you can your code to be like this they work fine.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;type &lt;br /&gt;  TIntArray = Array of Integer;&lt;br /&gt;&lt;br /&gt;var &lt;br /&gt;  I : TIntArray;&lt;br /&gt;  // or&lt;br /&gt;  I : TArray&amp;lt;Integer&gt;; {defined in System.pas as:   TArray&amp;lt;T&gt; = array of T;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Another small gotcha is that TValue.FromVariant() is misleading.&lt;br /&gt;&lt;br /&gt;I thought it meant that I would be taking a Variant and stuffing it into the TValue, however you will find that it really is not doing that, it's storing the data using originating type, the following code shows how it behaves.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses SysUtils, TypInfo,Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  vExample : Variant;&lt;br /&gt;  Value : TValue;&lt;br /&gt;begin&lt;br /&gt;  vExample := 'Hello World';&lt;br /&gt;  Value := TValue.FromVariant(vExample);&lt;br /&gt;  writeln(GetEnumName(TypeInfo(TTypeKind),Ord(Value.Kind)));&lt;br /&gt;  Writeln(value.ToString);&lt;br /&gt;&lt;br /&gt;  vExample := 1234;&lt;br /&gt;  Value := TValue.FromVariant(vExample);&lt;br /&gt;  writeln(GetEnumName(TypeInfo(TTypeKind),Ord(Value.Kind)));&lt;br /&gt;  Writeln(value.ToString);&lt;br /&gt;&lt;br /&gt;  readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;tkUString&lt;br /&gt;Hello World&lt;br /&gt;tkInteger&lt;br /&gt;1234&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you want to store a Variant into a TValue you can use this method&lt;br /&gt;&lt;pre class="brush:delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses SysUtils, TypInfo,Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  vExample : Variant;&lt;br /&gt;  Value : TValue;&lt;br /&gt;begin&lt;br /&gt;  vExample := 'Hello World';&lt;br /&gt;  Value := TValue.From&lt;Variant&gt;(vExample);&lt;br /&gt;  writeln(GetEnumName(TypeInfo(TTypeKind),Ord(Value.Kind)));&lt;br /&gt;  Writeln(value.AsType&lt;Variant&gt;);&lt;br /&gt;&lt;br /&gt;  vExample := 1234;&lt;br /&gt;  Value := TValue.From&lt;Variant&gt;(vExample);&lt;br /&gt;  writeln(GetEnumName(TypeInfo(TTypeKind),Ord(Value.Kind)));&lt;br /&gt;  Writeln(value.AsType&lt;Variant&gt;);&lt;br /&gt;&lt;br /&gt;  readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;tkVariant&lt;br /&gt;Hello World&lt;br /&gt;tkVariant&lt;br /&gt;1234&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are also other ways to work with TValue that I just don't have the time to cover. I recommend opening up Rtti.pas and exploring the interface to see everything that is available. The items I failed to cover are fairly straight forward.&lt;br /&gt;&lt;br /&gt;I hope this give's you a good taste of how TValue works.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-4472033879235790147?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/4472033879235790147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/tvalue-in-depth.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4472033879235790147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4472033879235790147'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/tvalue-in-depth.html' title='TValue in Depth'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-8165254744845578841</id><published>2009-09-17T12:37:00.005-06:00</published><updated>2009-09-17T15:40:25.024-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>Exploring TRttiMember Descendants in depth (Part II) Methods</title><content type='html'>Today I will be covering TRttiMethod.  it is the biggest reason I am so happy with the new RTTI in Delphi 2010.   In prior versions of Delphi dynamic method invocation was a black art, that had many limitations.   It was painful and was dependent on how your code was compiled.  The default behavior of the VCL classes had it disabled.  Prior to Delphi 2010 you had to know way too much about the internals of method information structure {$METHODINFO}, to invoke a method dynamically.&lt;br /&gt;&lt;br /&gt;Now in Delphi 2010 with default behavior is that RTTI Information for methods is generated for the public and published sections.    I don't need to know a thing about how the RTTI information is being stored.    There is a very elegant and easy to use API to dynamically query and invoke methods.   Which works for all the existing VCL classes.&lt;br /&gt;&lt;br /&gt;You must understand TRttiMethod and TValue you have the ability to dynamically invoke most any method.&lt;br /&gt;&lt;br /&gt;TRttiMethod descends from TRttiMember,  besides the Name &amp; Visibility which was defined in TRttiMember, we may need to know many other aspects about a given method.&lt;br /&gt;&lt;br /&gt;A few key properties are defined to allow easy access to this information.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;TypInfo.pas&lt;br /&gt;  TMethodKind = (mkProcedure, mkFunction, mkConstructor, mkDestructor,&lt;br /&gt;    mkClassProcedure, mkClassFunction, mkClassConstructor, mkClassDestructor,&lt;br /&gt;    mkOperatorOverload,&lt;br /&gt;    { Obsolete }&lt;br /&gt;    mkSafeProcedure, mkSafeFunction);&lt;br /&gt;&lt;br /&gt;  TCallConv = (ccReg, ccCdecl, ccPascal, ccStdCall, ccSafeCall);&lt;br /&gt;&lt;br /&gt;Rtti.pas&lt;br /&gt;&lt;br /&gt;  TDispatchKind = (dkStatic, dkVtable, dkDynamic, dkMessage, dkInterface);&lt;br /&gt;&lt;br /&gt;In TRttiMember &lt;br /&gt;    property MethodKind: TMethodKind read GetMethodKind;&lt;br /&gt;    property DispatchKind: TDispatchKind read GetDispatchKind;&lt;br /&gt;&lt;br /&gt;    property CodeAddress: Pointer read GetCodeAddress;&lt;br /&gt;    property IsConstructor: Boolean read GetIsConstructor;&lt;br /&gt;    property IsDestructor: Boolean read GetIsDestructor;&lt;br /&gt;    property IsClassMethod: Boolean read GetIsClassMethod;&lt;br /&gt;    // Static: No 'Self' parameter&lt;br /&gt;    property IsStatic: Boolean read GetIsStatic;&lt;br /&gt;&lt;br /&gt;    // Vtable slot for virtual methods.&lt;br /&gt;    // Message index for message methods (non-negative).&lt;br /&gt;    // Dynamic index for dynamic methods (negative).&lt;br /&gt;    property VirtualIndex: Smallint read GetVirtualIndex;&lt;br /&gt;    property CallingConvention: TCallConv read GetCallingConvention;&lt;br /&gt;    property CodeAddress: Pointer read GetCodeAddress;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now this information is fairly useless if you don't know the parameters of a given method and a possible result type, there is a property and a function to provide you with this information.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    function GetParameters: TArray&amp;lt;TRttiParameter&gt;; virtual; abstract;&lt;br /&gt;    property ReturnType: TRttiType read GetReturnType;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here is an example of looking at these, it looks at the TStringList.AddObject() Method &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses&lt;br /&gt;  Classes, Rtti;&lt;br /&gt;var&lt;br /&gt;  ctx : TRttiContext;&lt;br /&gt;  t : TRttiType;&lt;br /&gt;  Param : TRttiParameter;&lt;br /&gt;  AddObjectMethod : TRttiMethod;&lt;br /&gt;begin&lt;br /&gt;  ctx := TRttiContext.Create;&lt;br /&gt;  t := ctx.GetType(TStringList.ClassInfo);&lt;br /&gt;  AddObjectMethod := t.GetMethod('AddObject');&lt;br /&gt;  for Param in AddObjectMethod.GetParameters do&lt;br /&gt;  begin&lt;br /&gt;    Writeln(Param.ToString);&lt;br /&gt;  end;&lt;br /&gt;  Writeln('Returns:', AddObjectMethod.ReturnType.ToString );&lt;br /&gt;  readln;&lt;br /&gt;  ctx.Free;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;S: string&lt;br /&gt;AObject: TObject&lt;br /&gt;Returns:Integer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;TRttiParameter is contains the information you need to know about a given parameter.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;typInfo.pas&lt;br /&gt;...&lt;br /&gt;  TParamFlag = (pfVar, pfConst, pfArray, pfAddress, pfReference, pfOut, pfResult);&lt;br /&gt;  {$EXTERNALSYM TParamFlag}&lt;br /&gt;  TParamFlags = set of TParamFlag;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;Rtti.pas&lt;br /&gt;&lt;br /&gt;TRttiNamedObject&lt;br /&gt;...&lt;br /&gt;    property Name: string read GetName;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;TRttiParameter = class(TRttiNamedObject)&lt;br /&gt;...&lt;br /&gt;    function ToString: string; override;&lt;br /&gt;    property Flags: TParamFlags read GetFlags;&lt;br /&gt;    // ParamType may be nil if it's an untyped var or const parameter.&lt;br /&gt;    property ParamType: TRttiType read GetParamType;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now that you have access to the information for a given method you can call it.&lt;br /&gt;&lt;br /&gt;In this example you can see two calls, on to constructor and another to the Add() method of TStringList.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses&lt;br /&gt;  Classes, Rtti, TypInfo;&lt;br /&gt;var&lt;br /&gt;  ctx : TRttiContext;&lt;br /&gt;  t : TRttiType;&lt;br /&gt;  Param : TRttiParameter;&lt;br /&gt;  AddMethod : TRttiMethod;&lt;br /&gt;  SL : TValue; // Contains TStringList instance&lt;br /&gt;  &lt;br /&gt;begin&lt;br /&gt;  ctx := TRttiContext.Create;&lt;br /&gt;  t := ctx.GetType(TStringList.ClassInfo);&lt;br /&gt;  // Create an Instance of TStringList&lt;br /&gt;  SL := t.GetMethod('Create').Invoke(t.AsInstance.MetaclassType,[]);&lt;br /&gt;  // Invoke "Add" and return string representatino of result.&lt;br /&gt;  Writeln(t.GetMethod('Add').Invoke(SL,['Hello World']).ToString);&lt;br /&gt;  // Write out context.&lt;br /&gt;  Writeln((sl.AsObject as TStringList).Text);&lt;br /&gt;  readln;&lt;br /&gt;  ctx.Free;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false" &gt;&lt;br /&gt;0&lt;br /&gt;Hello World&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are three overloaded versions of Invoke&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    function Invoke(Instance: TObject; const Args: array of TValue): TValue; overload;&lt;br /&gt;    function Invoke(Instance: TClass; const Args: array of TValue): TValue; overload;&lt;br /&gt;    function Invoke(Instance: TValue; const Args: array of TValue): TValue; overload;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the above example you can see I used the TValue and TClass versions, now lets look at a more complex situation using the last overload.&lt;br /&gt;&lt;br /&gt;When dealing with method calls that update the parameters, such as those declared with the "var" syntax, the  the original array you pass in of parameters is updated with the correct changes.&lt;br /&gt;&lt;br /&gt;This program demonstrates how this works:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project12;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses&lt;br /&gt;  Classes, Rtti, TypInfo;&lt;br /&gt;const&lt;br /&gt; AreYouMyMotherISBN = '0-679-89047-5';&lt;br /&gt;type&lt;br /&gt;  TBookQuery = class(TObject)&lt;br /&gt;  public&lt;br /&gt;    function FindBook(ISBN : String;var Title : String) : Boolean;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  function TBookQuery.FindBook(ISBN : String;var Title : String) : Boolean;  &lt;br /&gt;  begin&lt;br /&gt;    Writeln('Checking:',ISBN);&lt;br /&gt;    // Find one of the books, I get to read every night :-)&lt;br /&gt;    if ISBN = AreYouMyMotherISBN then&lt;br /&gt;    begin&lt;br /&gt;      result := true;&lt;br /&gt;      Title := 'Are you my Mother?'&lt;br /&gt;    end&lt;br /&gt;    else &lt;br /&gt;    begin&lt;br /&gt;      Title := '';&lt;br /&gt;      result := false;&lt;br /&gt;    end;  &lt;br /&gt;  end;&lt;br /&gt;  &lt;br /&gt;var&lt;br /&gt;  ctx : TRttiContext;&lt;br /&gt;  BQ : TBookQuery;&lt;br /&gt;  Args : Array Of TValue;&lt;br /&gt;  Param : TRttiParameter;&lt;br /&gt;  FindBook : TRttiMethod;&lt;br /&gt;  SL : TValue; // Contains TStringList instance&lt;br /&gt;  &lt;br /&gt;begin&lt;br /&gt;  ctx := TRttiContext.Create;&lt;br /&gt;  BQ := TBookQuery.Create;&lt;br /&gt;  FindBook := Ctx.GetType(TBookQuery.ClassInfo).GetMethod('FindBook');&lt;br /&gt;&lt;br /&gt;  SetLength(args,2);&lt;br /&gt;  Args[0] := '123';  // an ISBN that won't be found&lt;br /&gt;  Args[1] := '';&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;  // Invoke the Method  &lt;br /&gt;  if FindBook.Invoke(BQ,Args).AsBoolean then&lt;br /&gt;   writeln(args[1].ToString)&lt;br /&gt;  else&lt;br /&gt;   writeln('Not Found');&lt;br /&gt;&lt;br /&gt;  SetLength(args,2);&lt;br /&gt;  Args[0] := AreYouMyMotherISBN;  // an ISBN that will be found&lt;br /&gt;  Args[1] := '';   &lt;br /&gt;&lt;br /&gt;  // Invoke the Method&lt;br /&gt;  if FindBook.Invoke(BQ,Args).AsBoolean then&lt;br /&gt;   writeln(args[1].ToString)&lt;br /&gt;  else&lt;br /&gt;   writeln('Not Found');&lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;  readln;&lt;br /&gt;  BQ.Free;  &lt;br /&gt;  ctx.Free;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false" &gt;&lt;br /&gt;Checking:123&lt;br /&gt;Not Found&lt;br /&gt;Checking:0-679-89047-5&lt;br /&gt;Are you my Mother?&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Updated:&lt;/span&gt;&lt;br /&gt;Well I neglected to be complete when it came to how you can query and access TRttiMethods.   I only showed "GetMethod()" on TRttiType but there are four&lt;br /&gt;ways to get information.   &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    // Get's all of the methods on a given class, with the declared ones first.&lt;br /&gt;    function GetMethods: TArray&amp;lt;TRttiMethod&gt;; overload; virtual; &lt;br /&gt;    // Will return the first method it finds with the given name&lt;br /&gt;    function GetMethod(const AName: string): TRttiMethod; virtual;&lt;br /&gt;    // Will return all of the methods it finds with a given method, so you can deal with overloads.&lt;br /&gt;    function GetMethods(const AName: string): TArray&amp;lt;TRttiMethod&gt;; overload; virtual;&lt;br /&gt;    // Will only get methods declared on the given class, and not on parents.&lt;br /&gt;    function GetDeclaredMethods: TArray&amp;lt;TRttiMethod&gt;; virtual;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's really all there is to using TRttiMethod, if you tried to do this in a prior version of Delphi I am sure you will be very happy with the changes.   If you never tried don't, just move to Delphi 2010 and use the new functionality.   Now you might be why would I use this, well hopefully you will get a taste of that in the practical application articles that are coming soon.   However, in my next Article I will cover TValue in Depth.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-8165254744845578841?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/8165254744845578841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/exploring-trttimember-descendants-in_17.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8165254744845578841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8165254744845578841'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/exploring-trttimember-descendants-in_17.html' title='Exploring TRttiMember Descendants in depth (Part II) Methods'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-4588186423225144213</id><published>2009-09-16T08:09:00.008-06:00</published><updated>2009-09-16T09:21:27.676-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>TRttiContext.Create() &amp; TRttiContext.Free()</title><content type='html'>I thought I needed to take a break from the normal articles to explain why I call&lt;br /&gt;TRttiContext.Create() and TRttiContext.Free()  when in fact you don't need too.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Yes you don't need to do it, but yet I do... Why?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First off lets look at the implementation of both.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;class function TRttiContext.Create: TRttiContext;&lt;br /&gt;begin&lt;br /&gt; Result.FContextToken := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TRttiContext.Free;&lt;br /&gt;begin&lt;br /&gt; FContextToken := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;At first glance there is nothing special, FContextToken is set to NIL in both cases.&lt;br /&gt;&lt;br /&gt;So what does setting FContextToken to NIL really do?&lt;br /&gt;&lt;br /&gt;We all know that Delphi currently does not have any Garbage collection mechanism.  As such having a rich RTTI library that is based on Objects could be problematic.&lt;br /&gt;&lt;br /&gt;In my code an I able to such cool things as...&lt;br /&gt;&lt;br /&gt;c.GetType().GetField().FieldType.ToString&lt;br /&gt;&lt;br /&gt;Without having to set temporary values for each returned object, to free them.&lt;br /&gt;How is this possible without a garbage collector?&lt;br /&gt;&lt;br /&gt;Well under the hood you will find TRttiPool that contains all of the RTTI object that are created.   &lt;br /&gt;When this pool is freed all of the objects created during RTTI calls are then freed.&lt;br /&gt;&lt;br /&gt;The construction and destruction of this pool is controlled by TPoolToken which is the Interface that is stored in FContextToken.&lt;br /&gt;&lt;br /&gt;When the TPoolToken is created and freed, the PoolRefCount is maintained, when it reaches zero the TRttiPool is freed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;So why call .Create() and .Free()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;So lets start with .Create()&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;So it's not like calling this code is a huge overhead, yes sure a record is managed and as such it will be initialized, making the call to set FContextToken redundant.  well sort of...   Although I don't intend every create a pointer to TRttiContext, its possible have the memory space not be initialized as expected, unless you are calling .Create.&lt;br /&gt;&lt;br /&gt;I also can't be sure that the implementation will remain as simple.   It is very possible that additional code could be called at this point.   Keeping my code safe in the future is always critical to me in my designs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Moving on to .Free()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Well, I like to keep my memory foot print clean.  Sure when the TRttiContext variable goes out of scope the exact same behavior will occur.&lt;br /&gt;&lt;br /&gt;Very early on when playing with new RTTI I inadvertently caused an access violation in a TCustomAttribute Descendant destructor.    With the call to .free() it was easier to see what had caused the problem.   Instead of having it occur after the destruction of the Object that had the TRttiContext declared as a field.&lt;br /&gt;&lt;br /&gt;And just to stop the obvious comment.... Yes, I know the &lt;a href="http://docwiki.embarcadero.com/RADStudio/en/Obtaining_the_RTTI_Context"&gt;documentation&lt;/a&gt; say's you don't have to call .Free()  And implies that the technique is important because it insures that all RTTI Objects are cached and reused,  well this would only be true of TRttiContext was declared as a global variable, which I think is a very BAD idea.&lt;br /&gt;&lt;br /&gt;Instead I think you should keep your TRttiContext around as long as you need it, but free it when the time is correct.&lt;br /&gt;&lt;br /&gt;In short... I find it a matter of personal preference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-4588186423225144213?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/4588186423225144213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/trtticontextcreate-trtticontextfree.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4588186423225144213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4588186423225144213'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/trtticontextcreate-trtticontextfree.html' title='TRttiContext.Create() &amp; TRttiContext.Free()'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-1898667475888068241</id><published>2009-09-15T16:24:00.002-06:00</published><updated>2009-09-15T16:27:40.985-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>Exploring TRttiMember Descendants in depth (Part I) Properties and Fields</title><content type='html'>Some types such as classes and records contain "members" such as field, properties and methods.&lt;br /&gt;&lt;br /&gt;RTTI information starts with the TRttiMember which provides 4 bits of information about each Member.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;The name&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Visibility (private,protected,public,published)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The type that the member is associated with&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Attributes associated with that member&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;This example code shows how to access each of these.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project4;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Rtti, TypInfo;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TTest = class(TCustomAttribute)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TBook = class(TObject)&lt;br /&gt;  private&lt;br /&gt;    FTitle: String;&lt;br /&gt;  public&lt;br /&gt;    [TTest]&lt;br /&gt;    property Title : String read FTitle write FTitle;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; m : TRttiMember;&lt;br /&gt;&lt;br /&gt;{ TExample }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  c := TRttiContext.Create;&lt;br /&gt;  m := c.GetType(TBook).GetProperty('Title');&lt;br /&gt;  Writeln('Name:',m.Name);&lt;br /&gt;  Writeln('Visibility:',GetEnumName(TypeInfo(TMemberVisibility),ord(m.Visibility)));&lt;br /&gt;  WriteLn('Parent:',m.Parent.ToString);&lt;br /&gt;  Writeln('First Attribute:',m.GetAttributes[0].ToString);&lt;br /&gt;  writeln;&lt;br /&gt;  m := c.GetType(TBook).GetField('FTitle');&lt;br /&gt;  WriteLn('Name:',m.Name);&lt;br /&gt;  WriteLn('Visibility:',GetEnumName(TypeInfo(TMemberVisibility),ord(m.Visibility)));&lt;br /&gt;  WriteLn('Parent:',m.Parent.ToString);&lt;br /&gt;  readln;&lt;br /&gt;  c.Free;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;Name:Title&lt;br /&gt;Visibility:mvPublic&lt;br /&gt;Parent:TBook&lt;br /&gt;First Attribute:TTest&lt;br /&gt;&lt;br /&gt;Name:FTitle&lt;br /&gt;Visibility:mvPrivate&lt;br /&gt;Parent:TBook&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The two basic TRttiMember descendants I want to cover in this blog post is TRttiField and TRttiPropery.    Both descendants allow you to get and set the values on an Instance of the given type.     They both provide SetValue() and GetValue() methods.&lt;br /&gt;&lt;br /&gt;The following code demonstrates how to use both.   If you missed my &lt;a href="http://robstechcorner.blogspot.com/2009/09/introduction-to-tvalue.html"&gt;Introduction to TValue&lt;/a&gt;&lt;br /&gt;I suggest you take some time to read it as it explains some of the "Magic" behind what is going on here.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Rtti, TypInfo;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&lt;br /&gt;  TBook = class(TObject)&lt;br /&gt;  private&lt;br /&gt;    FTitle: String;&lt;br /&gt;  public&lt;br /&gt;    property Title : String read FTitle write FTitle;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; p : TRttiProperty;&lt;br /&gt; f : TRttiField;&lt;br /&gt; book : TBook;&lt;br /&gt; v : TValue;&lt;br /&gt;begin&lt;br /&gt;  book := TBook.Create;&lt;br /&gt;  try&lt;br /&gt;    c := TRttiContext.Create;&lt;br /&gt;    &lt;br /&gt;    p := c.GetType(TBook).GetProperty('Title');&lt;br /&gt;    p.SetValue(Book,'Go, Dog, Go!');&lt;br /&gt;    v := p.GetValue(Book);&lt;br /&gt;    Writeln('Title:',v.ToString);&lt;br /&gt;&lt;br /&gt;    f := c.GetType(TBook).GetField('FTitle');&lt;br /&gt;    f.SetValue(Book,'Green Eggs and Ham');&lt;br /&gt;    v := f.GetValue(Book);&lt;br /&gt;    Writeln('FTitle:',v.ToString);&lt;br /&gt;&lt;br /&gt;    readln;&lt;br /&gt;    &lt;br /&gt;    c.Free;&lt;br /&gt; &lt;br /&gt;  finally&lt;br /&gt;    Book.Free;&lt;br /&gt;  end;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;Title:Go, Dog, Go!&lt;br /&gt;FTitle:Green Eggs and Ham&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With Properties you have to worry about if they are readable or writable, as attempting to call SetValue on a property that is not writable will produce an EPropReadOnly Exception.    TRttiProperty has two properties "isReadable" and 'isWritable" that allow you to discover how the property was declared.   The following code demonstrates how it works.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Rtti, TypInfo;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&lt;br /&gt;  TBook = class(TObject)&lt;br /&gt;  private&lt;br /&gt;    FTitle: String;&lt;br /&gt;    FUgly: String;&lt;br /&gt;    FAuthor: String;&lt;br /&gt;  public&lt;br /&gt;    property Title : String read FTitle write FTitle; &lt;br /&gt;    property Author : String read FAuthor;  &lt;br /&gt;    property Ugly : String write FUgly;  &lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; p : TRttiProperty;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  c := TRttiContext.Create;&lt;br /&gt;  try&lt;br /&gt;    p := c.GetType(TBook).GetProperty('Title');&lt;br /&gt;    WriteLn('Name:',p.Name);&lt;br /&gt;    Writeln('IsReadable:',p.IsReadable);&lt;br /&gt;    Writeln('IsWritable:',p.IsWritable);&lt;br /&gt;    writeln;&lt;br /&gt;    p := c.GetType(TBook).GetProperty('Author');&lt;br /&gt;    WriteLn('Name:',p.Name);&lt;br /&gt;    Writeln('IsReadable:',p.IsReadable);&lt;br /&gt;    Writeln('IsWritable:',p.IsWritable);&lt;br /&gt;    writeln;&lt;br /&gt;    p := c.GetType(TBook).GetProperty('Ugly');&lt;br /&gt;    WriteLn('Name:',p.Name);&lt;br /&gt;    Writeln('IsReadable:',p.IsReadable);&lt;br /&gt;    Writeln('IsWritable:',p.IsWritable);&lt;br /&gt;    readln;&lt;br /&gt;  finally&lt;br /&gt;    c.Free;&lt;br /&gt;  end;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;Name:Title&lt;br /&gt;IsReadable:TRUE&lt;br /&gt;IsWritable:TRUE&lt;br /&gt;&lt;br /&gt;Name:Author&lt;br /&gt;IsReadable:TRUE&lt;br /&gt;IsWritable:FALSE&lt;br /&gt;&lt;br /&gt;Name:Ugly&lt;br /&gt;IsReadable:FALSE&lt;br /&gt;IsWritable:TRUE&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That pretty much wraps it up for TRttiField and TRttiProperty, in the next&lt;br /&gt;post I will cover TRttiMethod.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-1898667475888068241?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/1898667475888068241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/exploring-trttimember-descendants-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/1898667475888068241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/1898667475888068241'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/exploring-trttimember-descendants-in.html' title='Exploring TRttiMember Descendants in depth (Part I) Properties and Fields'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-8788688487021396617</id><published>2009-09-14T22:54:00.003-06:00</published><updated>2009-09-14T23:02:14.026-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>Introduction to TValue</title><content type='html'>TValue is a new record structure defined in Rtti.pas, it provides the ability to store the value, and type information of an instance of any type.  This can be seen in the following code.&lt;br /&gt;&lt;br /&gt;For example, in the following program, you can see that the TypeInfo property on&lt;br /&gt;a TValue is the same as the what the TypeInfo() function would return for that type.  &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; v : TValue;&lt;br /&gt; i : Integer;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  i := 10;&lt;br /&gt;  v := I;&lt;br /&gt;  Writeln('Address of TypeInfo on TValue :', IntToStr(Integer(v.TypeInfo)));&lt;br /&gt;  Writeln('Address of TypeInfo on Integer:', IntToStr(Integer(TypeInfo(Integer))));&lt;br /&gt;  Writeln('Value of I:',I);&lt;br /&gt;  Writeln('Value of V:',v.AsInteger);&lt;br /&gt;  readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;Address of TypeInfo on TValue :4198560&lt;br /&gt;Address of TypeInfo on Integer:4198560&lt;br /&gt;Value of I:10&lt;br /&gt;Value of V:10&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are several implicit operators defined that allow assignment of these types easy.   If you have a type that is not on this list, don't worry there is a way to handle these, it just want to dedicate a single blog post to how to do this.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    class operator Implicit(const Value: string): TValue;&lt;br /&gt;    class operator Implicit(Value: Integer): TValue;&lt;br /&gt;    class operator Implicit(Value: Extended): TValue;&lt;br /&gt;    class operator Implicit(Value: Int64): TValue;&lt;br /&gt;    class operator Implicit(Value: TObject): TValue;&lt;br /&gt;    class operator Implicit(Value: TClass): TValue;&lt;br /&gt;    class operator Implicit(Value: Boolean): TValue;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are as set of matching functions to get the data out.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    function AsString: string;&lt;br /&gt;    function AsInteger: Integer;&lt;br /&gt;    function AsExtended: Extended;&lt;br /&gt;    function AsInt64: Int64;&lt;br /&gt;    function AsObject: TObject;&lt;br /&gt;    function AsClass: TClass;&lt;br /&gt;    function AsBoolean: Boolean;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Although, this may make you think about the Variant type, conversions from one type to another do not automatically occur.   The following code generates an&lt;br /&gt;EInvalidCast Exception, as the stored type is an Integer and not a string.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; v : TValue;&lt;br /&gt; i : Integer;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  i := 10;&lt;br /&gt;  v := I;&lt;br /&gt;  // Generates and Invalid Type Cast&lt;br /&gt;  Writeln('Value of V:',v.asString);&lt;br /&gt;  readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To help you in determining what type is in a given TValue you have several properties and functions.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt; // in TypInfo.pas&lt;br /&gt; TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat,&lt;br /&gt;    tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString,&lt;br /&gt;    tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray, tkUString,&lt;br /&gt;    tkClassRef, tkPointer, tkProcedure);&lt;br /&gt;&lt;br /&gt; // part of TValue in rtti.pas&lt;br /&gt; property Kind: TTypeKind &lt;br /&gt; function IsObject: Boolean;  &lt;br /&gt; function IsType&amp;lt;T&gt;: Boolean; overload;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;The following shows each of these:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  Rtti,TypInfo;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; v : TValue;&lt;br /&gt; i : Integer;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  i := 10;&lt;br /&gt;  v := I;&lt;br /&gt;  Writeln('V.Kind =',GetEnumName(TypeInfo(TTypeKind),ord(v.Kind)));&lt;br /&gt;  Writeln('V.IsType&amp;lt;Integer&gt; = ',v.IsType&amp;lt;Integer&gt;);&lt;br /&gt;  Writeln('V.IsType&amp;lt;TObject&gt; = ',v.IsType&amp;lt;TObject&gt;);&lt;br /&gt;  Writeln('V.IsObject = ',v.IsObject);&lt;br /&gt;  readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;V.Kind =tkInteger&lt;br /&gt;V.IsType&amp;lt;Integer&gt; = TRUE&lt;br /&gt;V.IsType&amp;lt;TObject&gt; = FALSE&lt;br /&gt;V.IsObject = FALSE&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;TValue has a way more functionality to explore, that I will cover in an in depth article later, but the basics needed to be covered before&lt;br /&gt;moving on to TRttiMember for Properties and Fields which is the next article.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-8788688487021396617?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/8788688487021396617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/introduction-to-tvalue.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8788688487021396617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8788688487021396617'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/introduction-to-tvalue.html' title='Introduction to TValue'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-2855913020120028944</id><published>2009-09-12T08:31:00.004-06:00</published><updated>2009-09-16T12:06:20.836-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>Exploring TRttiType and descendants in Depth</title><content type='html'>TRttiType provides us with an easy to use interface that allows us to the access all of the RTTI Information associated with that type.   For the most part, I find this very intuitive, and self documenting, I recommend opening Rtti.pas and looking at the declaration for TRttiType.    &lt;br /&gt;&lt;br /&gt;I introduced TRttiType in the &lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;previous articles.&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;Like I stated in a prior article, if your type supports, Fields, Properties, and/or Methods.  There are a few easy access method to get access to these.&lt;br /&gt;&lt;br /&gt;These methods provide access to all of the Fields, Properties, and Methods that have RTTI information, in up coming articles I will go in depth on TRttiField, TRttiProperty, and TRttiMethod.&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    function GetMethods: TArray&amp;lt;TRttiMethod&gt;; overload; virtual;&lt;br /&gt;    function GetFields: TArray&amp;lt;TRttiField&gt;; virtual;&lt;br /&gt;    function GetProperties: TArray&amp;lt;TRttiProperty&gt;; virtual;&lt;br /&gt;    &lt;br /&gt;    function GetMethod(const AName: string): TRttiMethod; virtual;&lt;br /&gt;    function GetMethods(const AName: string): TArray&amp;lt;TRttiMethod&gt;; overload; virtual;&lt;br /&gt;    function GetField(const AName: string): TRttiField; virtual;&lt;br /&gt;    function GetProperty(const AName: string): TRttiProperty; virtual;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However, sometimes you one want to access what was declared on that specific type and not in the parent types, this can be done with the following functionality.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    function GetDeclaredMethods: TArray&amp;lt;TRttiMethod&gt;; virtual;&lt;br /&gt;    function GetDeclaredProperties: TArray&amp;lt;TRttiProperty&gt;; virtual;&lt;br /&gt;    function GetDeclaredFields: TArray&amp;lt;TRttiField&gt;; virtual;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If your type supports ancestors, you can get the BaseType through the base type property.&lt;br /&gt;The following code shows how you can walk back up the type tree to find the parent types.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, RTTI;&lt;br /&gt;type&lt;br /&gt;  TOneObject = Class(TObject)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TTwoObject = Class(TOneObject)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TThreeObject = Class(TTwoObject)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; t : TRttiType;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;   c := TRttiContext.Create;&lt;br /&gt;   try&lt;br /&gt;     t := c.GetType(TThreeObject);&lt;br /&gt;     writeln(t.Name);&lt;br /&gt;     while Assigned(t.BaseType) do&lt;br /&gt;     begin&lt;br /&gt;       t := t.BaseType;&lt;br /&gt;       writeln(t.Name);&lt;br /&gt;     end;&lt;br /&gt;   finally&lt;br /&gt;     c.Free&lt;br /&gt;   end;&lt;br /&gt;   readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;TThreeObject&lt;br /&gt;TTwoObject&lt;br /&gt;TOneObject&lt;br /&gt;TObject&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are 3 sets of properties that give you more information about the given type.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    property AsInstance: TRttiInstanceType read GetAsInstance;&lt;br /&gt;    property IsInstance: Boolean read GetIsInstance;&lt;br /&gt;    property AsOrdinal: TRttiOrdinalType read GetAsOrdinal;&lt;br /&gt;    property IsOrdinal: Boolean read GetIsOrdinal;&lt;br /&gt;    property IsSet: Boolean read GetIsSet;&lt;br /&gt;    property AsSet: TRttiSetType read GetAsSet;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Instance Types are Classes, and the TRttiInstanceType provides the property "MetaclassType" which returns the TClass for the given type.     The following example shows how to use this type to construct an instance of an object.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, RTTI;&lt;br /&gt;type&lt;br /&gt;  TOneObject = Class(TObject)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TTwoObject = Class(TOneObject)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TThreeObject = Class(TTwoObject)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; t : TRttiType;&lt;br /&gt; o : TObject;&lt;br /&gt;begin&lt;br /&gt;   c := TRttiContext.Create;&lt;br /&gt;   try&lt;br /&gt;     t := c.GetType(TThreeObject);&lt;br /&gt;     o := t.AsInstance.MetaclassType.Create;&lt;br /&gt;     Writeln(o.ClassName);&lt;br /&gt;     o.Free;&lt;br /&gt;   finally&lt;br /&gt;     c.Free&lt;br /&gt;   end;&lt;br /&gt;   readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;TThreeObject&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;TRttiOrdinalType handles Ordinal Types, such as Integer, Enumerated Type, etc... &lt;br /&gt;It exposes 3 new properties to help you when working with Ordinal types.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    TOrdType = (otSByte, otUByte, otSWord, otUWord, otSLong, otULong);&lt;br /&gt;&lt;br /&gt;    ...    &lt;br /&gt;&lt;br /&gt;    property OrdType: TOrdType read GetOrdType;&lt;br /&gt;    property MinValue: Longint read GetMinValue;&lt;br /&gt;    property MaxValue: Longint read GetMaxValue;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The following example code shows how they behave.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, RTTI,TypInfo;&lt;br /&gt;type&lt;br /&gt;  TMyEnum = (enOne,enTwo,enThree);&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; t : TRttiType;&lt;br /&gt;begin&lt;br /&gt;   c := TRttiContext.Create;&lt;br /&gt;   try&lt;br /&gt;     t := c.GetType(TypeInfo(TMyEnum));&lt;br /&gt;     writeln(GetEnumName(TypeInfo(TOrdType),ord(t.AsOrdinal.OrdType)));&lt;br /&gt;     writeln(t.AsOrdinal.MinValue);&lt;br /&gt;     writeln(t.AsOrdinal.MaxValue);&lt;br /&gt;   finally&lt;br /&gt;     c.Free&lt;br /&gt;   end;&lt;br /&gt;   readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;otUByte&lt;br /&gt;0&lt;br /&gt;2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice, I dipped back into TypInfo.pas to call GetEnumName(), it and it's partner function GetEnumValue(), allow you to work with the names of an enumerated type instead of the ordinal values.&lt;br /&gt;&lt;br /&gt;The previous RTTI information that was available in prior versions of Delphi used a pointer to the type information i.e "pTypeInfo"&lt;br /&gt;&lt;br /&gt;This is now stored in the .Handle property of the TRttiType, I mention this as the routines in TypInfo.pas still work if you need drop to some lower level functionality.&lt;br /&gt;&lt;br /&gt;The TRttiSetType provides one new property "ElementType" which allows you to get the type of the elements of the set.   The following code shows an example of this in action.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, RTTI,TypInfo;&lt;br /&gt;type&lt;br /&gt;  TMyEnum = (enOne,enTwo,enThree);&lt;br /&gt;  TMySet = set of TMyEnum;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; t : TRttiType;&lt;br /&gt;begin&lt;br /&gt;   c := TRttiContext.Create;&lt;br /&gt;   try&lt;br /&gt;     t := c.GetType(TypeInfo(TMySet));&lt;br /&gt;     Writeln('Element Type:');&lt;br /&gt;     writeln(t.AsSet.ElementType.ToString);&lt;br /&gt;   finally&lt;br /&gt;     c.Free&lt;br /&gt;   end;&lt;br /&gt;   readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;Element Type:&lt;br /&gt;TMyEnum&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To be complete the following are provided on TRttiType, but TRttiRecordType only provides one new property, ManagedFields, however I have not found a reason I to need this property.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    property AsRecord: TRttiRecordType read GetAsRecord;&lt;br /&gt;    property IsRecord: Boolean read GetIsRecord;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But, don't overlook IsRecord as it's very useful.&lt;br /&gt;&lt;br /&gt;There are also several other descendant that you can use the standard "is" and "as" functions on get access to additional information associated with the given type.&lt;br /&gt;&lt;br /&gt;TRttiInterfaceType&lt;br /&gt;TRttiInt64Type&lt;br /&gt;TRttiMethodType&lt;br /&gt;TRttiClassRefType&lt;br /&gt;TRttiEnumerationType&lt;br /&gt;TRttiStringType&lt;br /&gt;TRttiAnsiStringType&lt;br /&gt;TRttiFloatType&lt;br /&gt;TRttiArrayType&lt;br /&gt;TRttiDynamicArrayType&lt;br /&gt;TRttiPointerType&lt;br /&gt;TRttiProcedureType&lt;br /&gt;&lt;br /&gt;The following code shows how you type cast a TRttiType to a TRttiStringType,&lt;br /&gt;to determine what type of string it's associated with.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, RTTI,TypInfo;&lt;br /&gt;type&lt;br /&gt;   TmyRecord = record&lt;br /&gt;     UniStr : String;&lt;br /&gt;     AnsiStr : AnsiString;&lt;br /&gt;     WideStr : WideString;&lt;br /&gt;   end;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; t : TRttiType;&lt;br /&gt; field : TRttiField;&lt;br /&gt;begin&lt;br /&gt;   c := TRttiContext.Create;&lt;br /&gt;   try&lt;br /&gt;     for field in c.GetType(TypeInfo(TMyRecord)).GetFields do&lt;br /&gt;     begin&lt;br /&gt;       t := field.FieldType;&lt;br /&gt;       writeln('Field:',field.Name);&lt;br /&gt;       writeln('RttiType:',t.ClassName);&lt;br /&gt;       if (t is TRttiStringType) then    &lt;br /&gt;         Writeln('String Kind:',GetEnumName(TypeInfo(TRttiStringKind),ord((t as TRttiStringType).StringKind)));&lt;br /&gt;       Writeln;&lt;br /&gt;     end;&lt;br /&gt;   finally&lt;br /&gt;     c.Free&lt;br /&gt;   end;&lt;br /&gt;   readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;Field:UniStr&lt;br /&gt;RttiType:TRttiStringType&lt;br /&gt;String Kind:skUnicodeString&lt;br /&gt;&lt;br /&gt;Field:AnsiStr&lt;br /&gt;RttiType:TRttiAnsiStringType&lt;br /&gt;String Kind:skAnsiString&lt;br /&gt;&lt;br /&gt;Field:WideStr&lt;br /&gt;RttiType:TRttiStringType&lt;br /&gt;String Kind:skWideString&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In conclusion, there are several other small features of TRttiType but I am not trying to reinvent the documentation, so I will leave that for you to discover.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-2855913020120028944?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/2855913020120028944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/exploring-trttitype-and-descendants-in.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2855913020120028944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2855913020120028944'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/exploring-trttitype-and-descendants-in.html' title='Exploring TRttiType and descendants in Depth'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-8323967518319626734</id><published>2009-09-11T17:25:00.009-06:00</published><updated>2009-09-16T12:12:55.809-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>Using Attributes and TCustomAttribute descendants</title><content type='html'>With Delphi 2010 attributes have been added as a language feature. They have been available in Delphi Prism (Targets .NET) and this now adds similar functionality to Win32.&lt;br /&gt;&lt;br /&gt;Attributes are a way of associating additional metadata information with a given type or member of a type.&lt;br /&gt;&lt;br /&gt;They can be applied in many places, the following code shows several of the places you can place attributes.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;  // Declaring an attribute.&lt;br /&gt;  TAttrTest = class(TCustomAttribute)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  // Places you can use an attribute.&lt;br /&gt;  [TAttrTest]&lt;br /&gt;  TRec = Record&lt;br /&gt;    [TAttrTest]&lt;br /&gt;    value : String;&lt;br /&gt;    [TAttrTest]&lt;br /&gt;    procedure DoThis([TAttrTest]arg1: String);&lt;br /&gt;  End;&lt;br /&gt;&lt;br /&gt;  [TAttrTest]&lt;br /&gt;  TMyEnum = (enOne,enTwo,enThree);&lt;br /&gt;&lt;br /&gt;  [TAttrTest]&lt;br /&gt;  TMySet = set of TMyEnum;&lt;br /&gt;&lt;br /&gt;  [TAttrTest]&lt;br /&gt;  TObj = class(TObject)&lt;br /&gt;  private&lt;br /&gt;    [TAttrTest]&lt;br /&gt;    FID: Integer;&lt;br /&gt;  public&lt;br /&gt;    [TAttrTest]&lt;br /&gt;    FName : String;&lt;br /&gt;    [TAttrTest]&lt;br /&gt;    property Id : Integer read FID write FID;&lt;br /&gt;    [TAttrTest]&lt;br /&gt;    constructor Create;&lt;br /&gt;    [TAttrTest]&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;    [TAttrTest]&lt;br /&gt;    procedure DoThis;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  [TAttrTest]&lt;br /&gt;  I : Integer;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So how do attributes work in Delphi 2010?&lt;br /&gt;&lt;br /&gt;Attributes must descend from TCustomAttribute, if you look at the declaration of TCustomAttribute you will find that there is nothing special.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;{ The base class for all custom attributes. Attribute&lt;br /&gt;instances created by the RTTI unit are owned by those&lt;br /&gt;members to which they apply. }&lt;br /&gt;TCustomAttribute = class(TObject)&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Passing just the name of the new attribute is only practical in a few cases, usually&lt;br /&gt;you need additional data associated. This is done through the constructor. The following example shows how to setup the call to the constructor in the attribute.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;Type&lt;br /&gt;  TAttrTest2 = class(TObject)&lt;br /&gt;  private&lt;br /&gt;     FId : Integer;&lt;br /&gt;  public&lt;br /&gt;     constructor Create(aID : Integer);&lt;br /&gt;     property ID : Integer read FID write FID;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  [TAttrTest2(123)]&lt;br /&gt;  TMyObject = Class(TObject)&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So its simple to declare an Attribute and decorate your types with them. Accessing the attributes stored in a given type involves using rtti.pas, I covered some of the basics of how this works in the &lt;a href="http://robstechcorner.blogspot.com/2009/09/delphi-2010-rtti-basics.html"&gt;previous post&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Anything that can have attributes has an associated .GetAttributes() method that returns&lt;br /&gt;the array of the attributes associated with that code.&lt;br /&gt;&lt;br /&gt;The following code shows how to access the attributes.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, RTTI;&lt;br /&gt;type&lt;br /&gt;  TAttrTest2 = class(TCustomAttribute)&lt;br /&gt;  private&lt;br /&gt;     FId : Integer;&lt;br /&gt;  public&lt;br /&gt;     constructor Create(aID : Integer);&lt;br /&gt;     property ID : Integer read FID write FID;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  [TAttrTest2(1)]&lt;br /&gt;  [TAttrTest2(2)]&lt;br /&gt;  [TAttrTest2(3)]&lt;br /&gt;  TMyObject = Class(TObject)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;{ TAttrTest2 }&lt;br /&gt;&lt;br /&gt;constructor TAttrTest2.Create(aID: Integer);&lt;br /&gt;begin&lt;br /&gt; FID := aId;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; t : TRttiType;&lt;br /&gt; a : TCustomAttribute;&lt;br /&gt;begin&lt;br /&gt;   c := TRttiContext.Create;&lt;br /&gt;   try&lt;br /&gt;     t := c.GetType(TMyObject);&lt;br /&gt;     for a in  t.GetAttributes do&lt;br /&gt;     begin&lt;br /&gt;       Writeln((a as TAttrTest2).ID);&lt;br /&gt;     end;&lt;br /&gt;   finally&lt;br /&gt;     c.Free&lt;br /&gt;   end;&lt;br /&gt;   readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Attributes also have a few other special items that the compiler implements.&lt;br /&gt;&lt;br /&gt;If you have an attribute named like this...&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;type&lt;br /&gt;TestAttribute = class(TCustomAttribute)&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;It can be refered to in two different ways&lt;br /&gt;&lt;br /&gt;[TestAttribute]&lt;br /&gt;TExample = class(Tobject)&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;[Test]&lt;br /&gt;TExample2 = class(TObject)&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The compiler will look for the type, if it is not found it will automatically append "Attribute" to the name and search again. This is done to mimic the .NET behavior.&lt;br /&gt;&lt;br /&gt;The compiler also has some special support for types allow you to get TRttiType&lt;br /&gt;easily from the pTypeInfo pointer. The following code segment shows how that pTypeInfo can be interchanged for TRttitype in attributes.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Rtti;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TestAttribute = class(TCustomAttribute)&lt;br /&gt;  public&lt;br /&gt;    constructor Create(aType : TRttiType);&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  [Test(typeinfo(Integer))]&lt;br /&gt;  TEmployee = class(TObject)&lt;br /&gt;  end;  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are many practical applications for Attributes, I will explore many of these in later articles.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-8323967518319626734?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/8323967518319626734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/using-attributes-and-tcustomattribute.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8323967518319626734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8323967518319626734'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/using-attributes-and-tcustomattribute.html' title='Using Attributes and TCustomAttribute descendants'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-72478666363675128</id><published>2009-09-10T09:18:00.008-06:00</published><updated>2009-09-16T12:19:32.942-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>Delphi 2010 RTTI - The basics</title><content type='html'>In Delphi 2009 and Prior RTTI was limited to items in the published section.&lt;br /&gt;You had access to pointers for properties, fields and Methods on objects.  If you spent some time learning, the old RTTI system was powerful.   However, the power of the RTTI in prior versions seem very small when compared to what is now available in Delphi 2010.&lt;br /&gt;&lt;br /&gt;In Delphi 2010 you have the option to have RTTI information for almost everything.  The choice of what to include is yours, it is controlled by the new $RTTI directive.    The default behavior is defined in System.pas shows that, properties and methods are now available via RTTI in both public and published sections, and Fields are available in all of the sections.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;Section of System.pas:&lt;br /&gt;{ RTTI Visibility }&lt;br /&gt;type  &lt;br /&gt;  TVisibilityClasses = set of (vcPrivate, vcProtected, vcPublic, vcPublished);&lt;br /&gt;&lt;br /&gt;const&lt;br /&gt;  { These constants represent the default settings built into the compiler.&lt;br /&gt;    For classes, these settings are normally inherited from TObject. }&lt;br /&gt;  DefaultMethodRttiVisibility = [vcPublic, vcPublished];&lt;br /&gt;  DefaultFieldRttiVisibility = [vcPrivate..vcPublished];&lt;br /&gt;  DefaultPropertyRttiVisibility = [vcPublic, vcPublished];&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  { Default RTTI settings }&lt;br /&gt;  {$RTTI INHERIT&lt;br /&gt;      METHODS(DefaultMethodRttiVisibility)&lt;br /&gt;      FIELDS(DefaultFieldRttiVisibility)&lt;br /&gt;      PROPERTIES(DefaultPropertyRttiVisibility)} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Raw RTTI Information would be worthless unless you have good way to access the information.    The new Unit RTTI.Pas provides a simple and elegant way to access this data.   Flexibility of classes, with out the headaches of Memory Management was a key concern of the new design.    As such RTTI access is done through a context, once that context is freed all the RTTI objects created are freed.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt;begin&lt;br /&gt;  c := TRttiContext.Create;&lt;br /&gt;  try&lt;br /&gt;     // RTTI Access code here&lt;br /&gt;  finally&lt;br /&gt;   c.free;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you open up RTTI.pas you will need notice that TRttiContext is not an object it is a Record, so don't get confused you should still call .Create and .Free as you would with an object.   The reason for this is to free the pool of RTTI objects that may have been created.  Atlhough the help file tells you not to free it, I personally like to clean up.  &lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt;&lt;br /&gt;I have had enough questions on this alone, I thought I would &lt;a href="http://robstechcorner.blogspot.com/2009/09/trtticontextcreate-trtticontextfree.html"&gt;explain in more detail&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;TRttiContext offers several key methods, which allow you to get access, to the types in the system.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    function GetType(ATypeInfo: Pointer): TRttiType; overload;&lt;br /&gt;    function GetType(AClass: TClass): TRttiType; overload;&lt;br /&gt;    function GetTypes: TArray&amp;lt;TRttiType&gt;;&lt;br /&gt;    function FindType(const AQualifiedName: string): TRttiType;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For example all of the following will return the TRttiType class representing, TButton.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;var&lt;br /&gt;  c : TRttiContext;&lt;br /&gt;  t : TRttiType;&lt;br /&gt;begin&lt;br /&gt;  c := TRttiContext.Create;&lt;br /&gt;  try&lt;br /&gt;    // Via a String&lt;br /&gt;    t := c.FindType('StdCtrls.TButton');&lt;br /&gt;&lt;br /&gt;    // Via the pTypeInfo Pointer&lt;br /&gt;    t := c.GetType(TButton.ClassInfo);&lt;br /&gt;&lt;br /&gt;    // Via the class type&lt;br /&gt;    t := c.GetType(TButton);&lt;br /&gt;  finally&lt;br /&gt;    c.Free;&lt;br /&gt;   end;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The TRttiType has many functions that allow you to query the members of that type.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;    function GetMethods: TArray&amp;lt;TRttiMethod&gt;; overload; virtual;&lt;br /&gt;    function GetFields: TArray&amp;lt;TRttiField&gt;; virtual;&lt;br /&gt;    function GetProperties: TArray&amp;lt;TRttiProperty&gt;; virtual;&lt;br /&gt;    &lt;br /&gt;    function GetMethod(const AName: string): TRttiMethod; virtual;&lt;br /&gt;    function GetMethods(const AName: string): TArray&amp;lt;TRttiMethod&gt;; overload; virtual;&lt;br /&gt;    function GetField(const AName: string): TRttiField; virtual;&lt;br /&gt;    function GetProperty(const AName: string): TRttiProperty; virtual;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;    &lt;br /&gt;So for example the following console application would show all of the methods of TButton.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project10;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses&lt;br /&gt;  StdCtrls, TypInfo, Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; m : TRttiMethod;&lt;br /&gt;begin&lt;br /&gt;   c := TRttiContext.Create;&lt;br /&gt;   for m in c.GetType(TButton).GetMethods do&lt;br /&gt;   begin&lt;br /&gt;     Writeln(m.ToString);&lt;br /&gt;   end;&lt;br /&gt;   c.Free;&lt;br /&gt;   readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;constructor Create(AOwner: TComponent)&lt;br /&gt;class destructor Destroy&lt;br /&gt;procedure Click&lt;br /&gt;... (Many Lines Removed) ...&lt;br /&gt;procedure AfterConstruction&lt;br /&gt;procedure BeforeDestruction&lt;br /&gt;procedure Dispatch(var Message)&lt;br /&gt;procedure DefaultHandler(var Message)&lt;br /&gt;class function NewInstance: TObject&lt;br /&gt;procedure FreeInstance&lt;br /&gt;class destructor Destroy&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Taking this to the next level the following code creates TStringList using the RTTI System, invokes the Add Method and accesses the Text Property.   Granted this is not a practical example, it is just designed to show you some of the functionality available.  You will notice that values are stored using the type TValue.   TValue can store and retrieve any type.   &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;program Project11;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses&lt;br /&gt;  StdCtrls, TypInfo, Classes, Rtti;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt; c : TRttiContext;&lt;br /&gt; m : TRttiMethod;&lt;br /&gt; t : TRttiInstanceType;&lt;br /&gt; SL : TValue;&lt;br /&gt; Lines : TValue;&lt;br /&gt;begin&lt;br /&gt;   c := TRttiContext.Create;&lt;br /&gt;   t := (c.FindType('Classes.TStringList') as TRttiInstanceType);&lt;br /&gt;   SL := t.GetMethod('Create').Invoke(t.MetaclassType,[]);&lt;br /&gt;   t.GetMethod('Add').Invoke(SL,['Hello Do you like my hat?']);&lt;br /&gt;   t.GetMethod('Add').Invoke(SL,['I like that hat, what a party hat!']);&lt;br /&gt;   Lines := t.GetProperty('Text').GetValue(SL.AsObject);&lt;br /&gt;   Writeln(Lines.ToString);&lt;br /&gt;   c.Free;&lt;br /&gt;   readln;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;pre class="brush: plain; gutter: false"&gt;&lt;br /&gt;Hello Do you like my hat?&lt;br /&gt;I like that hat, what a party hat!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Although it appears that TValue may act like a variant, TValue is not a replacement for Variant.  Specifically,  If you assign a specific type to a TValue you must retrieve it as that specific type.    For example you can't assign an Integer to a TValue and retrieve it as a String, doing so results in an Invalid Type Cast.  &lt;br /&gt;&lt;br /&gt;This is just taste, future articles will cover this in more detail.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;RTTI Article List&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-72478666363675128?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/72478666363675128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/delphi-2010-rtti-basics.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/72478666363675128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/72478666363675128'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/delphi-2010-rtti-basics.html' title='Delphi 2010 RTTI - The basics'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-4769170611097561666</id><published>2009-09-09T15:54:00.003-06:00</published><updated>2009-09-09T15:57:38.695-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeRage'/><category scheme='http://www.blogger.com/atom/ns#' term='DBX'/><title type='text'>CodeRage IV - BDE to DBX</title><content type='html'>Well I just finished my session on CodeRage IV Session BDE to DBX, and so I am reposting a messsage I posted at the end of DelphiLive with the same information.&lt;br /&gt;&lt;br /&gt;My slides and code are available in SVN at my &lt;a href="http://code.google.com/p/robstechcorner/source/browse/#svn/trunk/Delphi/presentations/DelphiLive/DBX"&gt;Google Code Site&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The BDEtoDBXDataPump was a quick and dirty application but it should work, let &lt;br /&gt;me know if you have a problem and I will update the code in SVN, I had to update it once since DelphiLiver version of this session.&lt;br /&gt;&lt;br /&gt;The ComponentConverter will convert TQuery and TTable to TdbxQuery components.&lt;br /&gt;It will also convert TDatabase to TSqlConnection, and few other things to help in the conversion, such as removing the BDE Units and adding in the DBX units. &lt;br /&gt;&lt;br /&gt;The ComponentCoverter contains a few little gems such as a DFM Parser.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-4769170611097561666?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/4769170611097561666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/coderage-iv-bde-to-dbx.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4769170611097561666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4769170611097561666'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/coderage-iv-bde-to-dbx.html' title='CodeRage IV - BDE to DBX'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-5064023195799773878</id><published>2009-09-01T14:43:00.009-06:00</published><updated>2009-09-01T15:24:58.806-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeRage'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>CodeRage Sessions</title><content type='html'>&lt;p&gt;Although, I just posted a fairly &lt;a href="http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html"&gt;big teaser of my RTTI session&lt;/a&gt;, I neglected the other sessions I will be covering at &lt;a href="http://conferences.embarcadero.com/coderage"&gt;CodeRage&lt;/a&gt;.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Building and Consuming Web Services in Delphi and Delphi Prism&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;This is a introduction to the topic, if you have done web services you won't learn anything new :-)&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Building Unit Tests with DUnit &lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;This is a introduction to the topic, I will be covering the XML test runner and other features that not visible on the surface. So it may be useful even if you use basic DUnit Tests.&lt;li&gt;&lt;strong&gt;Converting from BDE to DBX&lt;/strong&gt;  &lt;/li&gt;&lt;br /&gt;This is a refined version of my DelphiLive material.  This has been my most popular session I have ever given, I have recieved more feedback on this than any other.  It does not hurt that &lt;a href="http://blogs.embarcadero.com/andreanolanusse/"&gt;Andreano Lanusse&lt;/a&gt; repeated parts of the session on his &lt;a href="http://blogs.embarcadero.com/andreanolanusse/delphi-meeting-2009-in-brazil-2-more-weeks/"&gt;various stops in Brazil&lt;/a&gt;  I will be showing the DBX framework and some code/dfm parsers that do much of the work to convert a BDE application to DBX. I will also show a BDE to DBX datapump.&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Practical Application of RTTI and Attributes&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;I have never been more exicited about a feature in Delphi.  After seeing this session and the associated blog posts, I hope you realize what I am talking about :-)&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I hope to be able to chat with many of you next week at &lt;a href="http://conferences.embarcadero.com/coderage"&gt;CodeRage&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-5064023195799773878?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/5064023195799773878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/coderage-sessions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5064023195799773878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/5064023195799773878'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/coderage-sessions.html' title='CodeRage Sessions'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-3106627628777689488</id><published>2009-09-01T14:28:00.022-06:00</published><updated>2009-10-08T17:15:58.880-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeRage'/><category scheme='http://www.blogger.com/atom/ns#' term='RTTI'/><title type='text'>Delphi 2010 - RTTI &amp; Attributes</title><content type='html'>So what is RTTI? RTTI is an acronym for Run Time Type Information. It allows you interact with the type system at Run Time. I like to compare RTTI to meta data information stored in a database. If I execute the following SQL statement "select * from employee" how does the database know what to return? How does the application know what will be returned? It all boils down to "MetaData Information" which allows you to look up what database fields and there associated types will be returned. With RTTI, you have this same access to types defined in your Delphi code.&lt;br /&gt;&lt;br /&gt;Delphi has always had RTTI, but Delphi 2010 has taken RTTI to the next level.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://conferences.embarcadero.com/coderage"&gt;CodeRage&lt;/a&gt; is next week, there are two session that will be covering the RTTI system in Delphi 2010.&lt;br /&gt;&lt;br /&gt;The first is &lt;a href="http://blog.barrkel.com/"&gt;Barry Kelly's&lt;/a&gt; presentation on "Delphi Compiler RTTI Enhancements" if you have time to only see one, then see this one. Barry is the engineer behind the Compiler RTTI Enhancements. His presentation is currently scheduled for Tuesday.&lt;br /&gt;&lt;br /&gt;The second, is mine on "Practical Application of RTTI and Attributes" my presentation is currently scheduled for Thursday.&lt;br /&gt;&lt;br /&gt;Both are only 40 minutes long, it is enough to get your tips of your toes wet, and I want to jump right in :-) &lt;br /&gt;&lt;br /&gt;As such I have prepared a series of blog posts, I will start posting these after my CodeRage Session. Most likely one each day. Although, I tend to hate teasers, I decided to post one :-P&lt;br /&gt;&lt;br /&gt;Here is what to expect:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/09/delphi-2010-rtti-basics.html"&gt;Delphi 2010 RTTI - The basics&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/09/using-attributes-and-tcustomattribute.html"&gt;Using Attributes and TCustomAttribute descendants &lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/09/exploring-trttitype-and-descendants-in.html"&gt;Exploring TRTTIType in depth&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/09/introduction-to-tvalue.html"&gt;Introduction to TValue&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/09/exploring-trttimember-descendants-in.html"&gt;Exploring TRttiMember Descendants in depth (Part I) Properties and Fields&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/09/trtticontextcreate-trtticontextfree.html"&gt;Why I call TRttiContext.Create() and TRttiContext.Free()&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/09/exploring-trttimember-descendants-in_17.html"&gt;Exploring TRttiMember Descendants in depth (Part II) Methods&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/09/tvalue-in-depth.html"&gt;TValue in Depth&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/10/ini-persistence-rtti-way.html"&gt;INI persistence the RTTI way&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/10/xml-serialization-basic-usage.html"&gt;Xml Serialization - Basic Usage&lt;/a&gt; &lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://robstechcorner.blogspot.com/2009/10/xml-serialization-control-via.html"&gt;Xml Serialization - Control via Attributes &lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt; Attributes: Practical Example- Object to Client Dataset &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Types by Package... Dynamic plug-in systems. &lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;The above list may change a bit as I am still editing the material.&lt;br /&gt;&lt;br /&gt;I will update this post with links to the blog posts, as the become available if you want to bookmark this page.&lt;br /&gt;&lt;br /&gt;I hope to see you at CodeRage, to unleash the Chaos :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-3106627628777689488?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/3106627628777689488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3106627628777689488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3106627628777689488'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html' title='Delphi 2010 - RTTI &amp; Attributes'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-3200300082470983090</id><published>2009-08-14T08:24:00.002-06:00</published><updated>2009-08-14T08:51:03.627-06:00</updated><title type='text'>Wildfires - Santa Cruz Mountains</title><content type='html'>Having lived next to mountain ranges in Utah all of my life I have witnessed the first hand the mighty power of a wild fire, more than once. This morning &lt;a href="http://www.msnbc.msn.com/id/32400723/ns/weather/"&gt;a news story&lt;/a&gt; caught my attention, there is a fire in the Santa Cruz, CA mountains, that just forced a Bonny Doon a town of 2000 to evacuate. I thought that was close to Scotts Valley, the home of Embarcadero Developer Tools (Codegear). A quick search of &lt;a href="http://maps.google.com/maps?f=d&amp;source=s_d&amp;saddr=Scotts+Valley,+California&amp;daddr=Bonny+Doon,+Santa+Cruz,+California&amp;hl=en&amp;geocode=FUJsNQIdQj66-A%3B&amp;mra=ls&amp;sll=37.023936,-121.79718&amp;sspn=0.414444,0.786209&amp;ie=UTF8&amp;t=h&amp;z=13"&gt;google maps&lt;/a&gt;, showed that Bonny Doon is just 15 miles away. Having seen wild fires go miles in just a matter of days, my thoughts and prayers are with you. I hope the employee's there families and friends are not impacted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-3200300082470983090?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/3200300082470983090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/08/wildfires-santa-cruz-mountains.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3200300082470983090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3200300082470983090'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/08/wildfires-santa-cruz-mountains.html' title='Wildfires - Santa Cruz Mountains'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-3702107120601598318</id><published>2009-07-14T17:15:00.019-06:00</published><updated>2009-07-14T18:06:03.561-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeRage'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>CodeRage sessions, ask your questions now.</title><content type='html'>I have been working on my sessions for &lt;a href="http://conferences.codegear.com/coderage"&gt;CodeRage&lt;/a&gt;. I have four sessions this time. I would like to solicit "pre-session" questions on three of my sessions. It's your chance to shape the material that is presented.&lt;br /&gt;&lt;br /&gt;Do you have any questions on the topics below? &lt;br /&gt;If so let me know via either a comment to this blog post or an email rlove at peakbiz.com&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Converting from BDE to DBX&lt;/strong&gt;&lt;br /&gt;Learn how to convert your existing BDE applications to the DBX Architecture. We will cover the architectural and coding differences between BDE and DBX. We will then cover tools that freely available to assist you in this conversion.&lt;br /&gt;&lt;em&gt;Note:&lt;/em&gt; This session is similar to the material I presented at DelphiLive and by &lt;a href="http://blogs.embarcadero.com/andreanolanusse/"&gt;Andreano Lanusse&lt;/a&gt; in  Brazil, so if you attended one of these sessions and have feedback, I would be glad to hear it.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Building and Consuming Web Services in Delphi and Delphi Prism&lt;/strong&gt;&lt;br /&gt;Walk step by step through the process to build and consume web services, with both Delphi Win32 and Prism.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Building Unit Tests with DUnit&lt;/strong&gt;&lt;br /&gt;Get up to speed with unit testing in DUnit. No prior knowledge of Unit testing or DUnit is required.&lt;br /&gt;&lt;em&gt;Note:&lt;/em&gt; If you have tried DUnit and did not understand it, I want to hear from you!&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I need the questions by August 13th, as I need to record these sessions before I leave for a back-packing trip to the top of &lt;a href="http://en.wikipedia.org/wiki/Mount_Whitney"&gt;Mt. Whitney&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-3702107120601598318?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/3702107120601598318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/07/coderage-sessions-ask-your-questions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3702107120601598318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3702107120601598318'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/07/coderage-sessions-ask-your-questions.html' title='CodeRage sessions, ask your questions now.'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-3094990890693051093</id><published>2009-06-01T19:39:00.008-06:00</published><updated>2009-06-18T10:45:24.131-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='DBX'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>BDE to DBX Data Pump - Small updates</title><content type='html'>&lt;div&gt;In the comments of &lt;a href="http://robstechcorner.blogspot.com/2009/05/bde-to-dbx.html"&gt;BDE to DBX Blog Post&lt;/a&gt;  I was made aware of three bugs in the BDEToDBXDataPump application.   &lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;I have fixed 2 of the 3 and made a blind attempt at the remaining one, since I can't reproduce.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The updates can be found in my &lt;a href="http://code.google.com/p/robstechcorner/source/browse/#svn/trunk/Delphi/presentations/DelphiLive/DBX/ConvertData"&gt;googlecode SVN&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The bug is most likely in an incorrect mapping here of currency fields.  All of the mappings are done through a constant.   See the code below, by my comments you can&lt;br /&gt;tell how good I felt about it :-)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;//Mapping Best Guess in 10 minutes of work, so I suspect there&lt;br /&gt;//are problems but you could also change this to find tune for your&lt;br /&gt;//specific mapping needs.&lt;br /&gt;  FieldTypeMap : Array[TFieldType] of Integer =&lt;br /&gt;   ( {ftUnknown} TDBXDataTypes.UnknownType, {ftString} TDBXDataTypes.AnsiStringType, {ftSmallint} TDBXDataTypes.Int16Type, {ftInteger} TDBXDataTypes.Int32Type, {ftWord} TDBXDataTypes.UInt16Type, // 0..4&lt;br /&gt;    {ftBoolean} TDBXDataTypes.BooleanType, {ftFloat} TDBXDataTypes.DoubleType, {ftCurrency} TDBXDataTypes.BcdType, {ftBCD} TDBXDataTypes.BcdType, {ftDate}TDBXDataTypes.DateType , {ftTime} TDBXDataTypes.TimeType, {ftDateTime} TDBXDataTypes.DateTimeType, // 5..11&lt;br /&gt;    {ftBytes}TDBXDataTypes.BytesType , {ftVarBytes} TDBXDataTypes.VarBytesType, {ftAutoInc} TDBXDataTypes.AutoIncSubType, {ftBlob} TDBXDataTypes.BlobType, {ftMemo} TDBXDataTypes.MemoSubType, {ftGraphic} TDBXDataTypes.BlobType, {ftFmtMemo} TDBXDataTypes.MemoSubType, // 12..18&lt;br /&gt;    {ftParadoxOle}TDBXDataTypes.UnknownType , {ftDBaseOle}TDBXDataTypes.UnknownType, {ftTypedBinary}TDBXDataTypes.BlobType, {ftCursor}TDBXDataTypes.UnknownType, {ftFixedChar}TDBXDataTypes.CharArrayType, {ftWideString} TDBXDataTypes.WideStringType,  // 19..24&lt;br /&gt;    {ftLargeint}TDBXDataTypes.Int64Type, {ftADT}TDBXDataTypes.AdtType , {ftArray}TDBXDataTypes.ArrayType , {ftReference}TDBXDataTypes.UnknownType, {ftDataSet}TDBXDataTypes.UnknownType, {ftOraBlob}TDBXDataTypes.BlobType, {ftOraClob} TDBXDataTypes.BlobType, // 25..31&lt;br /&gt;    {ftVariant} TDBXDataTypes.UnknownType, {ftInterface}TDBXDataTypes.UnknownType, {ftIDispatch}TDBXDataTypes.UnknownType, {ftGuid}TDBXDataTypes.CharArrayType, {ftTimeStamp} TDBXDataTypes.DateTimeType, {ftFMTBcd} TDBXDataTypes.BcdType, // 32..37&lt;br /&gt;    {ftFixedWideChar} TDBXDataTypes.WideStringType, {ftWideMemo} TDBXDataTypes.UnknownType, {ftOraTimeStamp} TDBXDataTypes.OracleTimeStampSubType, {ftOraInterval}TDBXDataTypes.OracleIntervalSubType, // 38..41&lt;br /&gt;   {ftLongWord} TDBXDataTypes.Uint32Type, {ftShortint} TDBXDataTypes.Int16Type, {ftByte} TDBXDataTypes.Int8Type, {ftExtended} TDBXDataTypes.DoubleType, {ftConnection} TDBXDataTypes.UnknownType, {ftParams}TDBXDataTypes.UnknownType, {ftStream}TDBXDataTypes.UnknownType); //42..48&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hopefully my stab in the dark on the remaining issue of change ftCurrency to map to TDBXDatatypes.BCDType instead of CurrencyType is correct.   I based it on the comments in dbxCommon.pas&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;      ///&lt;summary&gt;Delphi Currency data type in System unit.&lt;br /&gt;      ///  Internally managed as a &lt;c&gt;TDBXDataTypes.BCDType&lt;/c&gt;&lt;br /&gt;      ///&lt;/summary&gt;&lt;br /&gt;      CurrencyType        = 25;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyway if anyone has any problems with BDEtoDBXDatapump please let me know by&lt;br /&gt;&lt;a href="http://code.google.com/p/robstechcorner/issues/list"&gt;posting an issue on Google Code&lt;/a&gt;  that way I fix them.    Please include the source and destination table/database types as it may be critical to figuring out the mapping problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-3094990890693051093?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/3094990890693051093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/06/bde-to-dbx-data-pump-small-updates.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3094990890693051093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3094990890693051093'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/06/bde-to-dbx-data-pump-small-updates.html' title='BDE to DBX Data Pump - Small updates'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-7349751200667727066</id><published>2009-05-29T14:43:00.005-06:00</published><updated>2009-06-01T20:01:11.600-06:00</updated><title type='text'>Computer Language/Compiler Development</title><content type='html'>In addition to everything else I have going on my life, I am a full time student.&lt;br /&gt;&lt;br /&gt;I have to write a research paper on the basics of computer language development.&lt;br /&gt;&lt;br /&gt;I am required to do a survey as part of this class.&lt;br /&gt;&lt;br /&gt;If any of you would be so kind, would you please take my survey.&lt;br /&gt;&lt;br /&gt;Update: Thank you for those that helped.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-7349751200667727066?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/7349751200667727066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/computer-languagecompiler-development.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7349751200667727066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7349751200667727066'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/computer-languagecompiler-development.html' title='Computer Language/Compiler Development'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-3094704332251983203</id><published>2009-05-15T22:27:00.003-06:00</published><updated>2009-06-01T19:58:23.118-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>Delphi Live RTTI Session</title><content type='html'>For those that attended my session, and any others who may ask.&lt;br /&gt;&lt;br /&gt;The source code and the 3 slides from my RTTI session are on &lt;a href="http://code.google.com/p/robstechcorner/source/browse/#svn/trunk/Delphi/presentations/DelphiLive/RTTI"&gt;my SVN Repository&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-3094704332251983203?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/3094704332251983203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/delphi-live-rtti-session.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3094704332251983203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/3094704332251983203'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/delphi-live-rtti-session.html' title='Delphi Live RTTI Session'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-4453624646050747900</id><published>2009-05-15T12:09:00.004-06:00</published><updated>2009-06-01T19:58:07.093-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>DelphiLive Pictures</title><content type='html'>I uploaded several raw &lt;a href="http://picasaweb.google.com/LovePhotoStore/DelphiLive2009?feat=directlink"&gt;pictures of DelphiLive&lt;/a&gt;.   I will be uploading more to the same location later.   Hopefully some from the What is cooking in the Labs session.&lt;br /&gt;&lt;br /&gt;Slide Show below...&lt;br /&gt;&lt;br /&gt;&lt;embed type="application/x-shockwave-flash" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" width="288" height="192" flashvars="host=picasaweb.google.com&amp;captions=1&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2FLovePhotoStore%2Falbumid%2F5336110959271980177%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-4453624646050747900?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/4453624646050747900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/delphilive-pictures.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4453624646050747900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4453624646050747900'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/delphilive-pictures.html' title='DelphiLive Pictures'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-8475002616829082379</id><published>2009-05-14T18:59:00.003-06:00</published><updated>2009-06-01T19:57:14.438-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='DBX'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>BDE to DBX</title><content type='html'>Well I have finished my session on converting BDE to DBX.&lt;br /&gt;&lt;br /&gt;My slides and code are available in SVN at my &lt;a href="http://code.google.com/p/robstechcorner/source/browse/#svn/trunk/Delphi/presentations/DelphiLive/DBX"&gt;Google Code Site&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The BDEtoDBXDataPump was a quick and dirty application but it should work, let &lt;br /&gt;me know if you have a problem and I will update the code in SVN.   &lt;br /&gt;&lt;br /&gt;The ComponentConverter will convert TQuery and TTable to TdbxQuery components.&lt;br /&gt;It will also convert TDatabase to TSqlConnection, and few other things to help in the conversion, such as removing the BDE Units and adding in the DBX units.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-8475002616829082379?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/8475002616829082379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/bde-to-dbx.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8475002616829082379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8475002616829082379'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/bde-to-dbx.html' title='BDE to DBX'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-4503406506267863689</id><published>2009-05-14T14:02:00.021-06:00</published><updated>2009-06-01T19:57:49.410-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>DelphiLive -  Where is Delphi Going?</title><content type='html'>Here is the disclaimer I have done my best to get my notes correct, but I may have missed something, slides go by sometimes too fast for those transcribed what is seen and heard.&lt;br /&gt;&lt;br /&gt;Here are some of my raw notes from the first two sessions:&lt;br /&gt;&lt;br /&gt;Four Delphi Projects going on at the same time.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Project Weaver&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Main Themes&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;User Experience&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Enhance Connectivity&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Documentation&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;IDE usability&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Team Productivity&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Touch&lt;br /&gt;&lt;/li&gt;&lt;li&gt;IDE – Insight (easy Keyboard access to almost everything)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Improvements to DataSnap&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Firebird Support&lt;br /&gt;&lt;/li&gt;&lt;li&gt;.NET AOP&lt;br /&gt;&lt;/li&gt;&lt;li&gt;SCM Support&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Enhanced RTTI Support&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Attribute Support&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Seamless .NET &lt;&gt; Native communication&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Windows 7 APIs and Direct 2D&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Full Support of SOAP 1.2 Clients&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Project X&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Cross-platform Windows, Mac OS, and Linux&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Cross-platform component library&lt;br /&gt;&lt;/li&gt;&lt;li&gt;DataSnap on all platforms&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Project Chromium, Quality, Quality&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Quality, Quality, Quality&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Pascal Code Formatter&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Documentation of the OTA&lt;br /&gt;&lt;/li&gt;&lt;li&gt;New Data binding model allowing binding to almost any property on a control&lt;br /&gt;&lt;/li&gt;&lt;li&gt;More integration with the database tools.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Project Commodore&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;64 Bit native&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Full compiler, RTL and VCL support for 64 native&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Multi-Core. Multi-threaded applications.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Sure it's not much more than a bullet point list... But several of the items are very intresting.   The order is not defined... Other than Weaver is expected next.&lt;br /&gt;&lt;br /&gt;I am sure more details will be coming from the Labs sessions.&lt;br /&gt;&lt;br /&gt;We did see a really cool Touch Demo!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-4503406506267863689?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/4503406506267863689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/delphilive-where-is-delphi-going.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4503406506267863689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/4503406506267863689'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/delphilive-where-is-delphi-going.html' title='DelphiLive -  Where is Delphi Going?'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-8980030324581209300</id><published>2009-05-13T12:46:00.006-06:00</published><updated>2009-06-01T19:59:09.489-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>DelphiLive - Just getting started...</title><content type='html'>Well I am now sitting in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Multithreading&lt;/span&gt; Master Class with Marco Cantu and Cary Jensen.&lt;br /&gt;&lt;br /&gt;At the break I will be switching and sitting in on the Delphi &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;DataSnap&lt;/span&gt; 2009 Deep Dive. I have considered using the new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Datasnap&lt;/span&gt; more than once. However, I have always ended up switching to something else. I have explored the source, written several demo apps, and feel like I understand it, I am really looking to see another perspective.&lt;br /&gt;&lt;br /&gt;On the plane flight out, I was thinking about all of the questions I might be asked during my &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;BDE&lt;/span&gt; to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;DBX&lt;/span&gt; session.&lt;br /&gt;&lt;br /&gt;One of the questions I realized I could be asked was... How do I convert paradox and/or another &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;BDE&lt;/span&gt; database to a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;DBX&lt;/span&gt; supported Database.&lt;br /&gt;&lt;br /&gt;There are several options, but I don't feel like there is a really, really easy way to do this.&lt;br /&gt;&lt;br /&gt;So hopefully I can finish before my session &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;tomorrow&lt;/span&gt; a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;BDE&lt;/span&gt; to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;DBX&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;DataPump&lt;/span&gt; application.... But no commitments :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-8980030324581209300?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/8980030324581209300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/delphilive-just-getting-started.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8980030324581209300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/8980030324581209300'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/delphilive-just-getting-started.html' title='DelphiLive - Just getting started...'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-7454472322291280742</id><published>2009-05-08T11:15:00.009-06:00</published><updated>2009-05-08T12:04:17.211-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='DelphiLive'/><title type='text'>Finalizing DelphiLive Material</title><content type='html'>Well today I am putting the finishing touches on my &lt;a href="http://www.delphilive.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;DelphiLive&lt;/span&gt;&lt;/a&gt; presentations.&lt;br /&gt;&lt;br /&gt;I will be presenting:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Power of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;RTTI&lt;/span&gt; In Delphi &lt;/li&gt;&lt;li&gt;Moving from &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;BDE&lt;/span&gt; to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;DBX&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I have this love hate relationship with PowerPoint, sometimes I find its the best way to communication information.   However as soon as things get technical I really dislike seeing a bunch of code on slides.&lt;/p&gt;&lt;p&gt;In My Power of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;RTTI&lt;/span&gt; in Delphi Session I currently I have grand total of 3 Slides for this presentation the rest is code.   &lt;/p&gt;&lt;p&gt;I will be covering: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Interacting with Published Information&lt;/li&gt;&lt;li&gt;Dynamic Method Invocation&lt;/li&gt;&lt;li&gt;Dynamic Class Creation&lt;/li&gt;&lt;li&gt;Ideas on how you might use it your applications.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In My &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;BDE&lt;/span&gt; to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;DBX&lt;/span&gt; Session, I have several slides, but don't worry I have plenty of code and examples to show.&lt;/p&gt;&lt;p&gt;One of the things I like the best about this presentation won't come till near the end, but at the State of Utah we wrote a simple &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;DFM&lt;/span&gt; parser and combined it with Martin &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Waldenburg&lt;/span&gt; Delphi Parser (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;TmwPasLex&lt;/span&gt;) and wrote a simple but effective conversion utility.    It saved us tons of time when converting a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;BDE&lt;/span&gt; Application to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;DBX&lt;/span&gt;.   The application we converted was not a simple demo program, It has 650+ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;DFMs&lt;/span&gt;.    And several more units 500+ with no associated &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;dfm&lt;/span&gt;.     That does not count any third party code, or our own internally developed components.&lt;/p&gt;&lt;p&gt;I have updated the conversion utility to be slightly more generic as the original was specific to our needs.  I will share that code with the attendees.&lt;/p&gt;&lt;p&gt;I hope to see you there!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-7454472322291280742?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/7454472322291280742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/finalizing-delphilive-material.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7454472322291280742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/7454472322291280742'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/05/finalizing-delphilive-material.html' title='Finalizing DelphiLive Material'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-6869336341056426925</id><published>2009-04-29T17:08:00.011-06:00</published><updated>2009-04-29T19:07:11.861-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Quality'/><title type='text'>How do you improve Quality?</title><content type='html'>There typically are 3 types of projects, when it comes to quality that I have seen.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The focus is getting the code out the door and then you pick up the pieces.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The focus is on getting quality code out the door until deadline nears then you revert to number 1.&lt;/li&gt;&lt;li&gt;The focus is on getting quality code out the door and as deadline nears features may be dropped and the deadline may slip.&lt;/li&gt;&lt;/ol&gt;When the project starts everyone seems to be on board with the idea of #3 but typically I have seen it slip all the way to #1 quite quickly.&lt;br /&gt;&lt;br /&gt;At my current employer we have an internal application that is used by 300+ end users.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;We used to have:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ZERO people dedicated to QA.  (4-5 Delphi Developers, 1 Mainframe Programmer, no analysts)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Testing was done by end users testing as they had time.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We had no automated or unit tests.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The build process was compile from your own machine and copy it the network, with any developer free to release any code they wanted.  Which would sometimes step over the other developers uncommitted code.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We had two environment's&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Development used by both developers and testing.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Production   &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Exceptions had no details or context to help track down problems.&lt;/li&gt;&lt;li&gt;We had a very small and painful bug tracking system.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We would commonly be related to #1 type model above.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Over the few years that I have been here we have made many changes.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;We now have:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We now have three people dedicated to QA.    ( 7 Delphi Developers, 1 Database PL/SQL developer, and 1 Analyst)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We have end users still testing with the time that they have.  But we now have better management support to get additional time needed.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We have a few automated tests, and a few more unit tests, but we really could use many more.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Our build process runs every hour through &lt;a href="http://www.finalbuilder.com/"&gt;Final Builder&lt;/a&gt;, alerting us with email when someone checks in bad code.&lt;/li&gt;&lt;li&gt;We now have 4 environment's&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Development (Dedicated to Developers only)&lt;/li&gt;&lt;li&gt;TEST where users get first look&lt;/li&gt;&lt;li&gt;QA a final look before production usually with data refreshed from production&lt;/li&gt;&lt;li&gt;Production.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;We now use the &lt;a href="http://jcl.delphi-jedi.org/"&gt;JCL Debug&lt;/a&gt; to help use find those &lt;a href="http://robstechcorner.blogspot.com/2009/04/finding-hard-to-reproduce-errors.html"&gt;Hard to Reproduce Errors&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We have a better bug tracking system, but still not nearly as nice as some of the home grown solutions I have used at past employers.&lt;/li&gt;&lt;li&gt;We are now some where between the #2 and #3 model's above.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Every release we ask what can we do better?   We try to learn from our mistakes and implement solutions to prevent problems.      We release a new version of our software nearly every month, so we are continually improving, and quality has improved in many ways in the past few years.&lt;br /&gt;&lt;br /&gt;However, today I feel awful!    &lt;br /&gt;&lt;br /&gt;We put out a release on Friday morning last week.  I don't think I have ever had a release go bad as this one has.  Today we are still working on fixing major problems that were caused by the release.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Some of which would have been caught by better testing.   &lt;/li&gt;&lt;li&gt;Some of which would have been caught by better management of the information coming in about problems.  (i.e. it was reported but not acted on!) Since, I usually manage this information, it's the reason I feel awful. &lt;/li&gt;&lt;li&gt;Of course like all systems some of them would have taken an unreasonable amount of testing to find. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;So I have been thinking, it's time to go back to and look at quality in new and different ways.&lt;br /&gt;&lt;br /&gt;I have been making a list for a while that specific to our product on ways to improve quality.   Several items on the list are general enough to share with others.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Build a health check system detects common/possible problems that can be run daily in each environment's, which is very database specific. We have scripts for all of these, but not an automated way to run them.&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Tables without primary keys&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Missing Synonyms&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Invalid Synonyms&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Tables without indexes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Missing Grants&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Disabled Constraints in Oracle&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Tables that have not been analyzed recently.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;FK Constraints without index on child table (table level lock will be placed on the parent table if these are found)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Invalid Database Objects&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Plus several that are specific to our schema, i.e. constraints that can't be described in meta data.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Error Messages (Exceptions)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ability to Send error messages to a web service&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ability to &lt;a href="http://robstechcorner.blogspot.com/2009/04/enhanced-screen-capture-code.html"&gt;capture a screen shot&lt;/a&gt; with the error message.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ability to ask users what they are doing when the exception occurred.&lt;/li&gt;&lt;li&gt;Ability to attach reported errors to items in bug tracking system.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Code Review to help identify and build additional unit tests around the code.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Automated Performance Testing Benchmark system. (I think &lt;a href="http://sourceforge.net/projects/dunit/"&gt;DUnit&lt;/a&gt; has something that will work for us)&lt;/li&gt;&lt;li&gt;Get current Delphi Unit tests into an daily build and smoke test instead of just being run by hand by developers.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;Ok...&lt;br /&gt;&lt;br /&gt;I have shared some of my ideas on how to improve quality, as well as some of the things we have done.  &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;How have you improved Quality in the software you write?&lt;/span&gt;  &lt;br /&gt;&lt;br /&gt;I am open to any suggestions, this is just a small attempt to think out side of the box. &lt;br /&gt;&lt;br /&gt;Since I just started this blog, I really hope that someone is reading this and has some good ideas they are willing to share.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-6869336341056426925?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/6869336341056426925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/how-do-you-improve-quality.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6869336341056426925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6869336341056426925'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/how-do-you-improve-quality.html' title='How do you improve Quality?'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-2368977117943454050</id><published>2009-04-13T10:33:00.016-06:00</published><updated>2009-04-15T17:53:20.531-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Enhanced Screen Capture Code</title><content type='html'>I had this crazy idea the other day.   I want to see what my users screen looks like at the time an exception occurred.    A quick Google search led me to &lt;a href="http://delphi.about.com/od/adptips2006/qt/captureactive.htm"&gt;this snippet&lt;/a&gt; of code on &lt;a href="http://delphi.about.com/"&gt;about.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After a bit of testing I found out that it only captures the main desktop or active window.    Well since many of our users run with multiple monitors, it's possible our application is running on the second monitor.  This means that if I capture the main desktop would potentially reveal nothing valuable.&lt;br /&gt;&lt;br /&gt;So I rewrote the code to handle multiple monitors better.&lt;br /&gt;&lt;br /&gt;So here is the interface section.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;uses&lt;br /&gt;  Windows, SysUtils, Graphics, MultiMon;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  EMonitorCaptureException = class(Exception);&lt;br /&gt;&lt;br /&gt;  TCaptureContext = (ccActiveWindow,ccDesktopMonitor,ccActiveMonitor,&lt;br /&gt;                     ccSpecificMonitor,ccAllMonitors);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function MonitorCount : Integer;&lt;br /&gt;&lt;br /&gt;procedure CaptureScreen(aCaptureContext : TCaptureContext; destBitmap : TBitmap;aMonitorNum : Integer = 1);&lt;br /&gt;&lt;br /&gt;procedure CaptureRect(aCaptureRect : TRect;destBitMap : TBitmap); inline;&lt;br /&gt;&lt;br /&gt;procedure CaptureDeviceContext(SrcDC: HDC;aCaptureRect : TRect;destBitMap : TBitmap); inline;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The enumerated type TCaptureContext allows few different options.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;ccActiveWindow: Capture an image of the ActiveWindow only.&lt;br /&gt;&lt;li&gt;ccDesktopMonitor: Capture an image of the primary/first monitor.&lt;br /&gt;&lt;li&gt;ccActiveMonitor:  Capture an image of the monitor with the active window on it.  If the active window is on more than one monitor it will pick the monitor that has the larger portion of the window on it.   If the active window is not in the visible space of any monitor, it will pick the closest one.&lt;br /&gt;&lt;li&gt;ccSpecificMonitor: Capture an Image of a Specific Monitor specified by the aMonitorNum parameter.  Note: aMonitorNum the first monitor is 1.   You can use the MonitorCount function to determine the valid range of monitors.  An EMonitorCaptureException will occur if you select a monitor number outside the valid range.&lt;br /&gt;&lt;li&gt;ccAllMonitors: Capture a single image of all the monitors.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;The entire code for the unit can be &lt;a href="http://code.google.com/p/robstechcorner/source/browse/trunk/Delphi/utils/SCapture.pas"&gt;downloaded from my SVN Repository.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To see it in Action...&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;File | New VCL Form Application.&lt;br /&gt;&lt;li&gt;Add SCapture.pas to the project, or place it in your library path&lt;br /&gt;&lt;li&gt;Drop down an Button and an Image on the Form&lt;br /&gt;&lt;li&gt;Place the following code in your button.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;var&lt;br /&gt; b : TBitMap;&lt;br /&gt;begin&lt;br /&gt; b := TBitmap.Create;&lt;br /&gt; try&lt;br /&gt;    CaptureScreen(ccAllMonitors,B,1);&lt;br /&gt;    Image1.Picture.Assign(b);&lt;br /&gt; finally&lt;br /&gt;   b.FreeImage;&lt;br /&gt;   b.Free;&lt;br /&gt; end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There is also another routine that allows you to capture any Rect from the display.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: delphi"&gt;&lt;br /&gt;var&lt;br /&gt; b : TBitMap;&lt;br /&gt; r : TRect;&lt;br /&gt;begin&lt;br /&gt; b := TBitmap.Create;&lt;br /&gt; try&lt;br /&gt;    r.top := 20;&lt;br /&gt;    r.Left := 20;&lt;br /&gt;    r.Bottom := 200;&lt;br /&gt;    r.Right := 200;&lt;br /&gt;    CaptureRect(R,B);&lt;br /&gt;    Image1.Picture.Assign(b);&lt;br /&gt; finally&lt;br /&gt;   b.FreeImage;&lt;br /&gt;   b.Free;&lt;br /&gt; end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Going back to the crazy idea of getting a screenshot on an exception.   I have not implemented it yet, but something things to think about if you going to try.  &lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;EOutofMemory and EOutofResource Exceptions will most likely cause this code to fail, I would check the Exception class and if it's one of these don't take the screen shot.&lt;br /&gt;&lt;li&gt;Unhandled Exception's raised in the Exception Handler mask the original error.  So if taking the screen shot fails, don't annoy the user.&lt;br /&gt;&lt;li&gt;Privacy &amp; Security:   The images of the desktop may contain information that may violate users privacy or be a security risk of image is not secured.&lt;br /&gt;&lt;li&gt;You want to capture the screen before the exception dialog appears otherwise the information you want will be masked by the dialog.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Regardless of my concerns, I will be coming up with a solution the positive outcome is greater than any potential negatives.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-2368977117943454050?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/2368977117943454050/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/enhanced-screen-capture-code.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2368977117943454050'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2368977117943454050'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/enhanced-screen-capture-code.html' title='Enhanced Screen Capture Code'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-2417127485062607139</id><published>2009-04-08T11:24:00.000-06:00</published><updated>2009-04-09T16:01:17.280-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Finding the Hard to Reproduce Errors</title><content type='html'>I used to do a ton of contract work.  One of the most common reasons I was called out to a company was that their users were experiencing an exception, usually an access violation, which they could not reproduce in the development environment.  &lt;br /&gt;&lt;br /&gt;Since I have been fairly busy, and I really don't have time to do side work.  I had a request to share what I do in this case, so they could go about fixing it with out me. Instead of just responding via email with my methods of madness, I decided to share the way I do this with everyone.&lt;br /&gt;&lt;br /&gt;First off the only way your going to get information to help is with good logging. There are a variety of tools out there to help. But I have found a good old text file is typically the easiest method, although products like &lt;a href="http://www.gurock.com/products/smartinspect/"&gt;SmartInspect&lt;/a&gt; and &lt;a href="http://www.raize.com/DevTools/CodeSite/Default.asp"&gt;CodeSite&lt;/a&gt; offer quite a bit more and may be worth investing in, I will let you evaluate and decide.&lt;br /&gt;&lt;br /&gt;The problem with logging is that the information is only as good as what you supply.  You don't know where the error is going to occur and you really don't need a log file endlessly filling up with useless information.    So how do you know where to log?  Well my favorite places to log information on Screen changes.  That way I know the order of the screens visited, and sometimes key values that are needed for that screen.   I also add verbose logging on a temporary basis for hard to find problems.  &lt;br /&gt;&lt;br /&gt;But hey! The odds are I have told you nothing that you did not know already.&lt;br /&gt;&lt;br /&gt;I have found many people are not familiar with call stack logging when an exception occurs.  In .NET getting the exception call stack is easy, you just need to reference the .StackTrace property on the exception. Once you have that write it out to your log file, using your method of choice.&lt;br /&gt;&lt;br /&gt;However, with native code it requires quite a bit more work. This is because information about method names and line numbers are not part of the compiled code.&lt;br /&gt;In Delphi the information that contains this information is in the MAP file. The key is how do you get this information at the time of the exception and log the details you need.&lt;br /&gt;&lt;br /&gt;There are two commercial products out there that do just that and more.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.eurekalog.com/"&gt;EurekaLog&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.madshi.net/madExceptDescription.htm"&gt;MadExcept&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I however use an open source alternative that works well.   It's was also great when doing consulting as I did not have to make them buy a commercial product.   &lt;br /&gt;&lt;br /&gt;The &lt;a href="http://jcl.delphi-jedi.org/"&gt;Jedi Class Library (JCL)&lt;/a&gt; has the libraries needed to do this.  It's used by &lt;a href="http://www.embarcadero.com/"&gt;Embarcadero&lt;/a&gt; inside of  Delphi to report errors to &lt;a href="http://qc.codegear.com/"&gt;Quality Central&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So take a moment if you have not already do it and &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=47514"&gt;download it now&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After installing the JCL, you will want to open and look at the following Demo applications found in the "jcl\examples\jclDebugExamples.bdsgroup" project group.&lt;br /&gt;It offers a fairly good look at the possibilities.&lt;br /&gt;&lt;br /&gt;Ultimately the question is: How do I plug the JCL Debug into my application and make it useful.&lt;br /&gt;&lt;br /&gt;Here are simple steps to do this.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Download and Install JCL&lt;br /&gt;&lt;li&gt;Open "jcl\experts\debug\tools\MakeJclDbg.dpr" and Compile.  It may have already been compiled during install.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Open: "jcl\experts\debug\dialog\CreateStdDialogs.dpr"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Look at "Params." around line 80 and set the params you want.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Run the application.&lt;br /&gt;ExceptDlg.pas/dfm and ExceptDlgMail.pas/dfm will be generated&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Copy these to your application source directory.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Add ExceptDlg to the uses of your project.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Turn on .MAP file generation in your project options. (Found under linker section)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Build your project.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;At the command line run MakeJclDbg -E YourProjectName.MAP&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;You are good to go!   Unhandled exceptions in your application will be replaced by this new dialog.   Since the code to the dialog is in your source directory you can change it to meet your specific needs and/or design layout.  &lt;br /&gt;&lt;br /&gt;In the last few steps, I showed you my preferred method of dealing with information for symbols, but the JCL supports many other methods.&lt;br /&gt;&lt;br /&gt;For example there is an expert that you can install that will do the same thing without dropping to the command prompt.    Since I never deploy an application that is compiled in the IDE, I use &lt;a ref="http://www.finalbuilder.com"&gt;FinalBuilder&lt;/a&gt;, calling MakeJclDbg seems second nature.&lt;br /&gt;&lt;br /&gt;One of the key things is that symbols can be stored in a variety of different ways, and JCL will search for them in the following order.&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt; JCL Debug data in the executable file (What MakeJclDbg and the Expert will do)&lt;br /&gt;&lt;li&gt; JDBG file&lt;br /&gt;&lt;li&gt; Borland TD32 symbols&lt;br /&gt;&lt;li&gt; MAP file&lt;br /&gt;&lt;li&gt; Library or Borland package exports&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;There is a good document on the options found in "\jcl\experts\debug\HowTo.txt"&lt;br /&gt;&lt;br /&gt;Now the most surprising question that I have heard over and over after doing this is: What do I do with this information?  &lt;br /&gt;&lt;br /&gt;Well you now have a call stack when the exception occurred.  You can see also see the line the exception occurred on.   Often looking at the line of code where the error occurred shows that the given method was called incorrectly.  With the call stack you can see the line of code that called that method.   This typically this should give you enough of a clue to resolve the problem, or at the very least you will know where to add more logging to figure it out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-2417127485062607139?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/2417127485062607139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/finding-hard-to-reproduce-errors.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2417127485062607139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/2417127485062607139'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/finding-hard-to-reproduce-errors.html' title='Finding the Hard to Reproduce Errors'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-6319052438587834742</id><published>2009-04-07T06:29:00.000-06:00</published><updated>2009-04-13T16:18:17.651-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>The Dark Side (of the moon) or Not?</title><content type='html'>For the past couple of months we have been doing a fairly in depth review of &lt;a href="http://prismwiki.codegear.com/en/Main_Page"&gt;Delphi Prism&lt;/a&gt;. We have a 6-8 month project that we need a fairly complex web service. Our past experience with Delphi for .NET and C# we knew that the API's in .NET would be a big advantage to our project.&lt;br /&gt;&lt;br /&gt;Since we already own RAD Studio, it was time to review and see if Prism was the right technology or if we should just move back to Delphi Native only. The flip-flopping on the .NET side of Delphi has driven me crazy.&lt;br /&gt;&lt;br /&gt;We decided to start with something simple but complex enough to test the needs of our project. If the technology did not prove it's self then we would not be out a ton of time. &lt;br /&gt;&lt;br /&gt;The &lt;a href="http://prismwiki.codegear.com/en/Delphi_Prism_Syntax_compared_with_Win32_Delphi"&gt;language changes&lt;/a&gt; took a few moments to get used to. Then after awhile you start wishing that Delphi Native had the features that are present in the Prism Compiler. I suspect that is partially why they are completely &lt;a href="http://edn.embarcadero.com/article/39174"&gt;rewriting the Delphi Native Compiler&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The IDE in Prism is &lt;a href="http://msdn.microsoft.com/en-us/vsx2008/products/bb933751.aspx"&gt;Visual Studio&lt;/a&gt; but I found the transition to the different IDE fairly easy, of course I have done quite a bit of C# work in the past.&lt;br /&gt;&lt;br /&gt;Overall I have to say I am impressed. We have been able to build a solid web service in short time. The language being Pascal based is a huge win as it requires far less training that switching to entirely different language. I also liked several of the &lt;a href="http://prismwiki.codegear.com/en/Delphi_Prism_vs._CSharp"&gt;language features that C# does not have&lt;/a&gt;. Specifically Sets and the colon operator.&lt;br /&gt;&lt;br /&gt;The one drawback I noticed was that there was not direct support for LINQ to SQL. If you have the full VS.NET product you can build a LINQ to SQL assembly and use it fine in Prism. However, Microsoft does not support Oracle which is the Database we use. Microsoft only supports SQL Server. If the DBX team could conquer LINQ to SQL for DBX it could be a huge win. But then again I think the designers only ship with the VS product and not with the Shell, which has been major reason for the flip-flopping of Delphi in the .NET world in the past.&lt;br /&gt;&lt;br /&gt;Will we be using Prism for anything other than &lt;a href="http://www.asp.net/"&gt;ASP.NET technologies&lt;/a&gt;? Well at this point I doubt it. I still am a huge fan of native code development.  It does work well in the ASP.NET environment and we will be using it for our 6-8 Month project we were reviewing the technology for.&lt;br /&gt;&lt;br /&gt;As for the title of the post? Look in the &lt;a href="http://www.codegear.com/products/delphi/prism/faq"&gt;About box&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-6319052438587834742?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/6319052438587834742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/dark-side-of-moon-or-not.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6319052438587834742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6319052438587834742'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/dark-side-of-moon-or-not.html' title='The Dark Side (of the moon) or Not?'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3339459875755088113.post-6771266560136498430</id><published>2009-04-06T17:58:00.000-06:00</published><updated>2009-04-06T18:42:43.022-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='About Rob'/><title type='text'>Blogging Again -or- Opening Mouth to Insert Foot</title><content type='html'>Open Mouth Insert Foot. I feel like I do that enough... So why not start blogging again.&lt;br /&gt;&lt;br /&gt;It's been several years since I last blogged. This time I am not going to try to develop and maintain a site for it. I just don't have the time to play around with duplicating technology that is already free and easy to use. Also, I don't have to worry about server costs and maintenance.&lt;br /&gt;&lt;br /&gt;Well what has happened in the past few years since I quit blogging.&lt;br /&gt;&lt;br /&gt;I started working at the &lt;a href="http://dts.utah.gov/"&gt;State of Utah&lt;/a&gt; full-time, I used to do contract work there. It was the right move for my family and in total I have spent 6+ years there. The State of Utah currently pays for tuition so I am enrolled in school. The school is &lt;a href="http://www.wgu.edu/"&gt;WGU&lt;/a&gt;, it's an online only school. I feel I might as well get that degree sooner or later, and I enjoy research and learning.&lt;br /&gt;&lt;br /&gt;I am still doing the following:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Develop in &lt;a href="http://www.embarcadero.com/products/delphi/"&gt;Delphi&lt;/a&gt; although now I have to manage a team of nine.&lt;/li&gt;&lt;li&gt;President of the &lt;a href="http://www.slcdug.org/"&gt;Salt Lake City Delphi Users Group&lt;/a&gt;. &lt;/li&gt;&lt;li&gt;Finding other ways to open my mouth and insert my foot.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://conferences.codegear.com/"&gt;CodeRage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://conferences.codegear.com/"&gt;DataRage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.delphilive.com/"&gt;DelphiLive&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href="http://www.idos.org/"&gt;Cooking outdoors&lt;/a&gt; as much as possible.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339459875755088113-6771266560136498430?l=robstechcorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robstechcorner.blogspot.com/feeds/6771266560136498430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/blogging-again-or-opening-mouth-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6771266560136498430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3339459875755088113/posts/default/6771266560136498430'/><link rel='alternate' type='text/html' href='http://robstechcorner.blogspot.com/2009/04/blogging-again-or-opening-mouth-to.html' title='Blogging Again -or- Opening Mouth to Insert Foot'/><author><name>Robert Love</name><uri>https://profiles.google.com/113308800011211904149</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-tHEE934Il4U/AAAAAAAAAAI/AAAAAAAAUuQ/bYDNUyC-2G0/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
