<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-6222893893652665733</atom:id><lastBuildDate>Tue, 10 Mar 2026 23:49:58 +0000</lastBuildDate><title>Cary Jensen  &quot;Let&#39;s Get Technical&quot;</title><description>Technical discussions related to software development. Particular attention is paid to Delphi development. Also expect a healthy dose of database-related content, including SQL, data modeling, and general database design.</description><link>http://caryjensen.blogspot.com/</link><managingEditor>noreply@blogger.com (Unknown)</managingEditor><generator>Blogger</generator><openSearch:totalResults>72</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-6826426551320645116</guid><pubDate>Mon, 22 Sep 2025 19:03:00 +0000</pubDate><atom:updated>2025-09-22T12:04:08.582-07:00</atom:updated><title></title><description>&lt;p&gt;&lt;/p&gt;&lt;p class=&quot;MsoNormal&quot;&gt;Join me this October in Düsseldorf, Germany for the annual
Entwickler Konferenz. This will be the 29&lt;sup&gt;th&lt;/sup&gt; year of this engaging
Delphi conference, and it is appropriately named EKON 29.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;I will be giving two presentations this year:&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Leveraging FireDAC’s SQL Command Processor in your Delphi
Applications&lt;br /&gt;
and&lt;br /&gt;
Cloning Cursors and Creating Nested DataSets with FireDAC FDMemTables&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;There are many other excellent talks by some of Delphi’s top
experts, including Ray Konokpa, Marco Geuze, Primož Gabrijelčič, Bruno Fierens
(TMS Software), Bernd Ua, Michael Philippenko (Fast Reports) and too many more
to mention. Follow this link to see the full program: &lt;a href=&quot;https://entwickler-konferenz.de/programm-de/&quot;&gt;https://entwickler-konferenz.de/programm-de/&lt;/a&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;In almost every time slot there is at least one presentation
in German and one in English, with an exception or two when presented in
English.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Register by 25 September and receive an early-bird discount.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;The event runs from 27 October to 30 October, with the last
two days consisting of focused, extended workshops.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;I hope to see you there! Follow this link for more information: &lt;a href=&quot;https://entwickler-konferenz.de/de/&quot;&gt;https://entwickler-konferenz.de/de/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</description><link>http://caryjensen.blogspot.com/2025/09/join-me-this-october-in-dusseldorf.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-992434345266610782</guid><pubDate>Tue, 06 Oct 2020 14:52:00 +0000</pubDate><atom:updated>2020-10-06T07:58:12.426-07:00</atom:updated><title>Deleaker: Advanced Memory Leak Detection for Delphi and RAD Studio</title><description>&lt;p&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; white-space: pre-wrap;&quot;&gt;Beginning with RAD Studio 2006, Delphi, and RAD Studio in general, greatly benefited from the addition of Fast Memory Manager, or FastMM. And one of the truly welcome additions was the global variable ReportMemoryLeaksUponShutdown, which, when set to True and a small block memory leak is detected upon your application’s shutdown, displays a dialog box that identifies what was left behind. It doesn’t identify where the leak occurred, however, only that it happened.&lt;/span&gt;&lt;/p&gt;&lt;span id=&quot;docs-internal-guid-9a3fe44b-7fff-ddd0-282e-3339a14ef933&quot;&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;FastMM continues to be available in RAD Studio, and you should consider downloading the full version from SourceForge (&lt;/span&gt;&lt;a href=&quot;http://sourceforge.net/projects/fastmm/&quot; style=&quot;text-decoration-line: none;&quot;&gt;&lt;span style=&quot;color: #1155cc; font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;http://sourceforge.net/projects/fastmm/&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;) to realize the full potential of FastMM, which includes much more than just memory leak detection, including enabling the generation of a stack trace, which may provide additional information about where the leak occurred.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;That said, as far as memory leaks go, sometimes you need more. Which brings me to Deleaker.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;I recently had the opportunity to try out Deleaker from Softantics in my Delphi applications, and I was impressed. Deleaker is a memory leak detection tool for Windows 32-bit and 64-bit applications. It can integrate with RAD studio and Visual Studio (as well as Qt Creator), and also supports a command line interface that permits you to include Deleaker as part of your continuous integration (CI) process.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;In the past I’ve relied on RAD Studio’s ReportMemoryLeaksOnShutdow to identify memory leaks, but that option only tells you that you have leaks as well as how much memory was leaked. By comparison, Deleaker, when property configured, does an amazing job of identifying the source of the leak, going so far as to identify unit names and even line numbers where the leak originated. It can also find leaks in any module, for example, WinAPI functions such as CoTaskMemAlloc. FastMM cannot find that kind of leak.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Installation is simple, and after installation a new menu item, Deleaker, appears in RAD Studio’s main menu. From that menu you can enable Deleaker for all of your applications, configure Deleaker’s options, and open the Deleaker Console.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;When the installation of Deleaker is complete it displays a help file that explains how to configure RAD Studio to generate the information Deleaker needs in order to serve you. (In short, you need to turn on your compiler and linker debugging options.) This help file, which can also be displayed any time you need it from the Deleaker Console, is well written and easy to follow, and the setup in RAD Studio only requires a few easy steps.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;When Deleaker is enabled, and you are running your application with debugging enabled, the Deleaker Console launches when you shutdown your application. If no leak is detected, it reports that. Alternatively, if a leak is detected, Deleaker can often identify the unit name and line number where the leak likely originated. If the leak is related to a Delphi object, Deleaker will report what class of object produced the leak. This can save you hours of time scrutinizing your code for mishandled resources.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;You can also display the Deleaker Console while your application is running. This permits you to take one or more snapshots of your memory usage, so you can see what’s going on while your application is still running. The Deleaker Console also lets you compare snapshots, which permits you to see changes in memory usage over time.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;The types of leaks that Deleaker can detect are extensive. Here is a list, taken from the Deleaker Help file:&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Memory: memory blocks allocated by heap functions, virtual memory, OLE memory:&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;	&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;BSTR, SAFEARRAY, etc&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;GDI: HBITMAP, HDC, HPEN, etc.&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;User32: HICON, HCURSOR, etc.&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Handles: file handles, events, mutexes, etc.&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;FileView: views of file mappings&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;ActCtxCookie: cookies of activation contexts&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Fiber: fibers made by CreateFiber, etc.&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;CriticalSection: critical sections ((if one has called InitializeCriticalSection but &lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;	&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;forgotten to call DeleteCriticalSection)&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;EnvironmentString: ANSI and UNICODE environment strings&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;FlsSlot: fls slots&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;TlsSlot: tls slots&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Atom: atoms.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;During development, when Deleaker is enabled, you need to run your application with debugging enabled. However, it is also possible to use Deleaker with an application that is running outside of Delphi. For example, on a machine on which Delphi is not installed. Simply copy the Deleaker Console onto the machine, and then run it (Microsoft’s .NET Framework 3.5 might need to be installed). From there you can either launch your application from the Deleaker Console, or even attach to your already running application.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;You can check out Deleaker free for 14 days, after which you can buy a license. Available licenses include a home license (for personal use), a single developer license, and site licenses.&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 12pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;You can find the Deleaker home page at &lt;a href=&quot;https://www.deleaker.com/&quot;&gt;https://www.deleaker.com/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;&quot;&gt;Copyright © 2020. All Rights Reserved.&lt;/p&gt;&lt;/span&gt;</description><link>http://caryjensen.blogspot.com/2020/10/deleaker-advanced-memory-leak-detection.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-4481896598722036175</guid><pubDate>Wed, 12 Feb 2020 20:08:00 +0000</pubDate><atom:updated>2020-02-12T12:08:34.216-08:00</atom:updated><title>25 Years of Communicating about Delphi</title><description>Delphi turns 25 this Friday, and I’ve been fortunate to have had a front row seat. And, in addition to being a life-long database application developer, I’ve also made a career out of sharing information about software development, through books, magazine articles, conference talks, and training seminars. In this post I want to reflect back on those heady days when Delphi first came on the scene. For those who’ve been with me on this journey, thank you. For those of you who are too young to have had this pleasure, may your careers be as rich and as rewarding as it has been for those who’ve been there the whole time.&lt;br /&gt;
&lt;br /&gt;
I was a frequent member of the Borland Conference (BorCon) advisory board, and that exposed me to Delphi early in its development stage. At the time I was an associate editor and columnist for Paradox Informant Magazine, and Delphi sounded like it was going to be the compiler that we Paradox developers had been waiting for.&lt;br /&gt;
&lt;br /&gt;
And it was. As my longtime friend Ann Lynnworth predicted, Delphi reduced Paradox to a mere file format. It was clear to me that Delphi was going to be a really big deal. As a result, in the pre-release times I took two steps to join the Delphi community as a charter member. I committed to Informant Group publisher Mitch Koulouris to write a monthly column for his new Delphi Informant Magazine. My column, called DBNavigator (after the Delphi component), focused primarily on database development and related issues. In that first issue I described using the Borland Database Engine from within Delphi to work with Paradox and Dbase tables. That was the first of 42 consecutive issues in which my column appeared, though I continued to be a regular contributor for the remaining years of publication.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXyciBKRFxE3BYNAJrRoLLhycS1vJKcOIdrytcjRZb0Fsd52AvmcHWsMlfgJz4rcDsppTblcRY95jZ-ht8P0t_2WHJznIc5hrRyzSIUQz7k-MW2Y4QC30A-8AT6b1hgwgId47s5i2foOI/s1600/Delphi+Informant+Premiere+Issue.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;1229&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXyciBKRFxE3BYNAJrRoLLhycS1vJKcOIdrytcjRZb0Fsd52AvmcHWsMlfgJz4rcDsppTblcRY95jZ-ht8P0t_2WHJznIc5hrRyzSIUQz7k-MW2Y4QC30A-8AT6b1hgwgId47s5i2foOI/s320/Delphi+Informant+Premiere+Issue.jpg&quot; width=&quot;245&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;b&gt;The front cover of the premiere issue of Delphi Informant Magazine, published in May of 1995&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
My second commitment was to Softbite International president Kevin Smith, to write and present a two-day Delphi course if he would take it out on tour. I had been working with Softbite for some years, and was a presenter on the Paradox 5 for Windows World Tour, and wrote the material for, and presented, on the Paradox 7 for Windows World Tour. He agreed, and this new 24 city tour was known as the Delphi World Tour. It began in Columbus, Ohio on July 6th of 1995. I taught that first stop, as well as about 12 others. I believe there were two other presenters, one of them being the venerable Bill Todd. If there was another, I can’t remember who it was. They (or he) covered the remaining cities.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpZsuQwWoMDahlK-YNk4QX4lsU_OxzHdJvq64miG90cEPo3yLqAkZyt5BMcUTP6mtUP9r_b7pLGZfSdy1m8Pk9_oaUlOx5j4gzg_I3o1Piga4dTS95bqrq6EZiiyX9QFIeYToI0GgQbdI/s1600/Delphi+World+Tour+ad.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;1229&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpZsuQwWoMDahlK-YNk4QX4lsU_OxzHdJvq64miG90cEPo3yLqAkZyt5BMcUTP6mtUP9r_b7pLGZfSdy1m8Pk9_oaUlOx5j4gzg_I3o1Piga4dTS95bqrq6EZiiyX9QFIeYToI0GgQbdI/s320/Delphi+World+Tour+ad.jpg&quot; width=&quot;245&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;b&gt;An ad for the original Delphi World Tour appearing in the July 1995 issue of Delphi Informant&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
Despite my principal work being as a Delphi developer, I continued to write and present the Delphi World Tours (the final being the Delphi 5 World Tour), and followed that with Delphi Development Seminars in conjunction with Informant Communication Group (one year only), several years of the Borland Developer Days (Europe, in conjunction with Desktop Associates), and then Delphi Developer Days, which I started with my wife, Loy Anderson. Delphi Developer Days ran from 2001 (where the first stop on the tour, Arlington, Virginia, had to be cancelled after the 9/11 attacks due to the closing of Metro underground that ran past the Pentagon and the number of government attendees, whose priorities changed after that awful event) and continued through 2017.&lt;br /&gt;
&lt;br /&gt;
We expanded Delphi Developer Days in 2009 by added a second presenter, which gave me the opportunity to work with four of the top Delphi professionals, all Spirit of Delphi recipients: Marco Cantú, Bob Swart, Ray Konopka, and Nick Hodges. Thanks, guys. It was a great pleasure.&lt;br /&gt;
&lt;br /&gt;
During the past 25 years I have written about and/or trained developers on every version of Delphi (including the notorious .NET only Delphi 8), and as you might imagine, I have acquired a museum-like collection of software. One of my favorites, shown here, is my original, shrink-wrapped copy of Delphi Client/Server.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHdUlXai_6qVLRmITmjuo5kKM-nwMBDpb4TdVU0cpYhZ47OJ6r1RlWzNPG2iTW1QzVX7CE-kJOcaZcvvC1alZ9BjmB8yY9r7kc_W-HCb6mjaWrmIEsy3SeYIC6geWBglvkAqVszQ_YCXk/s1600/DelphiCS.jpg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;1261&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHdUlXai_6qVLRmITmjuo5kKM-nwMBDpb4TdVU0cpYhZ47OJ6r1RlWzNPG2iTW1QzVX7CE-kJOcaZcvvC1alZ9BjmB8yY9r7kc_W-HCb6mjaWrmIEsy3SeYIC6geWBglvkAqVszQ_YCXk/s320/DelphiCS.jpg.png&quot; width=&quot;252&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;b&gt;A shrink-wrapped copy of the original Delphi Client/Server&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
I have a lot of stories that I could share about Delphi, but I think I’ll leave those for another time. I mean, there’s a real danger here. I know myself pretty well, and once I got started, I’d probably have to write an entire book, and I just don’t have the time for that right now, my being committed to a new startup.&lt;br /&gt;
&lt;br /&gt;
But a particular observation comes to mind. To quote the immortal Grateful Dead, and in respect for David Intersimone’s penchant for wearing tie-dye t-shirts, I have to say “What a long strange trip it’s been.”&lt;br /&gt;
&lt;br /&gt;
Let me conclude with an observation and a positive thought. Delphi is still going strong, and the latest version, Delphi Rio 10.3.3, is the best yet. So, Cheers! Here’s to the next 25 years.&lt;br /&gt;
&lt;br /&gt;
Copyright © 2020. All Rights Reserved.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://caryjensen.blogspot.com/2020/02/25-years-of-communicating-about-delphi.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXyciBKRFxE3BYNAJrRoLLhycS1vJKcOIdrytcjRZb0Fsd52AvmcHWsMlfgJz4rcDsppTblcRY95jZ-ht8P0t_2WHJznIc5hrRyzSIUQz7k-MW2Y4QC30A-8AT6b1hgwgId47s5i2foOI/s72-c/Delphi+Informant+Premiere+Issue.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-1915151989310376838</guid><pubDate>Thu, 21 Nov 2019 18:23:00 +0000</pubDate><atom:updated>2019-11-21T10:23:45.052-08:00</atom:updated><title>Exploring the Navigation Toolbar</title><description>&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: justify;&quot;&gt;
&lt;span style=&quot;text-align: left;&quot;&gt;There have been a few times when a major feature of the IDE
has gone largely unnoticed, but they are rare. Nonetheless, it has happened
again in a recent release of Delphi. Since the release of Delphi XE8, Delphi&#39;s
IDE now sports some new informational and navigational features that are big,
really big. And, so far, most Delphi developers that I&#39;ve demonstrated these to have been surprised, and shocked, and have immediately changed the way they work with
units while in Delphi&#39;s editor. This feature is call the Navigation toolbar,
and it&#39;s easy to miss.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The Navigation toolbar appears just above the code editor
when the Code tab is selected in the designer. The Navigation toolbar is shown
in the following figure. There&#39;s not much to it, is there. This is why it&#39;s
easy to miss.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiijGHWK1JCge8rK4ijSGAlw2wewhnbvJAwApSclgny0KiXP7jOZx1g2RSehmP88oTM6aumziuZ48duToS_bYhzIKJHCpfosMHqk93JSUUowJPwPQnI1EWmZV0kRcbshAZ4ntoBPwdvZlU/s1600/fig1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;40&quot; data-original-width=&quot;884&quot; height=&quot;27&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiijGHWK1JCge8rK4ijSGAlw2wewhnbvJAwApSclgny0KiXP7jOZx1g2RSehmP88oTM6aumziuZ48duToS_bYhzIKJHCpfosMHqk93JSUUowJPwPQnI1EWmZV0kRcbshAZ4ntoBPwdvZlU/s640/fig1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The Navigation toolbar is used both for information, as well
as navigation and searching. You can determine which unit is being displayed in
the code editor by the text that appears on the currently selected tab, and
that&#39;s been a feature of the IDE since Galileo was originally released with C++
Builder and Delphi 8 (and, the tabs are not part of the Navigation toolbar, The
Navigation toolbar is only the thin slice beneath the tabs). When the insertion
point (the current position of the cursor in the editor) is within a type
declaration or a type implementation, the type appears in the Types combo box.
This is shown in the following figure, where the insertion point is in the
TUserData declaration of the Win.UserData unit of the UserData project.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;
&lt;o:p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6pGPxdzXAukcqGgJmWOFeIK7owNrICOZAIotB3CL1Uhcyy2I1WKUDka5uNVLMI9l_bQZ1uWLUI0TuaEi5WeFOV_31tWr7VJJ9Bd_Urhh48AmqfuLY1LZzAI8pe1ryBAdHZdgP_Itxm-0/s1600/fig2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;40&quot; data-original-width=&quot;884&quot; height=&quot;28&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6pGPxdzXAukcqGgJmWOFeIK7owNrICOZAIotB3CL1Uhcyy2I1WKUDka5uNVLMI9l_bQZ1uWLUI0TuaEi5WeFOV_31tWr7VJJ9Bd_Urhh48AmqfuLY1LZzAI8pe1ryBAdHZdgP_Itxm-0/s640/fig2.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;o:p&gt;&lt;br /&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
If your insertion point is in the implementation of a
method, the class or record appears in the Type combo box, and the method
appears in the Methods combo box.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc79EgbbE7GyDGKFUjSMM74JTN6yXMFeFZ4jwgHL6kFUdd-MVGFBXs429fbGdOKAnBv0bccVPOWySpWqLH6p-WfTzfJRbZYPw7iktB7WRW_hMh6yjzVdDdLA1TZ2DnASkOkELrkjB0GaI/s1600/fig3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;40&quot; data-original-width=&quot;884&quot; height=&quot;28&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc79EgbbE7GyDGKFUjSMM74JTN6yXMFeFZ4jwgHL6kFUdd-MVGFBXs429fbGdOKAnBv0bccVPOWySpWqLH6p-WfTzfJRbZYPw7iktB7WRW_hMh6yjzVdDdLA1TZ2DnASkOkELrkjB0GaI/s640/fig3.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
If your insertion point is inside the implementation of a
pure function or procedure, the Type combo box will be empty, and the procedure
or function name will appear in the Methods combo box, as shown in the
following figure.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHSmOvDYMEsZ0n-fU6ITaNHTyC7CxcVAM2-PyTOZIlNf0ibAONf8s0xSJ_sHWOLUadg159uehwnn5UmvDOhogNdahv4-6MfY9whMhurvF6n4TQs2LU8CAL0nDXmYACy5Zrgjl9G5X5HLc/s1600/fig4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;40&quot; data-original-width=&quot;884&quot; height=&quot;28&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHSmOvDYMEsZ0n-fU6ITaNHTyC7CxcVAM2-PyTOZIlNf0ibAONf8s0xSJ_sHWOLUadg159uehwnn5UmvDOhogNdahv4-6MfY9whMhurvF6n4TQs2LU8CAL0nDXmYACy5Zrgjl9G5X5HLc/s640/fig4.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
While serving to inform you where your insertion point is
located, you can also use the Type and Method combo boxes to navigate your
units, and this is where the real advantage of the Navigation toolbar begins to
emerge.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Again, with the Win.UserData unit selected, I can easily
move between the various types declared in this unit by dropping down the Type
combo box, as shown in following figure.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM8cACkBlNW7zJzDSOmVVZbN-iZEAzIQudRajxPai38upgFIU0O-B0BUTsKbHdGyLGW9nX4Vy1yf5mAlywocInVnqM_ZJDjNfFew0EwKpcPBMpzBkGzcEwIMcLALQEjRl3i4z7MTaETEQ/s1600/fig5.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;712&quot; data-original-width=&quot;891&quot; height=&quot;508&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM8cACkBlNW7zJzDSOmVVZbN-iZEAzIQudRajxPai38upgFIU0O-B0BUTsKbHdGyLGW9nX4Vy1yf5mAlywocInVnqM_ZJDjNfFew0EwKpcPBMpzBkGzcEwIMcLALQEjRl3i4z7MTaETEQ/s640/fig5.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
If the selected type is a class or record, you can further
navigate to a particular method of that type by dropping down the Method combo
box.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYXAUfl11zZEtZOZnWk9g7_RJBGh8iAdmTdiDS7TavT5RADlRfe7UYnHYzk-qxhfohwlG7wJOzOcYjUMRN-ePoTbdPUyuwXg3f0ZH_hIH2WucwJ1CXvzJyVxqUAmf6Ihfm3aK4VujHLnw/s1600/fig6.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;712&quot; data-original-width=&quot;891&quot; height=&quot;510&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYXAUfl11zZEtZOZnWk9g7_RJBGh8iAdmTdiDS7TavT5RADlRfe7UYnHYzk-qxhfohwlG7wJOzOcYjUMRN-ePoTbdPUyuwXg3f0ZH_hIH2WucwJ1CXvzJyVxqUAmf6Ihfm3aK4VujHLnw/s640/fig6.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
While you can easily do this with your mouse, both the Type
combo box and Method combo box dropdowns can also be accessed using key
combinations. For the Type combo box, press Ctrl-Alt-N + Ctrl-Alt-T. That is,
hold down the Ctrl and Alt keys while pressing N, and then release and then
hold down the Ctrl and Alt keys while pressing T, and then release. Access the
Method combo box dropdown by pressing Ctrl-Alt-N + Ctrl-Alt-P. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
While I love the Type and Method combo boxes, my favorite
feature of the Navigation toolbar is the File Sections combo box. This combo
box permits you to instantly navigate to a specific section of the current
unit, a feature that you will use over and over. This combo box, shown in the
following figure, can also be accessed using the Ctrl-Alt-N + Ctrl-Alt-S key
combination.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglMXnF94idZsxgV4TgLntL1BKonBCHX2SWn5JNtq-Oin-fk_uujbTBkao9Cyu3gyVmSOTtMZp9QjdYSa8vDuuuenL6ShXTSGl7hkFhumqqic5FhcFweWjQp9iPujHHTyG-1lQwzRmuz6E/s1600/fig7.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;197&quot; data-original-width=&quot;890&quot; height=&quot;140&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglMXnF94idZsxgV4TgLntL1BKonBCHX2SWn5JNtq-Oin-fk_uujbTBkao9Cyu3gyVmSOTtMZp9QjdYSa8vDuuuenL6ShXTSGl7hkFhumqqic5FhcFweWjQp9iPujHHTyG-1lQwzRmuz6E/s640/fig7.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
To the left of the File Sections combo box you will find the
Used Units combo box. This combo box displays all of the units used by the
current unit (both interface and implementation section uses clauses), and
permits you to easily open and navigate to any of those units (assuming that
the source code is available). The Used Units combo box, shown in the following
figure, can also be displayed by pressing the Ctrl-Alt-N + Ctrl-Alt-U key
combination.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_1FuxYMWvi8jVq1X84eP1UB_1QYHQO5NurQ63tj2effRSf7KfMntRHjBV1bJH4G5K_v9fKMMKROF_WP2KTydStOddnnBxH4PkEmAJp1snZNt9t2NN4V5PgXKHwcBcVqeDyQtw3DkHXjM/s1600/fig8.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;197&quot; data-original-width=&quot;890&quot; height=&quot;140&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_1FuxYMWvi8jVq1X84eP1UB_1QYHQO5NurQ63tj2effRSf7KfMntRHjBV1bJH4G5K_v9fKMMKROF_WP2KTydStOddnnBxH4PkEmAJp1snZNt9t2NN4V5PgXKHwcBcVqeDyQtw3DkHXjM/s640/fig8.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
There is one more feature available from the Navigation
toolbar. To the right of the Methods combo box you will find the Project Symbol
Search feature, which is represented by a magnifying glass icon.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Click on the magnifying glass icon, or press Ctrl-Alt-N +
Ctrl-Alt-F, and the Navigation toolbar will display a search window and an
associated Results list box. As you type characters, all symbols within the
current project that include those consecutive characters that you&#39;ve typed
will appear in the Results list box (in the following figure I have typed &lt;b&gt;btnc&lt;/b&gt;).
If you then click on, or select and press the Enter key, any of the results,
you instantly navigate to the selected unit and symbol declaration.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPqqO1FOA5ad8DG92xJ_UjzdFrsgbBU8dduLMcsnS1OYwiAm4NMlorzmAWuo-pkK3frSR7Nw0yhQGOzmsn3pxGZNCByOeucoNwPNnIQRp4I22BOCj67Nf10v8Sz_S1xwxWBnP4q1DC6s8/s1600/fig9.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;736&quot; data-original-width=&quot;890&quot; height=&quot;528&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPqqO1FOA5ad8DG92xJ_UjzdFrsgbBU8dduLMcsnS1OYwiAm4NMlorzmAWuo-pkK3frSR7Nw0yhQGOzmsn3pxGZNCByOeucoNwPNnIQRp4I22BOCj67Nf10v8Sz_S1xwxWBnP4q1DC6s8/s640/fig9.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
That&#39;s it for the Navigation toolbar. However, before we
leave this section I want to point out the down arrow icon that appears at the
upper-right corner of the preceding figure. You probably already know about
this one, since it&#39;s been in the product a long time. But in case you do not,
let me point out that this dropdown displays all open units, in alphabetical
order. This can be very handy when you want to move to an open unit, but you
have so many units opened that only a subset of the open units appear in the
tabs above the editor pane. To use this feature, click on the down-arrow icon,
and then select the unit to which you want to navigate from the displayed
dropdown list.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;,serif; font-size: 12.0pt; mso-ansi-language: EN-US; mso-bidi-font-size: 10.0pt; mso-bidi-language: AR-SA; mso-fareast-font-family: &amp;quot;Times New Roman&amp;quot;; mso-fareast-language: EN-US;&quot;&gt;&lt;br /&gt;&lt;i&gt;
Note: Notice that all of these key combinations used by the Navigation toolbar
start with Ctrl-Alt-N (for navigation) while the second key press is almost
predictable, as in Ctrl-Alt-T for type, Ctrl-Alt-S for section, Ctrl-Alt-U for
Used Units. Only the Methods combo box dropdown key combination is awkward,
using Ctrl-Alt-P, but in that case I must assume the P stands for procedure.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;,serif; font-size: 12.0pt; mso-ansi-language: EN-US; mso-bidi-font-size: 10.0pt; mso-bidi-language: AR-SA; mso-fareast-font-family: &amp;quot;Times New Roman&amp;quot;; mso-fareast-language: EN-US;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;,serif; font-size: 12.0pt; mso-ansi-language: EN-US; mso-bidi-font-size: 10.0pt; mso-bidi-language: AR-SA; mso-fareast-font-family: &amp;quot;Times New Roman&amp;quot;; mso-fareast-language: EN-US;&quot;&gt;Copyright (c) 2017-2019 Cary Jensen. All Rights Reserved.&lt;/span&gt;</description><link>http://caryjensen.blogspot.com/2019/11/exploring-navigation-toolbar.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiijGHWK1JCge8rK4ijSGAlw2wewhnbvJAwApSclgny0KiXP7jOZx1g2RSehmP88oTM6aumziuZ48duToS_bYhzIKJHCpfosMHqk93JSUUowJPwPQnI1EWmZV0kRcbshAZ4ntoBPwdvZlU/s72-c/fig1.png" height="72" width="72"/><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-9163526220130053272</guid><pubDate>Mon, 26 Nov 2018 20:06:00 +0000</pubDate><atom:updated>2018-11-26T12:06:19.855-08:00</atom:updated><title>My Advice: Monitor Your Health</title><description>&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Permit me to share a bit of unsolicited advice. There are
two parts to it. First, get an annual physical from a health professional.
Second, if you sense an unusual change in your health, seek a physician’s
advice.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Getting an annual checkup, with the accompanying tests
(physical examination, blood work) permits you to establish baseline
measurements about your health, which can be useful in identifying trends that
may require additional follow-up. Seeking help when you experience an
unexpected change (increased pain, odd swelling, etc.) can potentially identify
a problem while it is still in an early stage.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
I give this advice because I have seen family and friends
skip annual checkups (“I’m very healthy. I don’t need to see a doctor” or “I
hate going to the doctor”), or ignore warning signs. In one heartbreaking case
for me, this lead to the untimely, and completely avoidable death of a wonderful
individual, depriving us all, permanently, of the joy of their presence.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Consider my situation. I get annual checkups, and during a
recent examination my PSA (prostate specific antigen) blood test showed an
increase in PSA. A subsequent test confirmed this, and I had a biopsy to determine
the cause. It was cancer. Due to the type of cancer, and my age, I had two
options: Radiation and surgery. I opted for surgery, and the operation was
performed at the end of February this year. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Based on the post-surgical lab work on the removed tissue,
and the first three post-op PSA tests, it looked like I was cancer-free. This
changed earlier this month, as I now have a detectable PSA reading, which means
that the cancer is still present. Importantly, we reacted quickly to the
original diagnosis, and we are moving aggressively to address this new
information. By doing so, we are giving me to best opportunity to overcome this
ailment.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
I’m sharing my story, and offering my advice, in hope that
you monitor your health, providing you with the opportunity to address and
overcome any obstacles before they get out of control, to the benefit of you
and your loved ones.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
So, please, if at all possible, adopt a regime of annual
physicals. And if you notice something wrong, or out of the ordinary, get it
checked out.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://caryjensen.blogspot.com/2018/11/my-advice-monitor-your-health.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-6286078925357249522</guid><pubDate>Thu, 04 Oct 2018 22:05:00 +0000</pubDate><atom:updated>2018-10-04T15:05:25.994-07:00</atom:updated><title>Cary Jensen is available to help your Delphi team</title><description>&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;Are you
looking for help with your Delphi applications and/or your Delphi team? I will
be available for contract work starting in mid-November 2018.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;Over the
past 30 years, I have primarily been a software developer specializing in
database applications, but I am also the author of more than 25 books on
software, and have written over 100 courses on software development. I was the
author of, and principle trainer on the original Delphi World Tour in 1995,
continuing until it concluded in 1999. On a related note, I am the founder of
Delphi Developer Days, which began in 2001 and continues to this day.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;On the more
technical level, I have a Ph.D. in Engineering Psychology, specializing in
human/computer interaction. My studies emphasized an analytical approach, with
a heavy dose of statistics.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;Due to my
commitments to writing, Delphi Developer Days, and existing clients, I am
looking for a part-time opportunity, where I can provide from one to three
weeks of support each month.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;I love to
travel, so I am particularly interested in opportunities that include onsite
work almost anywhere in the world, but I am open to some remote support.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;I can help
in the following areas:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;•
Application architecture&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;•
Object-oriented development&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;• Legacy
application migration to recent versions of Delphi&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;•
Application refactoring to improve maintenance and support&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;• Class and
component creation&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;• Evaluating
employee candidates&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;• Developer
training&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;• Developer
mentoring&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;• Class and
component creation&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;• Software
documentation&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;• General
business consulting&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-size: 16.0pt; line-height: 107%;&quot;&gt;If you are
interested in learning more about how I can help your organization, please
contact me at the following email address: cary at jensendatasystems.com.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://caryjensen.blogspot.com/2018/10/cary-jensen-is-available-to-help-your.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-5090508620876836852</guid><pubDate>Mon, 03 Sep 2018 16:04:00 +0000</pubDate><atom:updated>2018-09-04T06:45:29.398-07:00</atom:updated><title>Sign Up for the Delphi Community Edition Boot Camp Today</title><description>&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
If you are new to Delphi, the cross-platform, native
compiling rapid application development (RAD) tool from Embarcadero
Technologies, or know someone who is, there’s an upcoming event that you need
to know about. It is the Delphi Community Edition (CE) Boot Camp.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The Delphi CE Boot Camp is a series of lectures designed to
introduce you to developing world-class applications using Delphi. Beginning on
September 3&lt;sup&gt;rd&lt;/sup&gt;, and continuing for a total of 8 weeks, each week
introduces you to a different aspect of Delphi development, from building the
user interface to compiling applications for iOS and Android devices. Week 1
begins with an introduction to the Delphi language (object-oriented Pascal),
presented by Delphi guru and Delphi Product Manager Marco Cant&lt;span style=&quot;mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;&quot;&gt;ú&lt;/span&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The Delphi CE Boot Camp is free for everyone. To attend, use
the following link to get started: &lt;a href=&quot;https://www.embarcaderoacademy.com/p/the-delphi-ce-bootcamp-2018&quot; target=&quot;_blank&quot;&gt;https://www.embarcaderoacademy.com/p/the-delphi-ce-bootcamp-2018&lt;/a&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The lessons for each week will become available on the date
listed for each topic area. You can watch the lessons any time you want once
they are published. In addition, some lessons are followed up with live question and answer sessions with the instructor. See the Boot Camp site for details.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Don’t have a current copy of Delphi. No problem. So long as
you meet the requirements, you can download and use the free Delphi Community
Edition which became available this past July. The Delphi Community Edition is
a full featured Professional Edition designed to get you up and running. To learn
more about the Delphi Community Edition, along with its terms of use, visit &lt;a href=&quot;https://www.embarcadero.com/products/delphi/starter/free-download&quot; target=&quot;_blank&quot;&gt;https://www.embarcadero.com/products/delphi/starter/free-download&lt;/a&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
If you are a database developer, you will want to attend my
course on database development with Delphi. My lessons will become available on
September 24&lt;sup&gt;th&lt;/sup&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
If you have colleagues who are new to Delphi, please be sure
to share this information with them. There’s never been a better time to get
started with the best native compiler for building applications for Windows,
OSX, iOS, Android, and Linux.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://caryjensen.blogspot.com/2018/09/sign-up-for-delphi-community-edition.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-697080550562690088</guid><pubDate>Tue, 13 Jun 2017 11:06:00 +0000</pubDate><atom:updated>2017-06-13T04:09:21.041-07:00</atom:updated><title>Announcing Delphi Developer Days 2017 Special Edition Database Workshop</title><description>&lt;div class=&quot;MsoNormal&quot;&gt;
I am pleased to announce that registration is now open for
&lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;Delphi Developer Days&lt;/a&gt; 2017 Special Edition Database Workshop with Bob Swart and
me, Cary Jensen, which will be held this fall in the U.S. and Europe.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Unlike our traditional Delphi Developer Days events, which
include a broad range of topics, this workshop focuses exclusively on
database development. It begins with a detailed look at connecting to data and
configuring FireDAC, and continues with a look at some of FireDAC’s more
advanced features, including Array DML, the SQL command preprocessor, and
cached updates. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The workshop continues with an in-depth discussion of
multi-tier development. Topics include creating DataSnap servers and using
Embarcadero’s RAD Server. Here you will learn how to access your data from
mobile applications, how to support both Delphi and non-Delphi clients using
REST (REpresentational State Transfer), and how to create RAD Server
microservices with Delphi.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Both days of this workshop are taught jointly by me and Bob.
You are encouraged (though not required) to bring a laptop in order to follow
along with the provided code samples.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Each attendee will receive a Delphi Developer Days course
book, which includes a special edition of my latest book &lt;i&gt;&lt;a href=&quot;http://www.jensendatasystems.com/FireDACBook&quot; target=&quot;_blank&quot;&gt;Delphi in Depth: FireDAC&lt;/a&gt;&lt;/i&gt;, along with material on DataSnap, mobile
development, and RAD Server written by Bob (Dr.Bob) Swart.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Here are the cities and dates for this fall tour:&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Chicago, 25-26 September 2017&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Antwerp, Belgium, 9-10 October 2017&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Frankfurt, Germany, 27-28 November 2017&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
In addition to the course book, attendees also receive lunch
on each day and all code samples covered during the workshop. Due to the nature
of this workshop format, seating is limited. Register now to save your place in
this special edition database workshop and receive a substantial discount for
early registration. For more information, visit &lt;a href=&quot;http://www.delphideveloperdays.com/&quot;&gt;http://www.DelphiDeveloperDays.com&lt;/a&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The Delphi Developer Days 2017 Special Edition Database Workshop
is taught in English.&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;br /&gt;
Note that we will return with the traditional Delphi Developer Days event in the spring of 2018, where we present both joint as well as separate sessions on a wide variety of Delphi topics.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://caryjensen.blogspot.com/2017/06/announcing-delphi-developer-days-2017.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-7991386460185740789</guid><pubDate>Fri, 12 May 2017 07:03:00 +0000</pubDate><atom:updated>2017-05-12T00:57:12.552-07:00</atom:updated><title>Delphi in Depth: FireDAC is now available</title><description>&lt;div class=&quot;MsoNormal&quot;&gt;
Last autumn, as I was finishing up my chapters for the 2016
Delphi Developer Days course book, which I wrote with Nick Hodges, Director of
Engineering at Embarcadero Technologies, I received a question about FireDAC
from my German colleague Dr. Holger Flick. He was asking about the relevance of
my ClientDataSet book to some work he was doing with FireDAC. I replied that
the book would help to some extent since so many aspects of Delphi database
development were covered by that book, and that I had used FireDAC and
InterBase for many of that book’s examples. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
But his question got me to thinking about the FireDAC
material that I had already written. I had four or five chapters from previous
Delphi Developer Days, I had another three or four articles that I had
published in software-related magazines, and I had several FireDAC
presentations from CodeRage under my belt. I might have half a book there
already. Why not, I thought, my next book will be a &lt;a href=&quot;http://www.jensendatasystems.com/FireDACbook&quot; target=&quot;_blank&quot;&gt;FireDAC book&lt;/a&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
I don’t regret that decision at all, though I must say that
even I was surprised at how much work it was to complete this book. This is my
twenty-sixth book (and that’s not counting the eight Delphi Developer Days
books that we’ve published since 2009). I know how much work it takes to write
a book, but this one was different. The amount of research that this book
required was a surprise.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
For one thing, I felt that this book should be more than
just a FireDAC book. It should be a book that deserves to be on the shelf of
every Delphi database developer. For the new Delphi database developer who is
unfamiliar with the “Delphi way” of doing things, this book contains
discussions of and demonstrations of the essential techniques that every Delphi
database developer needs to know. This includes concepts like the TDataSet
interface, the current record, and how to read to and write from TFields. (Just a note here, this book assumes you are using Delphi XE6 or later.)&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The advanced Delphi database developer, however, is not left
out. These developers may simply want to scan some of the chapters where core
concepts are reviewed, but there are many chapters that delve into some of the
more powerful and exciting features of FireDAC, including virtual field
management, cloned cursors, and cached updates.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
So, the short story is that the book was a lot of work, and
in the end, worth the effort.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The book begins with an overview of FireDAC, including its
features and benefits. In chapter 2 you learn the many different ways to
connect to your data, whether you are using one of the mainstream databases and
a FireDAC native driver or are migrating from a legacy file-server database.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Chapter 3 explores how you configure FireDAC to control
nearly every aspect of your data retrieval, in-memory management, and subsequent
database writes. Here you learn about FireDAC dataset property inheritance, and
how to fine tune configurations at the individual component level.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Chapters 4 and 5 demonstrate how you communicate with the
underlying database using dataset components, queries, and stored procedures.
Here I describe the capabilities of these components, as well as some of their
basic configuration, including how to create and use parameterized query and
stored procedure calls. I also cover how to use transactions, as well as how to
monitor the database connections from your running applications.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Chapter 6 introduces the fundamentals of Delphi database
development, introducing concepts like the current record, data-bound
navigation and editing, as well as programmatic navigation and editing. Chapter
7 introduces the creation and use of indexes, while chapters 8 and 9 discuss
searches and filtering, many techniques of which employee indexes.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
These four chapters are specifically intended to provide a
core understanding of data-related operations in Delphi. I expect the more
advanced Delphi database developers to quickly scan chapter 6 for anything that
doesn’t look familiar. However, even the advanced developer may glean new and
useful information from a more thorough read of chapters 7 through 9, as
several of the technical reviewers noted (and these guys are definitely
advanced Delphi database developers).&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The remaining chapters of this book are dedicated to more
advanced FireDAC technologies that can enable sophisticated solutions in your
database applications. Chapter 10 introduces virtual fields, and shows you how
to use aggregates, Calculated (and InternalCalc) fields, and Lookup fields. It
also examines the FieldsOptions property, a feature introduced in Delphi XE6.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
In chapter 11 I cover how to persist your FireDAC datasets
and FDSchemaAdapters to files and streams, as well as how to retrieve that
data. There’s a lot of good stuff in that chapter, including how to control
what data is persisted, and how data being loaded can interact with data that
is already loaded.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
In Chapter 12 and 13 I explore the FDMemTable. Here I
discuss the role played by the FDMemTable within the FireDAC landscape, and
then examine many of the techniques that are best suited for FDMemTables.
Topics include the dynamic creation of FDMemTable structure, loading
FDMemTables from other datasets, cloning cursors, and creating nested datasets.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
In Chapter 14 I take an in-depth look at the SQL command
preprocessor. Here you learn how to add tremendous flexibility to your SQL
statements, features that permit you to run a common set of SQL statements
across two or more different database servers. The SQL command preprocessor
also gives you unprecedented control over expressions that you add to your SQL,
introducing dozens of FireDAC scalar functions for your use.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Chapter 15 covers Array DML (Data Manipulation Language), a
high-speed mechanism for executing a large number of similar parameterized
queries, for instance, when you are inserting thousands of records into a given
table with an INSERT SQL statement. When you need to update or insert a large
amount of data quickly, this is your tool.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
In Chapter 16 I examine a feature that I have been a
champion of for years, cached updates. Here you will learn how to create,
manage, and exploit cached updates to create advanced features for your
applications. I also discuss both the decentralized and centralized models of
cached updates, and provide important guidance for the process of applying
updates and handling potential update failures.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
I finish the book with a short chapter on Local SQL,
demonstrating how to configure your FireDAC components to perform SQL queries
on any Delphi dataset or combination of datasets. It’s a powerful technique
that provides for solutions that would previously be difficult or impossible.&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
This has been a challenging while fun and rewarding project
for me, and for those of you who buy my book, thank you! I hope you enjoy it.&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;
&lt;br /&gt;
Still interested? Learn more here: &lt;a href=&quot;http://www.jensendatasystems.com/FireDACbook&quot;&gt;http://www.jensendatasystems.com/FireDACbook&lt;/a&gt;&lt;/div&gt;
</description><link>http://caryjensen.blogspot.com/2017/05/delphi-in-depth-firedac-is-now-available.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>10</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-9041228795754599654</guid><pubDate>Mon, 07 Nov 2016 17:48:00 +0000</pubDate><atom:updated>2016-11-07T10:00:35.530-08:00</atom:updated><title>A Special Year for Delphi Developer Days</title><description>Delphi Developer Days 2016 with Nick Hodges and me, Cary Jensen, is just around the corner (we start in Chicago a week from today). And, the Delphi Developer Days book has been printed, which for an author is that one milestone that is always rewarding. As in years past, this book is once again weighing in at about 400 pages.&lt;br /&gt;
&lt;br /&gt;
This year is very special for another reason. We started planning Delphi Developer Days 2016 back in late May, and this year I have the pleasure of working with my longtime friend and former Delphi Product Manager Nick Hodges.&lt;br /&gt;
&lt;br /&gt;
Nick has been a prolific writer over the past couple of years, publishing not one, but two Delphi books (&lt;i&gt;Coding in Delphi&lt;/i&gt; and &lt;i&gt;More Coding in Delphi&lt;/i&gt;). I was really looking forward to working with him on the Delphi Developer Days book, and I was not let down one bit. This book is loaded with good stuff, and I cannot wait for our chance to present this material.&lt;br /&gt;
&lt;br /&gt;
But that is not the special part I am talking about. My past Delphi Developer Days presenters have all been serious contributors to the Delphi community. Marco Cantù has gone on to become the current Delphi Product Manager. Bob Swart continues to speak at conferences, publish articles, and runs the Delphi Developer Network in the Netherlands (and I look forward to his return to Delphi Developer Days as my co-presenter next year). Ray Konopka continues his great work, and both Konopka Signature Components and Code Site are bundled with various versions of Delphi. And then, in September, we learned that Nick had joined Embarcadero as the Director of Product Management, and will be overseeing Delphi as well as other Embarcadero products.&lt;br /&gt;
&lt;br /&gt;
But even with that great responsibility, Nick is committed to completing this autumn&#39;s Delphi Developer Days tour. And what a special gift for our attendees. Not only are they going to hear one of the really gifted Delphi presenters, but they will be interacting with one of the people Embarcadero has entrusted with shepherding Delphi, and other products, into the future.&lt;br /&gt;
&lt;br /&gt;
There are still some seats available for our Chicago and Baltimore events, and Frankfurt is almost full (Copenhagen has been sold out for over a month now). So, if you want to be a part of one of the coolest Delphi events this year, you have got to act soon. Oh, yeah, and you get your own copy of this year&#39;s Delphi Developer Days 2016 book. (Sorry, this book is available only to Delphi Developer Days attendees.)&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglK-fvUqzpZHGzw_ZtwPQXyQzorS-IedpyFaklEBP00o5qAkFPUdnvVcPnNnWTlcpHHus8KvLGCAHngLiIcjG7wqHpiJDHC22Me_0NMh-TelPG1wCSEOHC78505_Rb2yF9jZk1ma1VEi4/s1600/DDDBook2016.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglK-fvUqzpZHGzw_ZtwPQXyQzorS-IedpyFaklEBP00o5qAkFPUdnvVcPnNnWTlcpHHus8KvLGCAHngLiIcjG7wqHpiJDHC22Me_0NMh-TelPG1wCSEOHC78505_Rb2yF9jZk1ma1VEi4/s320/DDDBook2016.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://caryjensen.blogspot.com/2016/11/delphi-developer-days-2016-with-nick.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglK-fvUqzpZHGzw_ZtwPQXyQzorS-IedpyFaklEBP00o5qAkFPUdnvVcPnNnWTlcpHHus8KvLGCAHngLiIcjG7wqHpiJDHC22Me_0NMh-TelPG1wCSEOHC78505_Rb2yF9jZk1ma1VEi4/s72-c/DDDBook2016.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-4775727137921530283</guid><pubDate>Tue, 11 Oct 2016 19:19:00 +0000</pubDate><atom:updated>2016-10-11T13:08:06.472-07:00</atom:updated><title>When Migrating to FireDAC, You Must Understand UpdateMode</title><description>&lt;div class=&quot;MsoNormal&quot;&gt;
Let&#39;s start with a little history lesson. When Delphi first
shipped it had one data access framework, the Borland Database Engine (BDE).
While the BDE was a breakthrough product in its early years, providing a fast,
independent, and easy-to-use data access layer, it was cumbersome to install,
used a lot of network bandwidth, and had limited support for remote database
servers. Over time, it became increasingly obsolete.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The need for a new data access mechanism for Delphi became
even more apparent during the development of Kylix, a Delphi-based compiler and
IDE (integrated development environment) for Linux. Porting the BDE to Linux
was ruled out, and dbExpress was born. The dbExpress data access framework is
high-speed and client/server friendly, largely based on pass-through SQL
(structured query language). &lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The dbExpress framework has one major drawback, however. In
most cases converting a BDE project to dbExpress required a major refactoring
of the data access logic, and dbExpress did not support the old-style file
server databases, such as Paradox, dBase, or MS Access until Delphi XE2. As a
result, for most many developers dbExpress was a poor option.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
FireDAC changes that. Conversion from the BDE to FireDAC is
pretty smooth, and Delphi even ships with a tool, named reFind, that helps with
much of the conversion process. It is for this reason that I use FireDAC in all
of my new projects (and all of the database projects included in my source code
for &lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;Delphi Developer Days&lt;/a&gt;). In addition, I think that a good argument can be
made for migrating legacy applications to use FireDAC when a major revision is
scheduled. Yes, it is that good.&lt;/div&gt;
&lt;h3&gt;
One Big Difference: UpdateOptions.UpdateMode&lt;/h3&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
One reason why migration to FireDAC from the BDE is so easy
is that FireDAC provides a solid implementation of the TDataSet Interface, and
all of the basic operations available in the BDE can be found in FireDAC.
Better still, FireDAC implements many of the higher-end features previously
only found in ClientDataSets. As a result, if you know the BDE and/or
ClientDataSets, using FireDAC is a no brainer.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
There is one very significant difference between how FireDAC
and the BDE/ClientDataSets work, and this difference is very easy to miss, in
part because it is related to the default value of a single property. And
because the effects of this property have such a profound impact on how your
database applications work, it is important that you know about this difference
when you decide to start using FireDAC. The property is UpdateMode.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
UpdateMode is a property found in the UpdateOptions property
of FireDAC TDataSets. It is also a property of BDE TDataSets as well as the
TDataSetProvider when used to apply updates to a caching ClientDataSet. In all
of these mentioned classes the UpdateMode property performs the same task, it
influences how the corresponding component generates the SQL used to write
changes to the underlying database.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The UpdateMode property is of the type TUpdateMode. The following
is the declaration of the TUpdateMode type:&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;Code&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;TUpdateMode = (upWhereAll, upWhereChanged, upWhereKeyOnly);&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Here is how it works. When UpdateMode is set to upWhereAll,
all non-BLOB fields are included in the WHERE clause of UPDATE and DELETE
queries. This results in update failures if any of the non-BLOB fields of the
underlying record were modified since the time that the table was opened, the
query or stored procedure was executed, or the FDMemTable was loaded. This
approach is known as optimistic locking, and when two or more users are trying
to apply changes at about the same time to the same record, only the first to
apply changes will succeed. All others will fail.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
When UpdateMode is set to upWhereChanged, only the primary
field keys and the fields that have been modified are included in the WHERE
clause of UPDATE queries. (Again, INSERTs are not affected. DELETE queries
continue to use an exact match criteria since there are no changed fields in a
deleted record.) As long as none of the primary key fields of an updated record
are affected, and all non-primary key fields that have been modified have also
not been updated in the underlying table since the time the data was loaded
into the DataSet, these queries should succeed.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Using upWhereChanged permits two or more users to apply
their changes to the underlying database so long as none of them have made
changes to common fields. For example, if one user changed a field called
Address, and another changed a field called PhoneNumber, and neither of these
fields are part of the primary key, both users will successfully apply their
changes. This type of update permits merges.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The final UpdateMode value is upWhereKeyOnly. With
UpdateMode set to upWhereKeyOnly, the WHERE clause of UPDATE queries only includes
the values of the primary key fields. (INSERT and DELETE queries continue to
act as they do with upWhereChanged.) Using this mode, so long as the key fields
of the underlying record have not been changed, the updates are applied,
replacing any updates that other users may have applied.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Assuming that key fields are not touched (this is a pretty
safe assumption in most database architectures), the use of upWhereKeyOnly
permits everyone to succeed in posting their changes. As a result, the last
user to post is the user whose data appears in the underlying database.&lt;/div&gt;
&lt;h3&gt;
The Difference and Why It Is Important&lt;/h3&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The default value of FireDAC&#39;s UpdateOptions.UpdateMode is
upWhereKeyOnly, and this is a really big deal. It means that if you use FireDAC
datasets without changing this default value, there is a good chance that some
users may report that their changes have &lt;i&gt;disappeared&lt;/i&gt;. Or, even worse,
never know that their edits have been overwritten.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Here is how this can happen. If two or more users read the
same record (by way of a query, stored procedure call, or by opening an
FDTable), and two or more post a change to that record, the last user to post
their record will replace those changes posted before them. What&#39;s problematic
about this is that the users who posted before the last user will have no idea
that their changes have been overwritten.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
By comparison, most developers prefer to use either pessimistic locking
(the first user to start editing the record prevents any other user from
editing the record until changes have been posted), or optimistic locking (once
the first user posts a change to a record, subsequent attempts to post to that
same record will fail, since the original record no longer can be found, based
on the WHERE clause predicates). In these scenarios, the first user to post
wins, and other users must first re-read the record, after which they can
decide whether or not to update the newly posted contents.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
FireDAC defaults to an UpdateMode of upWhereKeyOnly, since
the queries required to update the database tend to execute faster. It is up to
you, however, to decide whether or not the performance improvement is more
important that the possible loss of data. &lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
The DataSetProvider class, the class which ClientDataSets
use to resolve changes back to the underlying database, and BDE DataSets
(TTable, TQuery, and TStoredProc) also have an UpdateMode property. For these
objects, the default value of UpdateMode is upWhereAll, the conservative
setting that prevents a user from overwriting another user&#39;s edits. &lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
So, the bottom line is this. You need to understand how
FireDAC&#39;s UpdateOptions.UpdateMode affects how records are updated in the
underlying database, and set this property to the value that meets the needs of
your application.&lt;/div&gt;
&lt;h3&gt;
An Easy Solution, If You Want to Change UpdateMode&lt;/h3&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Fortunately, another feature of FireDAC makes it easy to
change the default value of UpdateOptions.UpdateMode property. The
UpdateOptions property, like a number of other properties in FireDAC, is found
in a number of classes in the FireDAC framework, including FDManager,
FDConnection, FDQuery, FDMemTable, and so on. &lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
These classes are related in a hierarchical sense, in that
the settings found in the UpdateOptions property of the FDManager (a singleton
object) are inherited by all FDConnections configured to use the FDManager.
Similarly, any FireDAC dataset, such as an FDQuery or FDMemTable, will employ
the settings found in the FDConnection to which they are connected. &lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
So, if your application is using one FDConnection, changing
the UpdateOptions.UpdateMode property of that FDConnection will automatically
apply that setting to any FDTable, FDQuery, FDStoredProc using that connection
(so long as you have not already touched the UpdateOptions.UpdateMode property
on any of these TDataSets). If you are using more than one FDConnection, add an
FDManager and change the value of the UpdateOptions.UpdateMode property there,
and that change will likewise cascade down to any FDConnections, and then on
down to the individual TDataSets, again, so long as that property has not also
been overridden in any of the individual FDConnections or TDataSets.&lt;br /&gt;
&lt;br /&gt;
Note that if your FDQuery, FDStoredProc, or FDTable is already connected to an FDConnection, and that FDConnection currently uses upWhereKeyOnly, changing the FDConnection UpdateOptions.UpdateMode property alone might not change the FireDAC DataSet. You might have to disconnected, and then re-connect the DataSet to the FDConnection before the DataSet&#39;s UpdateMode property updates.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: 12pt;&quot;&gt;Copyright © 2016 Cary Jensen. All Right Reserved&lt;/span&gt;&lt;/div&gt;
</description><link>http://caryjensen.blogspot.com/2016/10/when-migrating-to-firedac-you-must.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-2664500974183099379</guid><pubDate>Tue, 12 Jul 2016 14:22:00 +0000</pubDate><atom:updated>2016-07-12T07:22:18.060-07:00</atom:updated><title>Delphi Developer Days 2016 with Nick Hodges and Cary Jensen Agenda Published</title><description>&lt;div class=&quot;MsoNormal&quot;&gt;
The agenda and course topics for this year&#39;s Delphi
Developer Days with Nick Hodges and me, Cary Jensen, has been released, and we
think that you will be pleased with the selection of topics. Over the course of
this two-day event we will have a combination of talks, some of which are
jointly presented by Nick and me, as well as talks where we break out into
separate rooms to cover a variety of topics.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
For our joint sessions we are covering threading and thread
synchronization, the parallel programming library, code de-coupling, dependency
injection, and a debugging deep dive. We are also going to discuss best
practices in professional development, a thought-provoking look at the
principles and philosophies crucial to success in the art of software
development. And finally, no Delphi Developer Days tour would be complete
without the Tip, Tricks, and Techniques session, were Nick and I share some of
our favorite tricks-of-the-trade.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
I
am really excited about presenting these joint sessions with Nick. Over the
past couple of years Nick and I have co-presented talks at several Delphi
conferences, and each time it was not only fun for us, but also provided our
audiences with a deeper understanding of the subject matter. Nick and I are
passionate about the topics we picked for our joint sessions, and the
opportunity to present them jointly gives us the chance to really explore the
issues, and provide a contrast of opinions and solutions.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Topics for our separate talks including unit testing,
FireDAC, advanced Delphi language features, patterns in Delphi, building
Windows services, and using JSON (JavaScript Object Notation). As in the past,
these joint sessions are concurrent, meaning that you&#39;ll have to choose between
two simultaneous topics. But you&#39;ll miss nothing, as Nick and I are publishing
the material for each session in the Delphi Developer Days course book. This
course book, which in the past has been well over three hundred pages long, is
only available to attendees of Delphi Developer Days.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
Along the way we&#39;ll also have a keynote address from
Embarcadero, question and answer sessions, and the opportunity to network with
fellow Delphi developers. For a detailed agenda and descriptions of each of the
topics, please visit &lt;a href=&quot;http://www.delphideveloperdays.com/descriptions.html&quot; target=&quot;_blank&quot;&gt;http://www.DelphiDeveloperDays.com/descriptions.html&lt;/a&gt;.&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
We are very fortunate to have Nick join us for Delphi
Developer Days this year. Over the past several years Nick has published two
books on Delphi, &lt;i&gt;Coding in Delphi&lt;/i&gt; and &lt;i&gt;More Coding in Delphi&lt;/i&gt;. He
is getting ready to publish his next book, &lt;i&gt;Dependency Injection in Delphi&lt;/i&gt;,
and you don&#39;t want to miss this chance to hear one of the leading Delphi
experts share his views and insights. I hope to see you at Delphi Developer
Days 2016 in Chicago, Copenhagen, Frankfurt, or Baltimore. &lt;/div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-size: 12pt;&quot;&gt;Register by August 12, 2016 and save 25% off of the
regular price. For more information, and to register, visit
&lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;http://www.DelphiDeveloperDays.com&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;</description><link>http://caryjensen.blogspot.com/2016/07/delphi-developer-days-2016-with-nick.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-3799973229356987997</guid><pubDate>Tue, 07 Jun 2016 08:01:00 +0000</pubDate><atom:updated>2016-06-07T01:07:47.082-07:00</atom:updated><title>Delphi Developer Days 2016 with Nick Hodges and Cary Jensen</title><description>It is my great pleasure to announce that Nick Hodges will be joining me for this year&#39;s Delphi Developer Days tour, which will visit the United States, Europe, and Scandinavia late this autumn. Delphi Developer Days are intense, two-day training events focusing on Delphi, the cross-platform, rapid application development platform from &lt;a href=&quot;https://www.embarcadero.com/&quot; target=&quot;_blank&quot;&gt;Embarcadero Technologies&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The tour will begin in Chicago on November 14th and 15th, and will continue in Copenhagen, Denmark on November 24th and 25th. We will be in Frankfurt, Germany on November 28th and 29th, and will conclude the tour in the Baltimore/Washington DC area on December 5th and 6th.&lt;br /&gt;
&lt;br /&gt;
Delphi Developer Days consists of both joint talks, where Nick and I present a topic together, as well as individual sessions where we focus on various aspects of Delphi development. As we have done in the past, each attendee will receive a printed book containing the material from all of our talks. In the past these books have been in excess of 350 pages long, and this year looks to be no different.&lt;br /&gt;
&lt;br /&gt;
I am especially proud to have Nick Hodges presenting with me this year. Nick is one of the original members of the Delphi community, and the author of arguably the first custom Delphi component (TSmiley). He is the recipient of the coveted Spirit of Delphi award, one of Embarcadero&#39;s Delphi MVPs, and a regular presenter at Delphi conferences and web casts. Nick previously served as the Delphi Product Manager, and has recently published two celebrated books on Delphi (&lt;a href=&quot;http://codingindelphi.com/&quot; target=&quot;_blank&quot;&gt;Coding in Delphi&lt;/a&gt;, and &lt;a href=&quot;http://morecodingindelphi.com/&quot; target=&quot;_blank&quot;&gt;More Coding in Delphi&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
Nick is both an excellent presenter and writer, two talents that are essential for Delphi Developer Days. He is the perfect addition to the list of co-presenters that I&#39;ve had the honor to work with over the years. My Delphi Developer Days co-presenters in previous years were Marco Cantú (currently the RAD Studio Product Manager), Bob (Dr.Bob) Swart, and Ray Konopka (Raize Software). Bob is still involved with Delphi Developer Days, but is unable to commit to travel this fall. I look forward to his return to Delphi Developer Days in 2017, but in the meantime, I am delighted to have Nick stepping in as a first-rate replacement.&lt;br /&gt;
&lt;br /&gt;
Nick and I are currently working on our agenda, and we will announce our topics in the next couple of weeks. Registration is now open at &lt;a href=&quot;http://www.delphideveloperdays.com/&quot;&gt;www.DelphiDeveloperDays.com&lt;/a&gt;, and if you register in the next several weeks (prior to August 12, 2016), you will receive a 25% discount on the registration fee. We&#39;ve sold out many of our events in the past, and with Nick on board for this tour, I anticipate that seats will go fast.&lt;br /&gt;
&lt;br /&gt;
Just a final note. Normally Delphi Developer Days tours occur in the spring. We had to postpone our spring tour this year due to the unexpected loss of a close family member. Thank you to all who supported us during this difficult time, and thank you also for your patience. We are very happy that we are able to provide a 2016 tour, and with the addition of Nick, it&#39;s guaranteed to be one of the best &lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;Delphi Developer Days&lt;/a&gt; tours yet.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://caryjensen.blogspot.com/2016/06/delphi-developer-days-2016-with-nick.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-7878620672686299808</guid><pubDate>Mon, 25 Jan 2016 07:30:00 +0000</pubDate><atom:updated>2016-01-24T23:30:34.772-08:00</atom:updated><title>Delphi Developer Days Postponed</title><description>The annual spring Delphi seminar known as Delphi Developer Days has been postponed due to circumstances beyond our control.&lt;br /&gt;
&lt;br /&gt;
Loy Anderson (the DDD event manager), Bob (Dr.Bob) Swart, and I have been working to put together this year&#39;s Delphi Developer Days, and we were getting close to announcing our dates when Loy and I suffered the tragic and sudden loss of a close family member. The circumstances of this event are going to require that Loy and I spend a significant amount of time helping out our family. Unfortunately, it is not possible to provide this help and at the same time invest the time required to make Delphi Developer Days a success.&lt;br /&gt;
&lt;br /&gt;
We will make an announcement once we have re-scheduled the Delphi Developer Days dates. If you would like to be informed once new dates have been chosen, you can visit www.DelphiDeveloperDays.com and click the link labeled Notify Me. I will also blog and tweet once we know when the next DDD event will be offered, as well as post this information to the official Delphi Developer Days site and the Delphi Developer Days Facebook page (https://www.facebook.com/delphideveloperdays).&lt;br /&gt;
&lt;br /&gt;
Thank you for your understanding, and we look forward to seeing you at the next Delphi Developer Days...&lt;br /&gt;
&lt;br /&gt;
Cary</description><link>http://caryjensen.blogspot.com/2016/01/delphi-developer-days-postponed.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-3581250832517254081</guid><pubDate>Fri, 13 Feb 2015 12:49:00 +0000</pubDate><atom:updated>2015-02-15T09:03:59.961-08:00</atom:updated><title>Using Trim in ClientDataSet Filters</title><description>I announced in my &lt;a href=&quot;http://caryjensen.blogspot.com/2015/01/now-available-delphi-in-depth.html&quot; target=&quot;_blank&quot;&gt;last blog post&lt;/a&gt; that an updated version of Delphi in Depth: ClientDataSets is now available, both in printed and in eBook formats. In response, a reader posted this question as a comment:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;span style=&quot;font-family: Times, Times New Roman, serif;&quot;&gt;I used TClientDataSet.Filter. CDS&#39;s Filter support &quot;Trim&quot; statement in Delphi help doc. It support &quot;Trim(Name, &#39;.&#39;)&quot;. But, how to used the statement?&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Here is the answer. Imagine that your ClientDataSet includes a Company field, and that you have set the ClientDataSet&#39;s Filtered property to True, and have entered a Trim statement in the Filter property.&lt;br /&gt;
&lt;br /&gt;
When you call Trim you can pass either one or two parameters. If you pass one parameter, you pass the name of a field. In response, Trim will remove any leading and trailing white spaces (please see the first comment below). For example, the filter Trim(Company) = &#39;Unisco&#39; will trim white space, and the filtered data will include records whose Company field includes &#39;Unisco &#39;, &#39; &amp;nbsp; &amp;nbsp;Unisco&#39;, &#39; &amp;nbsp;Unisco &amp;nbsp;&#39;, and &#39;Unisco&#39;.&lt;br /&gt;
&lt;br /&gt;
If you include the second, optional parameter, Trim will return the value of that field after removing that leading and/or trailing character. As a result, Trim(Company, &#39;o&#39;) = &#39;Unisc&#39; will match on &#39;Unisco&#39;, &#39;oUnisc&#39;, and &#39;oUnisco. Likewise, Trim(Company, &#39;.&#39;) = &#39;Unisco&#39; will match on &#39;Unisco&#39;, &#39;.Unisco&#39;, &#39;Unisco....&#39;, and &#39;...Unisco.&#39;.&lt;br /&gt;
&lt;br /&gt;
There are two variations on Trim. These are TrimLeft and TrimRight. Like Trim, these functions can also take one or two parameters. If you call TrimLeft or TrimRight with only one parameter, those functions will remove white space from the beginning or the ending of the specified field, respectively. If you pass a second parameter, TrimLeft or TrimRight will remove that character from the beginning or ending of the specified field, respectively.&lt;br /&gt;
&lt;br /&gt;
For example, TrimLeft(Company, &#39;U&#39;) = &#39;nisco&#39; will match on a record whose Company field contains &#39;Unisco&#39; and &#39;nisco&#39;. Likewise, TrimRight(Company, &#39;o&#39;) = &#39;Unisc&#39; will match on a record whose company field contains &#39;Unisc&#39;, &#39;Unisco&#39;, and even &#39;Uniscooo&#39;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://caryjensen.blogspot.com/2015/02/using-trim-in-clientdataset-filters.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-5962787607709839751</guid><pubDate>Mon, 12 Jan 2015 10:46:00 +0000</pubDate><atom:updated>2015-01-12T02:48:40.857-08:00</atom:updated><title>Now Available: Delphi in Depth: ClientDataSets 2nd Edition</title><description>I published the original Delphi in Depth: ClientDataSets book back in March of 2011. At the time I believe it was my 24th book on computer software, though I must admit that I&#39;ve lost count. Nonetheless, I greatly appreciated the many kind comments I&#39;ve received from readers since its publication, even though it is a Delphi book &quot;about one component.&quot;&lt;br /&gt;
&lt;br /&gt;
I decided to update the code samples following the release of Delphi XE7. My original code samples made use of the Borland Database Engine and the sample Paradox tables that shipped with Delphi, which permitted those code samples to be compiled and run without any additional configuration, something that I felt was important.&lt;br /&gt;
&lt;br /&gt;
Things changed with the release of Delphi XE7. The BDE is no longer installed by default. In addition, Delphi Professional (and higher) now ships with an alternative database solution that can be used without any additional configuration. This solution, which makes use of FireDAC and InterBase, did not exist when the first edition of this book was published.&lt;br /&gt;
&lt;br /&gt;
Once I started updating the code samples to use FireDAC and InterBase, I realized that there were also a few additions that I could make to the original book. For example, the new FieldOptions property introduced to TDataSet in Delphi XE6 gave developers additional flexibility in their use of persistent fields, such as calculated and internal calc fields. A nod to LiveBindings would also be warranted.&lt;br /&gt;
&lt;br /&gt;
It didn&#39;t take long before I concluded that it was time to give the book a good once over, tweaking the odd description here and there, adding material where appropriate, and correcting a few missed typos. And, of course, using the new FireDAC/InterBase examples in the book&#39;s code listings. I also updated all of the figures in the book to show the latest version of Delphi at the time of my writing (XE7). The original BDE/Paradox examples are still available for download, which is necessary in order to support older versions of Delphi, those prior to XE5. XE5 was the first version of FireDAC to use the new FD prefix in component names, as well as the new FireDAC unit names.&lt;br /&gt;
&lt;br /&gt;
Permit me now to anticipate a question that is sure to come up. &quot;What if I bought the original edition of Delphi in Depth: ClientDataSets? Should I buy the 2nd edition?&quot; Well, you probably don&#39;t need to buy the 2nd edition unless you want to have the most current version on your bookshelf. In updating the 2nd edition I re-read, for the purpose of correcting and editing, every page of the original manuscript many times. And, for the most part, I was very happy with what I had written. As a result, there are large segments from the original text that are unchanged, or have inconsequential changes in the wording. Yes, I did add sections on FieldOptions, LiveBindings, and special filter operations. There are also a few additional examples and extended discussions.&lt;br /&gt;
&lt;br /&gt;
I should also note that you can use the new FireDAC/InterBase samples with the original book. Visit the book&#39;s download site, listed in Appendix A of the original publication. There you will find the FireDAC/InterBase code sample download, along side the BDE/Paradox code download. Again, these FireDAC examples only work with Delphi XE5 and later, so the BDE-based examples are still available for use with earlier versions of Delphi.&lt;br /&gt;
&lt;br /&gt;
I should also note that I removed three chapters that appeared at the end of the original book from the 2nd edition. Those chapters covered DataSnap, with a mix of COM-based DataSnap and the newer DataSnap introduced in Delphi 2009. While ClientDataSets played a central role in the COM-based DataSnap (the obsolete version), they are one of many options in the new DataSnap. In the end, I concluded that the DataSnap chapters were out of place.&lt;br /&gt;
&lt;br /&gt;
I am releasing two versions of Delphi in Depth: ClientDataSets 2nd Edition. The printed version is available on CreateSpace and Amazon. And, in response to popular request, I am releasing a PDF version on FastSpring. You can find links to these releases from the book&#39;s web site at &lt;a href=&quot;http://www.jensendatasystems.com/cdsbook2/&quot; target=&quot;_blank&quot;&gt;http://www.JensenDataSystems/cdsbook2&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I am very happy with how Delphi in Depth: ClientDataSets 2nd Edition turned out. I hope that you are too.&lt;br /&gt;
&lt;br /&gt;
Publication Date: Jan 07 2015&lt;br /&gt;
ISBN/EAN13: 150584018X / 9781505840186&lt;br /&gt;
Page Count: 358 pages, 7.44&quot; x 9.69&quot;&lt;br /&gt;
&lt;br /&gt;
Web Site: &lt;a href=&quot;http://www.jensendatasystems.com/cdsbook2/&quot; target=&quot;_blank&quot;&gt;http://www.JensenDataSystems/cdsbook2&lt;/a&gt;</description><link>http://caryjensen.blogspot.com/2015/01/now-available-delphi-in-depth.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>15</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-2351794435048636552</guid><pubDate>Tue, 06 Jan 2015 14:48:00 +0000</pubDate><atom:updated>2015-01-06T06:55:22.069-08:00</atom:updated><title>Delphi Developer Days 2015 Agenda Announced</title><description>&lt;div&gt;
Ray Konopka and I worked over the holidays to prepare the &lt;a href=&quot;http://www.delphideveloperdays.com/descriptions.html&quot; target=&quot;_blank&quot;&gt;agenda&lt;/a&gt; for &lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;Delphi Developer Days 2015&lt;/a&gt;,&amp;nbsp;and I am very happy with the content we have planned for this year&#39;s tour.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
As usual, we have created a balanced program that offers something for every Delphi developer. We have sessions covering the VCL (Visual Component Library) as well as sessions on mobile/FireMonkey development. Some sessions cover some of Delphi&#39;s newest features, while others apply to nearly every version of Delphi. In the database realm, we have client/server sessions as well as sessions covering distributed (DataSnap and REST) topics. We even have sessions covering some of the third party tools that ships with Delphi, including &lt;a href=&quot;http://www.raize.com/DevTools/CodeSite/Default.asp&quot; target=&quot;_blank&quot;&gt;CodeSite&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href=&quot;http://www.fast-report.com/en/product/fast-report-vcl-5/&quot; target=&quot;_blank&quot;&gt;Fast Report&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Ray Konopka is the world&#39;s leading expert on Delphi component creation, and is also an expert on user interface design, and we&#39;ve ensured that these topics are represented in the agenda. Best of all, all of the topics that I&#39;ve mentioned will be covered in the Delphi Developer Days book that all attendees receive. Ray and I are now turning our attention to writing that book, and it is a creative process to which I am looking forward.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Delphi Developer Days 2015 is visiting four cities in the United States, Europe, and Scandinavia between 13 April and 11 May. And, we are currently in our very early registration period, and you will save even more if you register and make payment by 23 January, 2015.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
For complete information on Delphi Developer Days 2015 locations, the agenda, session descriptions, and discounts, please visit &lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;http://www.DelphiDeveloperDays.com&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Space is limited. Register today to save your seat.&lt;/div&gt;
</description><link>http://caryjensen.blogspot.com/2015/01/delphi-developer-days-2015-agenda.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-7031358471973291404</guid><pubDate>Thu, 18 Dec 2014 13:48:00 +0000</pubDate><atom:updated>2014-12-29T12:46:32.102-08:00</atom:updated><title>Delphi Developer Days 2015 with Ray Konopka and Cary Jensen</title><description>In case you missed the official press release on Tuesday, let me be the first to share with you that Ray Konopka is going to join me in presenting this year&#39;s Delphi Developer Days 2015 tour. We will be visiting four cities in the United States, Europe, and Scandinavia this spring, and it is promising to be one of the best Delphi Developer Days tours so far.&lt;br /&gt;
&lt;br /&gt;
Before I go any further, I want to assure you that my co-presenter for the past two years, Bob (Dr.Bob) Swart is still part of Delphi Developer Days. Bob is taking a sabbatical from traveling in the first part of 2015, and his humor and profound knowledge of Delphi will be sorely missed. But he will be back next year, and I am certain that he will have a wealth of new information to share at that time.&lt;br /&gt;
&lt;br /&gt;
In the meantime, I have the supreme pleasure to have another of the world&#39;s great Delphi gurus joining me for this annual seminar tour. Ray Konopka is an Embarcadero MVP, winner of the coveted Spirit of Delphi award, and owner and founder of &lt;a href=&quot;http://www.raize.com/Home.asp&quot; target=&quot;_blank&quot;&gt;Raize Software&lt;/a&gt;, one of the first providers of third-party Delphi components. Another of his products, CodeSite Express, ships with Delphi.&lt;br /&gt;
&lt;br /&gt;
I first met Ray when we served together on the annual Borland International Conference advisory board. That was more than 20 years ago. And I have to say that he is one of the hardest working and most focused people I&#39;ve ever met. More importantly, he is an articulate speaker with a gift for communication. Whatever the topic, he understands the essential points, and presents them with clarity. You can&#39;t ask for more from a presenter.&lt;br /&gt;
&lt;br /&gt;
But there&#39;s more, and it&#39;s particularly important when it comes to Delphi Developer Days. As everyone who has attended in the past knows, one of the hallmarks of Delphi Developer Days is the book that every attendee receives. Packed with hundreds of packages of material, it ensures that you take home more than an experience — you take home information.&lt;br /&gt;
&lt;br /&gt;
This is why Delphi Developer Days presenters also have to be skilled writers. My first Delphi Developer Days co-presenter, Marco Cantù, is an excellent example of this. Marco has published more books on Delphi than anyone else, and I don&#39;t know anyone working with Delphi who doesn&#39;t own several of them. Bob, likewise, has published a number of books, countless tutorials, and many magazine articles. Who hasn&#39;t found the answer to some impenetrable problem from Bob&#39;s posts? I know I have.&lt;br /&gt;
&lt;br /&gt;
Ray, likewise, is an author. He wrote the Blazing Pascal column for PC Techniques, and the column Delphi by Design for Visual Developer Magazine. Furthermore, his book, Developing Custom Delphi Components was groundbreaking (as was the follow-up, Developing Customer Delphi 3 Components), and it deserves a place on every Delphi developer&#39;s shelf.&lt;br /&gt;
&lt;br /&gt;
Ray and I are still working on the agenda for this year&#39;s topics, but I can assure you that there will be lots of great information. I will blog and tweet again once we&#39;ve posted the topics. In the meantime, you can read the press release at &lt;a href=&quot;http://www.delphideveloperdays.com/press_release.html&quot; target=&quot;_blank&quot;&gt;http://www.DelphiDeveloperDays.com/press_release.html&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
For more information, visit &lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;http://www.DelphiDeveloperDays.com&lt;/a&gt;. And, I&#39;d be remiss if I didn&#39;t mention that we&#39;re currently in the very early registration period, and you can save 25% if you sign up soon.&lt;br /&gt;
&lt;br /&gt;
Let me finish by now returning to my main point. This year&#39;s Delphi Developer Days tour will be one to remember. Ray and I are looking forward to it, and I hope you are, too.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://caryjensen.blogspot.com/2014/12/delphi-developer-days-2015-with-ray.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-2066872262258376694</guid><pubDate>Thu, 19 Jun 2014 15:33:00 +0000</pubDate><atom:updated>2024-09-16T15:41:00.513-07:00</atom:updated><title>Ode to Code</title><description>Ode to Code:&lt;br /&gt;
Reflections on Software Development in Iambic Heptameter&lt;br /&gt;
by Cary Jensen&lt;br /&gt;
&lt;br /&gt;
While true, it&#39;s said, there&#39;s work to do, and now it&#39;s time to start&lt;br /&gt;
This is my task, so plain and clear. It&#39;s science, love, and art&lt;br /&gt;
&lt;br /&gt;
My slate starts clean, a screen pure white, no logic bears my will&lt;br /&gt;
Upon this page, through thought and might, it&#39;s my intent to fill&lt;br /&gt;
&lt;br /&gt;
I make my plan, each step designed, my spec is well thought out&lt;br /&gt;
It matters much, oh yes it does, there can&#39;t be any doubt&lt;br /&gt;
&lt;br /&gt;
My fingers fly, the logic pours, a waterfall sublime&lt;br /&gt;
I see my goal, I type and click, I lose all sense of time &lt;br /&gt;
&lt;br /&gt;
My words are key, my syntax right, and subtly reserved&lt;br /&gt;
I own this world. I&#39;m in control, though humble, numb, and nerved&lt;br /&gt;
&lt;br /&gt;
It&#39;s getting close, the tension firms, anticipation&#39;s high&lt;br /&gt;
I hit F9, compile and run, I feel success is nigh&lt;br /&gt;
&lt;br /&gt;
But wait! It fails! How can this be, catastrophe I feel&lt;br /&gt;
I&#39;ve lost my touch, my senses fail, my mortal soul revealed&lt;br /&gt;
&lt;br /&gt;
Oh, damn the Gods! This logic broke, a bug I cannot find&lt;br /&gt;
I check the source. I check each line. I think I&#39;ll lose my mind&lt;br /&gt;
&lt;br /&gt;
But what is this, a misplaced test, can this thing truly be&lt;br /&gt;
Compile again, and it just works, I&#39;m now in ecstasy&lt;br /&gt;
&lt;br /&gt;
I document the change I made, my comment explains why&lt;br /&gt;
I always try to take this step, to prevent a future cry&lt;br /&gt;
&lt;br /&gt;
Relaxed, I am, my goal achieved, a conquest satisfied&lt;br /&gt;
It&#39;s what I do, a job compelled, a source of joy and pride&lt;br /&gt;
&lt;br /&gt;
You beauty mine, my cherished child, the product of my soul&lt;br /&gt;
From white blank slate to final code, a void has morphed to whole&lt;br /&gt;
&lt;br /&gt;
No eye will see this gold I&#39;ve spun, no heart with feel its beat&lt;br /&gt;
It lies beneath the interface, resplendent and complete&lt;br /&gt;
&lt;br /&gt;
I scratch one item off my list, but I cannot pretend&lt;br /&gt;
With this task done, there will be more, my work will never end;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: 12pt;&quot;&gt;Copyright © 2014 Cary Jensen. All Rights
Reserved&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;</description><link>http://caryjensen.blogspot.com/2014/06/ode-to-code.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-4281204146071961639</guid><pubDate>Tue, 13 May 2014 15:36:00 +0000</pubDate><atom:updated>2014-05-13T08:41:33.534-07:00</atom:updated><title>Simplifying LiveBindings Configuration in Mobile Apps Using Frames</title><description>Unless you have been sleeping under a rock, you already know that Delphi can create native executables for both iOS and Android mobile devices. These applications must be created using FireMonkey, since FireMonkey is Delphi&#39;s cross-platform component library. When using FireMonkey, most developers make use of LiveBindings and the LiveBindings Designer to enable data awareness in the visual controls.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, the evolving best practices for mobile application design in Delphi has relied on applications based on a single form, where a TabControl containing two or more TabItems defines the various screens (pages) of the application.&lt;br /&gt;
&lt;br /&gt;
This design avoids some of the issues associated with having multiple forms in a mobile application. For example, Android applications do not support the concept of non-modal forms, and although iOS does, the active form always occupies the entire screen. &lt;br /&gt;
&lt;br /&gt;
Another issue related to having more than one form in a modal application is related to mobile device orientation. Specifically, many applications will re-orient themselves when a user rotates their device 90 degrees, switching from a portrait view to a landscape view and back. The problem here is that the OnResize event is received only by the form with focus. No other forms in memory receive this event, and therefore may not be aware that orientation has changed.&lt;br /&gt;
&lt;br /&gt;
If a mobile application needs two or more pages (or views or forms or whatever you want to call them), this can be achieved by including a single form on which a TabControl appears. You then create one TabItem for each page of the application, and provide user interface elements such as menus, tabs, or buttons to navigate between the available TabItems. In fact, this is the model used by all of Delphi&#39;s multi-page wizards in the Object Repository, which you can select from when you select File | New | FireMonkey Mobile Application from Delphi&#39;s main menu.&lt;br /&gt;
&lt;br /&gt;
While the TabControl/TabItem configuration works, it introduces an unwanted side effect. Specifically, if you use the LiveBindings Designer to visually bind your controls to BindSourceDB components, every control appears on the default layer, and the designer quickly becomes cluttered, making it difficult to create and manage your LiveBindings. And even though the LiveBindings Designer permits you to define layers on which to display select controls, the clutter remains a challenging issue. And, the clutter increases in direct proportion with the overall number of controls on your one form. This can be seen in the following view of the LiveBindings Designer for a somewhat simple two TabItem TabControl.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ7sKBS1zlGv6aAUdSxrw917joPaK-1VSDxx1qW3LgmPmbsNqbQtP_FAvLs-J4-my8cmfBEY4SM1lQbdPnddOvGR41kyAs1Z3gdVYaReHxH-2UC0-5z8Jbeol7un2CUZx9PfGQ15jNKzI/s1600/Figure1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ7sKBS1zlGv6aAUdSxrw917joPaK-1VSDxx1qW3LgmPmbsNqbQtP_FAvLs-J4-my8cmfBEY4SM1lQbdPnddOvGR41kyAs1Z3gdVYaReHxH-2UC0-5z8Jbeol7un2CUZx9PfGQ15jNKzI/s1600/Figure1.jpg&quot; height=&quot;180&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&amp;nbsp;&lt;/div&gt;
Unfortunately, a two-page mobile application is uncommon. Most mobile applications will have many more pages (TabItems), and the problem of clutter in the LiveBindings Designer can get completely out of hand.&lt;br /&gt;
&lt;br /&gt;
There is another solution, however, and it can be found in FireMonkey frames, which were added to FireMonkey in Delphi XE3 (the VCL introduced frames in Delphi 5, and I have found them to be invaluable in my Windows applications).&lt;br /&gt;
&lt;br /&gt;
Here&#39;s the deal. A frame is a design surface, and each design surface in Delphi has its own LiveBindings Designer. As a result, only those controls that appear on the frame automatically appear when you view the frame&#39;s LiveBindings Designer.&lt;br /&gt;
&lt;br /&gt;
Here is what you can do. In the simplest case, you create one frame for each TabItem that you will include in your single form application. You then place each frame into its corresponding TabItem, and then align the frame to alClient. If you want to get really clever, you might even place two or more frames into a single TabItem, but that is a design issue. &lt;br /&gt;
&lt;br /&gt;
For each frame, you include in its uses clause only those data modules whose TDataSets you want to bind using LiveBindings. The result is that each LiveBindings Designer includes only a subset of controls that appear in the single form. This can be seen in the following view, which shows a frame that replaces the controls that appear on the first TabItem of the form whose LiveBinding Designer was shown earlier in this post.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMWf2x_cz2GTNt76i63bAQu6KMKrv1ka9dbxjD8CmT3_M3wJHSo8IA1ra94RB0-7YEYbzLgRM04en5jb-yNWUu5Cu_uz-wAsjiSceqN6ADFbmLdujL6TXpiAh1qGjN7tL8VF0wIA-nAeY/s1600/Figure2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMWf2x_cz2GTNt76i63bAQu6KMKrv1ka9dbxjD8CmT3_M3wJHSo8IA1ra94RB0-7YEYbzLgRM04en5jb-yNWUu5Cu_uz-wAsjiSceqN6ADFbmLdujL6TXpiAh1qGjN7tL8VF0wIA-nAeY/s1600/Figure2.jpg&quot; height=&quot;180&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&amp;nbsp;&lt;/div&gt;
The problem is not entirely solved. Specifically, the one form of your application on which the TabControl appears will display all of the objects from all of the frames placed on the individual TabItems within the LiveBindings Designer when the form itself is selected in the designer, so the clutter still exists. But you will not really care. As long as you can configure LiveBindings at the Frame level, you will use the LiveBindings Designer only with individual frames, in which case only the components on the selected frame will be visible. Furthermore, the benefits of this frame-by-frame configuration will increase in direct proportion to the number of TabItems on your form.&lt;br /&gt;
&lt;br /&gt;
This is just one of the tips, along with many other fun and useful Delphi techniques, that I will be covering along with Bob Swart&amp;nbsp;(Dr.Bob)&amp;nbsp;at this years Delphi Developer Days 2014 tour. We have completed our first two cities in the United States, and the response was excellent. We now continue on to&amp;nbsp;Frankfurt, Germany on May 26th and 27, Amsterdam, The Netherlands on June 12th and 13th, and London, Great Britain on June 18th and 19th. For&amp;nbsp;more information and to register, please visit &lt;a href=&quot;http://wwwdelphideveloperdays.com/&quot;&gt;http://wwwDelphiDeveloperDays.com&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Copyright (2014) Cary Jensen. All Rights Reserved</description><link>http://caryjensen.blogspot.com/2014/05/simplifying-livebindings-configuration.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ7sKBS1zlGv6aAUdSxrw917joPaK-1VSDxx1qW3LgmPmbsNqbQtP_FAvLs-J4-my8cmfBEY4SM1lQbdPnddOvGR41kyAs1Z3gdVYaReHxH-2UC0-5z8Jbeol7un2CUZx9PfGQ15jNKzI/s72-c/Figure1.jpg" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-8363611044565260569</guid><pubDate>Tue, 11 Feb 2014 08:09:00 +0000</pubDate><atom:updated>2014-02-13T08:37:32.495-08:00</atom:updated><title>Delphi Developer Days 2014</title><description>It is again my pleasure to announce the dates and cities for our annual &lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;Delphi Developer Days&lt;/a&gt; tour by me and Delphi expert Bob (Dr.Bob) Swart. We will be visiting two cities in the United States and three in Europe/United Kingdom. We will be in the Washington DC/Baltimore area on May 5th and 6th and Chicago on May 8th and 9th.&lt;br /&gt;
&lt;br /&gt;
We continue in Frankfurt, Germany on May 26th and 27th, continuing to Amsterdam, The Netherlands on June 12th and 13th. We have once again added London to our spring tour, and we will be there June 18th and 19th.&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with Delphi Developer Days, it is an intense, two-day Delphi-focused event, where we cover some of Delphi&#39;s latest features, as well as topics that apply to many versions of Delphi. Bob and I present some of the more general topics together in joint sessions, where we share our knowledge and personal perspectives. We also include a number of breakout sessions, where Bob and I go to separate rooms to present different topics.&lt;br /&gt;
&lt;br /&gt;
I am very pleased with this year&#39;s agenda. Our joint sessions include an overview of mobile development with Delphi, where we will talk about both iOS and Android development, device setup, app deployment, and Delphi&#39;s next generation compiler. In another joint session we review some of the more advanced language features that have been added to Delphi since Delphi 2009.&lt;br /&gt;
&lt;br /&gt;
We also have a joint session on data awareness in cross-platform applications. In this session we discuss LiveBindings, as well as alternative techniques for presenting data to your users. And Delphi Developer Days would not be complete without our Tips, Tricks, and Techniques session. In this joint session Bob and I share a collection of powerful, and sometimes odd features of Delphi that you can use to extend your applications and improve your development experience.&lt;br /&gt;
&lt;br /&gt;
We also have a wide variety of separate sessions. In these sessions we cover FireDAC, Delphi&#39;s new data access framework, REST servers and clients, debugging and development support techniques, including unit testing, and an extensive and in-depth survey of object-oriented programming in Delphi. Other separate sessions cover advanced mobile development, a comparison of Delphi&#39;s target platforms and how these operating systems differ, as well as a session on when and where to place your data entry validation and business rules in database applications.&lt;br /&gt;
&lt;br /&gt;
For a complete list of sessions, view our agenda&amp;nbsp; at &lt;a href=&quot;http://www.delphideveloperdays.com/descriptions.html&quot; target=&quot;_blank&quot;&gt;http://www.delphideveloperdays.com/descriptions.html&lt;/a&gt;. On this page you will also find a link to view a more detailed description of each session.&lt;br /&gt;
&lt;br /&gt;
It&#39;s a lot of material in two days, and due to the separate sessions, you won&#39;t be able to physically attend every session. That&#39;s why Bob and I document every session we cover (with the obvious exception of the question and answer sessions that we hold at the end of each day). These limited edition &lt;a href=&quot;http://caryjensen.blogspot.com/2013_04_01_archive.html&quot; target=&quot;_blank&quot;&gt;course books&lt;/a&gt;, available only to Delphi Developer Days attendees, are extensive and detailed, typically weighing in at 300-400 pages. This year is no different. I have set aside a significant amount of time over the next three months for my writing, and I know Bob is doing the same. Regardless of which sessions you attend, you&#39;ll get all of the material we cover, include the many code samples we use in our demonstrations.&lt;br /&gt;
&lt;br /&gt;
I also want to mention that we are particular about where we hold our events. All of our venues are close to airports and/or train stations. For example, both of the hotels in the US have free shuttles from the nearby airports. These hotels also have free parking if you arrive by car. Our Frankfurt hotel is less than 2 kilometers from Frankfurt&#39;s main train station, from where you can hire a taxi or even catch a bus that stops outside the hotel. Alternatively, the hotel is a 30 euro taxi ride from Frankfurt Airport, one of the largest airports in Europe. There is also free parking for attendees on the days of the event.&lt;br /&gt;
&lt;br /&gt;
In Amsterdam, we are at the historic Victoria Park Plaza, which is directly across the street from Amsterdam&#39;s Central Station, which is a short train ride from Amsterdam&#39;s Schiphol Airport, also one of the largest in Europe. Finally, in London we are at the Park Inn London Heathrow. Fly into Heathrow and you can catch a free bus that drops you off a short walk from the hotel. There is also free parking for attendees on the days of the event.&lt;br /&gt;
&lt;br /&gt;
Attendance in each city is limit to 42 developers, which permits sufficient networking opportunities while keeping the experience intimate. As a result, however, we have sold out most cities over the past years, so you should consider registering early to ensure that you reserve a seat in the city of your choice. We are also offering discounts for early registration, and if you&#39;ve attended Delphi Developer Days since 2009, there are additional discounts. There are also discounts when your company sends three or more of their developers.&lt;br /&gt;
&lt;h3&gt;
Delphi Developer Days History&lt;/h3&gt;
Delphi Developer Days in a long-time Delphi touring event focusing exclusively on Delphi development. &lt;a href=&quot;http://www.jensendatasystems.com/aboutcj.html&quot; target=&quot;_blank&quot;&gt;Cary Jensen&lt;/a&gt;, who authored and was the featured speaker on the original Delphi World Tours (1995 through 1999), started Delphi Developer Days in the fall of 2001. From 2009 through 2012, &lt;a href=&quot;http://www.marcocantu.com/&quot; target=&quot;_blank&quot;&gt;Marco Cantù&lt;/a&gt; of Wintech Italia, Srl and Cary joined forces to co-offer Delphi Developer Days in Europe and in the United States. When Marco was hired to be the Delphi product manager, noted Delphi expert &lt;a href=&quot;http://www.drbob42.com/&quot; target=&quot;_blank&quot;&gt;Bob Swart&lt;/a&gt; of Bob Swart Training &amp;amp; Consultancy (eBob42) teamed up with Cary to keep the Delphi Developer Days tradition alive.&lt;br /&gt;
For more information, and to register, visit &lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;www.DelphiDeveloperDays.com&lt;/a&gt;.</description><link>http://caryjensen.blogspot.com/2014/02/delphi-developer-days-2014.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-3031514892033936970</guid><pubDate>Thu, 09 Jan 2014 14:38:00 +0000</pubDate><atom:updated>2014-01-10T07:15:23.675-08:00</atom:updated><title>Two Approaches to Sub-classing Components Compared</title><description>Delphi is an object oriented programming language. Unless you write nothing but console applications, this fact is obvious. For example, when your application includes either a form or a data module, the class that defines the form or data module is a descendent of an existing class. In the case of a form, it is a TForm descendant, and in the case of a data module it is a TDataModule descendant. &lt;br /&gt;
&lt;br /&gt;
This process of extending an existing class, especially one that is not TObject, is used extensively by the visual component library (VCL), and to a lesser extent in the runtime library (RTL). Importantly, it is a technique that you can use to create your own custom classes, ones that inherit the power of an existing class, and which extend that class to add additional features. These features might include new properties, additional methods, or alternative behaviors for methods inherited from the ancestor class.&lt;br /&gt;
&lt;br /&gt;
Overall, the VCL is a remarkable and rich component library. Nonetheless, it is not uncommon, especially with seasoned developers, to want to extend existing classes of the VCL or RTL to add custom capabilities. &lt;br /&gt;
&lt;br /&gt;
In this&amp;nbsp;post I am going to discuss two different, though not entirely dissimilar, techniques for creating a new class based on an existing VCL component. In most cases, these techniques can also be used to extend any component, whether created by you or your development team or a third party. Towards the end of this post I will compare these two techniques by discussing the particular strengths of each approach.&lt;br /&gt;
&lt;h3&gt;
The Traditional Method&lt;/h3&gt;
Most developers who sub-class components of the VCL do so by declaring that class as a descendant of the existing component, followed by compiling that class into a runtime package which they install in Delphi. I am going to demonstrate this technique by creating a component that extends the TDBGrid class, adding a handy feature for reading data from it&#39;s underlying TDataSet. &lt;br /&gt;
&lt;br /&gt;
This sub-classed grid exposes a GetField method, which returns a TField associated with the current record of the data set being displayed by the grid based on the name of the underlying dataset field. This new class also includes an InitializeDictionary method which must be called at least once after the grid has been associated with a dataset, but before the first call to GetField.&lt;br /&gt;
&lt;br /&gt;
Here is the declaration of this new class, named TEasyReaderDBGrid:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;type
&amp;nbsp; TEasyReaderDBGrid = class(Vcl.DBGrids.TDBGrid)
&amp;nbsp; private
&amp;nbsp;&amp;nbsp;&amp;nbsp; { Private declarations }
&amp;nbsp;&amp;nbsp;&amp;nbsp; FDict: TDictionary&amp;lt; string, TField&amp;gt;;
&amp;nbsp; public
&amp;nbsp;&amp;nbsp;&amp;nbsp; { Public declarations }
&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(AOwner: TComponent); override;
&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure InitializeDictionary(DataSet: TDataSet);
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &lt;summary&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// You must call InitializeDictionary each time you assign the
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// DataSet property of the grid before you can use GetField
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &lt;/summary&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function GetField(const Name: string): TField;
&amp;nbsp; end;&lt;/pre&gt;
&lt;br /&gt;
This class is not very complicated. It uses a generic TDictionary&lt;key value=&quot;&quot;&gt; (declared in System.Generics.Collections) to implement the GetField method. This can be seen in the implementation of this class, shown here:&lt;/key&gt;&lt;br /&gt;
&lt;pre&gt;{ TDBGrid }&lt;/pre&gt;
&lt;pre&gt;constructor TEasyReaderDBGrid.Create(AOwner: TComponent);
begin
&amp;nbsp; inherited;
&amp;nbsp; FDict := TDictionary&amp;lt; string, TField&amp;gt;.Create;
end;&lt;/pre&gt;
&lt;pre&gt;destructor TEasyReaderDBGrid.Destroy;
begin
&amp;nbsp; FDict.Free;
&amp;nbsp; inherited;
end;&lt;/pre&gt;
&lt;pre&gt;function TEasyReaderDBGrid.GetField(const Name: string): TField;
begin
&amp;nbsp; Result := FDict.Items[Name];
end;&lt;/pre&gt;
&lt;pre&gt;procedure TEasyReaderDBGrid.InitializeDictionary(DataSet: TDataSet);
var
&amp;nbsp; Field: TField;
begin
&amp;nbsp; for Field in DataSet.Fields do
&amp;nbsp;&amp;nbsp;&amp;nbsp; FDict.Add(Field.FieldName, Field);
end;&lt;/pre&gt;
All we need to do to make this component available on the component palette is to create a design time package, add this component&#39;s unit to the package, make a call to RegisterComponents from a Register procedure, and then install this new package.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve added the forward declaration and implementation of the Register method to the same unit in which the TEasyReaderDBGrid class is declared, adding this new component to the Samples page of the Tool Palette. Finally, here is the source of the design time package:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;package EasyReaderDBGrid;

{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$DESCRIPTION &#39;Runtime package for TEasyReaderDBGrid&#39;}
{$DESIGNONLY}
{$IMPLICITBUILD ON}

requires
&amp;nbsp; rtl,
&amp;nbsp; vcl,
&amp;nbsp; dbrtl,
&amp;nbsp; vcldb;

contains
&amp;nbsp; Traditionalu in &#39;Traditionalu.pas&#39;;

end.&lt;/pre&gt;
&lt;br /&gt;
Once we compile and install this new design time package, the new component, TEasyReaderDBGrid appears on the Samples page of the Tool Palette, as shown in Figure 1.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7nr_PXj_ayC_5Q0jRPA5m1fQKMnEEPKaQ0G1RhAyrRVLXuaHW5MM29dwQ5YzZPv11WEnHODjbU4yKGVzvtIlGKGWTDpEpwzZ1335I3XPji6lD_Dk-4B6cuyGinHPNmICJzcaFNIbyasA/s1600/figure1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7nr_PXj_ayC_5Q0jRPA5m1fQKMnEEPKaQ0G1RhAyrRVLXuaHW5MM29dwQ5YzZPv11WEnHODjbU4yKGVzvtIlGKGWTDpEpwzZ1335I3XPji6lD_Dk-4B6cuyGinHPNmICJzcaFNIbyasA/s1600/figure1.jpg&quot; height=&quot;231&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;em&gt;Figure 1. A traditionally sub-classed component appears on the Tool Palette&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
Figure 2 shows a VCL Forms application on which an instance of the TEasyReaderDBGrid class has been placed at design time.&amp;nbsp;In this figure a call to GetField has been made from the OnClick event handler of a button, shown here:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;procedure TForm1.Button1Click(Sender: TObject);
begin
&amp;nbsp; ShowMessage(EasyReaderDBGrid1.GetField(&#39;CustNo&#39;).AsString);
end;

&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtRCgoOFp0V8XRN8grP6mUYMDNmIYGhwZGsyAA1ukxhYzq3tZnNvLdzPBtnnczFkMag4rOhxDm9BBNLV2_mP8kYyBKnufK1mNSk-xn-j-fOImOPql4bZi5FyWDliwdBHNdZRQKqREfUnM/s1600/figure2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtRCgoOFp0V8XRN8grP6mUYMDNmIYGhwZGsyAA1ukxhYzq3tZnNvLdzPBtnnczFkMag4rOhxDm9BBNLV2_mP8kYyBKnufK1mNSk-xn-j-fOImOPql4bZi5FyWDliwdBHNdZRQKqREfUnM/s1600/figure2.jpg&quot; height=&quot;166&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;em&gt;Figure 2. The GetField method of the TEasyReaderDBGrid component returns a TField associated the grid&#39;s TDataSet.&lt;/em&gt;&lt;br /&gt;
&lt;h3&gt;
The Interceptor Method&lt;/h3&gt;
Unlike the traditional method, which involves adding a component to the component palette, the interceptor method &quot;intercepts&quot; the name of the existing VCL component, mapping it to a different class. Consider the form shown in Figure 3. &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKwyZ4Tl6UHnhV4PLmEKLrCCrBT53r8G3Qgnj6FKg32tJfFCKYITxxTo8YjFg1Bkcr57QuBr8U9nb5atAYvun2gpegv02uFbkDac-foXVB70v4JxOJqa6Gti4AWC9sLgGP7R86NteGtgk/s1600/figure3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKwyZ4Tl6UHnhV4PLmEKLrCCrBT53r8G3Qgnj6FKg32tJfFCKYITxxTo8YjFg1Bkcr57QuBr8U9nb5atAYvun2gpegv02uFbkDac-foXVB70v4JxOJqa6Gti4AWC9sLgGP7R86NteGtgk/s1600/figure3.jpg&quot; height=&quot;171&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;em&gt;Figure 3. A VCL Forms application using a class that intercepts TDBGrid&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
The form in Figure 3 looks and behaves like that shown in Figure 2. The difference is that the grid that appears in Figure 3 is not a TEasyReaderDBGrid. Instead, the grid is actually an instance of the TDBGrid class. This class, however, is intercepted and extended, giving the TDBGrid class the methods necessary to support the features of the TEasyReaderDBGrid class.&lt;br /&gt;
There are two general approaches to class interception. One is to intercept the class within the module where the extended class is used. This approach is shown in the following type declaration:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;type
&amp;nbsp; TDBGrid = class(Vcl.DBGrids.TDBGrid)
&amp;nbsp; private
&amp;nbsp;&amp;nbsp;&amp;nbsp; { Private declarations }
&amp;nbsp;&amp;nbsp;&amp;nbsp; FDict: TDictionary&amp;lt; string, TField&amp;gt;;
&amp;nbsp; public
&amp;nbsp;&amp;nbsp;&amp;nbsp; { Public declarations }
&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(AOwner: TComponent); override;
&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure InitializeDictionary(DataSet: TDataSet);
&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&amp;nbsp;&lt;summary&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&amp;nbsp;&amp;nbsp; You must call InitializeDictionary each time you assign the
&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&amp;nbsp;&amp;nbsp; DataSet property of the grid before you can use GetField
&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&amp;nbsp;&lt;/summary&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function GetField(const Name: string): TField;
&amp;nbsp; end;
&amp;nbsp; TForm1 = class(TForm)
&amp;nbsp;&amp;nbsp;&amp;nbsp; ClientDataSet1: TClientDataSet;
&amp;nbsp;&amp;nbsp;&amp;nbsp; DataSource1: TDataSource;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Button1: TButton;
&amp;nbsp;&amp;nbsp;&amp;nbsp; DBGrid1: TDBGrid;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Button1Click(Sender: TObject);
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure FormCreate(Sender: TObject);
&amp;nbsp; end;&lt;/pre&gt;
&lt;br /&gt;
Alternatively, the interceptor class can be declared in its own unit. In that case, all you need to do is ensure that the unit in which the interceptor class is declared appears later in the uses clause than the unit of the class that is being extended. Here is an example of how the interface section of an interceptor unit might look (the implementation is identical to that shown earlier for the TEasyReaderDBGrid class):&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;unit Interceptoru;

interface

uses System.Classes, Vcl.Grids, Vcl.DBGrids,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Generics.Collections, Data.DB;

type
&amp;nbsp; TDBGrid = class(Vcl.DBGrids.TDBGrid)
&amp;nbsp; private
&amp;nbsp;&amp;nbsp;&amp;nbsp; { Private declarations }
&amp;nbsp;&amp;nbsp;&amp;nbsp; FDict: TDictionary&amp;lt; string, TField&amp;gt;;
&amp;nbsp; public
&amp;nbsp;&amp;nbsp;&amp;nbsp; { Public declarations }
&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(AOwner: TComponent); override;
&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure InitializeDictionary(DataSet: TDataSet);
&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&amp;nbsp;&lt;summary&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&amp;nbsp;&amp;nbsp; You must call InitializeDictionary each time you assign the
&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&amp;nbsp;&amp;nbsp; DataSet property of the grid before you can use GetField
&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&amp;nbsp;&lt;/summary&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function GetField(const Name: string): TField;
&amp;nbsp; end;&lt;/pre&gt;
&lt;br /&gt;
When using an interceptor unit, I generally find it necessary to document the placement of the interceptor unit in the uses clause, as shown here:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;unit MainformIu;

interface

uses
&amp;nbsp; Winapi.Windows, Winapi.Messages, System.SysUtils,
&amp;nbsp; System.Variants, System.Classes, Vcl.Graphics,
&amp;nbsp; Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids,
&amp;nbsp; Vcl.DBGrids, system.Generics.Collections, Data.DB,
&amp;nbsp; Vcl.StdCtrls,Datasnap.DBClient,
&amp;nbsp; Interceptoru;&amp;nbsp; //This unit must appear later in this
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //uses clause than the Vcl.DBGrids unit

type
&amp;nbsp; TForm1 = class(TForm)
&amp;nbsp;&amp;nbsp;&amp;nbsp; ClientDataSet1: TClientDataSet;
&amp;nbsp;&amp;nbsp;&amp;nbsp; DataSource1: TDataSource;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Button1: TButton;
&amp;nbsp;&amp;nbsp;&amp;nbsp; DBGrid1: TDBGrid;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Button1Click(Sender: TObject);
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure FormCreate(Sender: TObject);
&amp;nbsp; end;&lt;/pre&gt;
&lt;br /&gt;
The real difference in implementation between the traditional method and the interceptor method is that your code looks as though you are using the class that you sub-classed, as opposed to the sub-class itself. This can be seen in the following event handler, which is similar to the OnClick event handler for the button shown earlier in this article.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;procedure TForm1.Button1Click(Sender: TObject);
begin
&amp;nbsp; ShowMessage(DBGrid1.GetField(&#39;CustNo&#39;).AsString);
end;&lt;/pre&gt;
&lt;h3&gt;
Comparing These Two Methods&lt;/h3&gt;
While the end result of these two approaches is identical, there are significant differences. These differences make each of these mechanisms better suited for some uses over the other. I&#39;ll begin by considering the advantages of the traditional approach.&lt;br /&gt;
&lt;h2&gt;
Advantage of the Traditional Approach&lt;/h2&gt;
The primary advantage of the traditional approach is that your sub-classed component can appear in the Tool Palette. Having the component in the Tool Palette provides two benefits. First, any published properties that you add to your sub-classed component will appear in the Object Inspector at design time. Second, once you&#39;ve placed the component onto your module from the Tool Palette, the unit in which your component is defined will be added to your interface section automatically the next time you save or compile your project.&lt;br /&gt;
&lt;br /&gt;
Both of these benefits come down to convenience. Traditionally sub-classed components are easier to use.&lt;br /&gt;
&lt;h2&gt;
Advantages of the Interceptor Approach&lt;/h2&gt;
While the interceptor approach has the drawback that it is somewhat more complicated to use, it also introduces benefits that make it a powerful alternative. To begin with, creating a interceptor class takes less time. There is no need to create a design time package and a design time package does not need to be installed.&lt;br /&gt;
&lt;br /&gt;
Not needing a design time package actually makes interceptor classes easier to share with a development team. Using the traditional approach, you need to provide each of the developers who will be working on the project with access to the package, which they will need to install into their copy of Delphi. When using an interceptor class, all you need to do is add the interceptor class unit into a directory on your library search path, and it will just work. Alternatively, you can make the interceptor unit a unit of your project, again making any classes defined in it immediately available to any unit that uses the interceptor unit.&lt;br /&gt;
&lt;br /&gt;
Another advantage of an interceptor class is that it makes it remarkably easy to extend an existing class when you want to add only one or two new features. Furthermore, when you declare your interceptor class directly in the unit from which it will be used, you can customize each instance of the ancestor class for that module. For example, you might want to add an additional method to a TListBox interceptor on a given form. If you have a second form that also needs a modified TListBox, but with a different custom method, no problem. Create a different interceptor class for each form and you are done.&lt;br /&gt;
&lt;br /&gt;
Finally, and what I think is absolutely the best advantage of interceptor classes is that it lets you make customizations to a component&#39;s sub-classes. For example, imagine that you want to add one or more custom properties to the individual menu items of a TMainMenu. This can be done very easily by creating an interceptor class for TMenuItem. After that, all of the menu items you add to your main menu will have those properties. Granted, you can only access those properties at runtime, but that is just a detail.&lt;br /&gt;
&lt;br /&gt;
Here is a simple example of a TMenuItem interceptor type declaration that, if added to a unit prior to the TForm declaration, adds a MyInteger runtime property to any menu item appearing on that form.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;type
&amp;nbsp; TMenuItem = class(Vcl.Menus.TMenuItem)
&amp;nbsp; strict private
&amp;nbsp;&amp;nbsp;&amp;nbsp; FMyInteger: Integer;
&amp;nbsp; public
&amp;nbsp;&amp;nbsp;&amp;nbsp; property MyInteger: Integer read FMyInteger write FMyInteger;
&amp;nbsp; end;&lt;/pre&gt;
&lt;br /&gt;
By comparison, if you use the traditional approach, you would have to actually sub-class TMainMenu and implement an extended version of TMenuItem from within the owner class. &lt;br /&gt;
&lt;h3&gt;
Summary&lt;/h3&gt;
Sub-classing existing classes of the VCL (or other libraries) is a powerful tool that every Delphi developer should take advantage of. In this article I have looked at the two primary mechanisms for sub-classing existing components. Each of these approaches have their strengths, making each best suited for some applications over the other.&lt;br /&gt;
&lt;br /&gt;
Copyright (c) 2013 Cary Jensen. All Rights Reserved</description><link>http://caryjensen.blogspot.com/2014/01/two-approaches-to-sub-classing.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7nr_PXj_ayC_5Q0jRPA5m1fQKMnEEPKaQ0G1RhAyrRVLXuaHW5MM29dwQ5YzZPv11WEnHODjbU4yKGVzvtIlGKGWTDpEpwzZ1335I3XPji6lD_Dk-4B6cuyGinHPNmICJzcaFNIbyasA/s72-c/figure1.jpg" height="72" width="72"/><thr:total>8</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-7068965914428517968</guid><pubDate>Thu, 19 Sep 2013 04:45:00 +0000</pubDate><atom:updated>2013-09-18T21:45:26.550-07:00</atom:updated><title>New 2013 Delphi Developer Days Event</title><description>I am pleased to announce a special edition of Delphi Developer Days 2013 and Mobile Development Workshop, to be held this December 4th, 5th, and 6th near London&#39;s Heathrow Airport. This three-day event includes the classic two-day Delphi Developer Days 2013 sessions by me and Delphi expert Bob (Dr.Bob) Swart, where Bob and I present joint sessions, where we present in-depth topics together, as well as separate sessions, where we break out into separate rooms to present diverse topics.&lt;br /&gt;
&lt;br /&gt;
The optional third day is the Delphi Developer Days Mobile Development Workshop, where Bob and I work with you to develop and deploy mobile applications to your iOS * or Android ** mobile device. This one-of-a-kind workshop includes focused discussions by Bob and me where we explain aspects of mobile development, followed by hand-on sessions where you implement the concepts we describe. During this time we are available to answer questions, provide guidance, and help you build and deploy your sample applications.&lt;br /&gt;
&lt;br /&gt;
You can attend all three days of this special event, just the first two days, or only the Delphi Developer Days Mobile Development Workshop. Discounts are available to previous Delphi Developer Days attendees, and their is a special discount for the hands-on workshop available to attendees of this spring&#39;s Delphi Developer Days. There are also discounts for early registration.&lt;br /&gt;
&lt;br /&gt;
Lunch is provided on each day that you attend. All attendees registered for the first two days will receive our Delphi Developer Days 2013 course book, containing more than 400 pages of material covered in our presentations. Similarly, attendees of the Delphi Developer Days Mobile Development Workshop will receive material on iOS, Android, and FireDAC mobile development written by Bob and me. Space is limited, so register now to reserve your seat.&lt;br /&gt;
&lt;br /&gt;
Visit &lt;a href=&quot;http://www.delphideveloperdays.com/&quot;&gt;www.DelphiDeveloperDays.com&lt;/a&gt; for more information, including registration, agenda, software and hardware requirements, location details, and more.&lt;br /&gt;
&lt;br /&gt;
* iOS devices include iPhone, iPad, and iPad mini devices&lt;br /&gt;
** Android devices must be based on ARMv7 compatible CPUs. Android Jelly Bean is preferred, though most Ice Cream Sandwich and Gingerbread devices are supported</description><link>http://caryjensen.blogspot.com/2013/09/new-2013-delphi-developer-days-event.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-6650542646998399056</guid><pubDate>Wed, 07 Aug 2013 13:11:00 +0000</pubDate><atom:updated>2013-08-08T17:12:51.775-07:00</atom:updated><title>Dragging and Dropping in DBGrids Revisited</title><description>&lt;i&gt;Please note: a bug&amp;nbsp;was found in the original code upload. It was reported in a comment below. &lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;I have uploaded a code example that fixes the problem (see link at the of this post). However, that code can only handle drag/drop operations in a DBGrid so long as the Options property of that DBGrid includes the dgTitles flag.&lt;/i&gt;&lt;br /&gt;
&lt;em&gt;&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;I am leaving this post, and a link to the updated code, live on this blog, as I know that the feature described here is a valuable one. I will continue to work on addressing the remaining issue, and will update this blog and the code upload once I have accomplished that. &lt;/em&gt;&lt;br /&gt;
&lt;em&gt;&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Once again, thank you for your patience.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
About a year ago I posted a &lt;a href=&quot;http://caryjensen.blogspot.com/2012/08/dragging-and-dropping-into-dbgrids.html&quot; target=&quot;_blank&quot;&gt;blog&lt;/a&gt; that described in detail how to implement drag and drop operations with a DBGrid. The technique that I described employed a ClientDataSet as a key element in the drag and drop process, and it is one that I have used extensively in the year since.&lt;br /&gt;
&lt;br /&gt;
There was one glich, however. During this past spring&#39;s &lt;a href=&quot;http://www.delphideveloperdays.com/&quot; target=&quot;_blank&quot;&gt;Delphi Developer Days&lt;/a&gt; tour with my colleague &lt;a href=&quot;http://www.drbob42.com/&quot;&gt;Bob Swart&lt;/a&gt;&amp;nbsp;(a.k.a Dr.Bob)&amp;nbsp;one of the attendees asked what would happen if the DBGrid displayed less than all records in the underlying ClientDataSet. It turns out that this is an issue with my original code example (and it has since been pointed out elegantly in a comment posted to the blog post I linked to above). If the first record displayed in the DBGrid does not correspond to the first record in the underlying ClientDataSet, my original code would incorrectly place a record dropped into the top position of the DBGrid in the top-most position of the ClientDataSet, instead of above the record onto which the drop operation targeted.&lt;br /&gt;
&lt;br /&gt;
Initially I did not worry about this discrepancy too much, selfishly I will admit. In my&amp;nbsp;real world usage, the number of records being dragged or dropped never exceeded the visual display capacity&amp;nbsp;of the DBGrid. But it is a problem, and Michael Riley&#39;s posted comment on my earlier blog motivated me once again to look for a solution.&lt;br /&gt;
&lt;br /&gt;
As that last paragraph implied, I did try to find a solution earlier, in response to the question posed by the Delphi Developer Days attendee. However, I could not see a way to determine the record number of the underlying DataSet when the visible rows of the DBGrid were greater than the number of records in the DataSet, and the DBGrid was scrolled down.&lt;br /&gt;
&lt;br /&gt;
Having taken up the challenge again, I turned to every coder&#39;s best friend, Stack Overflow. There I posted my &lt;a href=&quot;http://stackoverflow.com/questions/18034030/what-dataset-row-appears-in-the-top-most-row-of-dbgrid-when-rowcount-visiblero&quot; target=&quot;_blank&quot;&gt;question&lt;/a&gt;, hoping that someone had discovered an appropriate mechanism. Even though I posted the question on a Saturday, long-time Stack Overflow contributor &lt;a href=&quot;http://stackoverflow.com/users/26833/uwe-raabe&quot; target=&quot;_blank&quot;&gt;Uwe Raabe&lt;/a&gt; was quick to post an answer. With this information in hand, I was able to quickly adapt my earlier drag and drop example to correctly perform drag and drop into and within a DBGrid under all relevant conditions.&lt;br /&gt;
&lt;br /&gt;
What Uwe proposed was the creation of a class helper for the TDBGrid class. His class helper looked like the following:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;TDBGridHelper = class helper for TDBGrid
public
    function RecNoFromVisibleRow(Value: Integer): Integer;
end;
&lt;/pre&gt;
&lt;br /&gt;
His implementation of the RecNoFromVisibleRow method is shown here:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;function TDbGridHelper.RecNoFromVisibleRow(Value: Integer): Integer;
begin
  Result := DataSource.DataSet.RecNo - Row + TopRow + Value;
  if dgTitles in Options then
    Dec(Result);
end;
&lt;/pre&gt;
&lt;br /&gt;
This worked like a charm, and solve the problem that I specifically asked about in my Stack Overflow post, which concerned the first visible record in the DBGrid. Testing&amp;nbsp;my updated drag and drop example revealed another issue that I had not anticipated. Specifically, if the DBGrid contained more records than the number visible in the DBGrid, and the user dropped a new record past the end of the last visible record, that record would be placed at the end of the underlying ClientDataSet, rather than after the last visible record.&lt;br /&gt;
&lt;br /&gt;
This problem was easy to solve by modifying Uwe&#39;s code in the following manner.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;function TDBGridHelper.RecNoFromVisibleRow(Value: Integer): Integer;
begin
  if Value = -1 then
  begin
    Result := DataSource.DataSet.RecNo - Row + TopRow + VisibleRowCount
  end
  else
  begin
    Result := DataSource.DataSet.RecNo - Row + TopRow + Value;
    if dgTitles in Options then
      Dec(Result);
  end;
end;
&lt;/pre&gt;
&lt;br /&gt;
Over the past several days I have tested this code pretty hard, and it appears to work under all conditions. A link to the download for the final code example is located at the end of this blog post.&lt;br /&gt;
&lt;br /&gt;
I will leave it up to you to&amp;nbsp;follow the link I provided at the outset of this post to read the details about how this dragging and dropping in DBGrids works. I will, however, point out the minor changes that the introduction of this class helper has on the original code. In addition, I will discuss the use of class helpers, and offer an alternative solution, in the form of an interceptor class.&lt;br /&gt;
&lt;br /&gt;
My original OnDragDrop event handler on the DBGrid began like the following:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;procedure TForm1.DBGridDragDrop(Sender, Source: TObject; X, Y: Integer);
var
  GridRow: Integer;
  OriginalRow: Integer;
begin
  GridRow := DBGrid.MouseCoord(X,Y).Y;
  if GridRow = 0 then
    GridRow := 1;
  if (Source is TListBox) then
&lt;/pre&gt;
&lt;br /&gt;
It now looks like this, where the initial adjustment of the GridRow variable is replaced by a call to the RecNoFromVisibleRow method:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;procedure TForm1.DBGridDragDrop(Sender, Source: TObject; X, Y: Integer);
var
  GridRow: Integer;
  OriginalRow: Integer;
begin
  GridRow := DBGrid.MouseCoord(X,Y).Y;
  GridRow := DBGrid.RecNoFromVisibleRow((*ClientDataSet.RecNo, *)GridRow);
  if (Source is TListBox) then
&lt;/pre&gt;
&lt;br /&gt;
However, when dragging and dropping within the DBGrid itself, GridRow values of 0 do need to be adjusted to 1, so that happens later in this method method, once a within grid drag/drop is confirmed, as shown here:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;  if Source = Sender then
  begin
    //We are dragging within the DBGrid
    if ClientDataSet.IsEmpty then exit;
    OriginalRow := ClientDataSet.RecNo;
    if (OriginalRow = GridRow) or (GridRow = -1) then
      exit
    else
    if GridRow = 0 then GridRow := 1;
    MoveRecord(ClientDataSet, OriginalRow, GridRow);
  end;
&lt;/pre&gt;
&lt;br /&gt;
I also added an additional line of code to reposition the current record in the underlying ClientDataSet at the end of the segment associated with a drop from the ListBox (dropping from outside of the DBGrid). This line, and the several above it, are shown here:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;  //Insert the new item at the drop position
  ClientDataSet.InsertRecord( [GridRow,  TListBox(Source).Items[TListBox(Source).ItemIndex], RandomRange(1, 101)]);
  //Make the dropped record the current record
  ClientDataSet.RecNo := GridRow;
&lt;/pre&gt;
&lt;br /&gt;
Other than the declaration of the class helper and the implementation of RecNoFromVisibleRow, all of the remaining original code is untouched.&lt;br /&gt;
&lt;br /&gt;
Now, let me address the use of the class helper. First let me say that using a class helper is a perfectly sound solution. It does, however, have one drawback. You can have only one class helper for a given class. If you already have a class helper for TDBGrid (or if Embarcadero introduces one), this new class helper will make that one unavailble.&lt;br /&gt;
&lt;br /&gt;
An alternative solution is to use an interceptor class. An interceptor class is one that has the same class name as the existing class, and extends that existing class, but which has a scope closer to the code that uses it than the original class. When those conditions exist, the&amp;nbsp;interceptor class takes precedence, and its overridden or introduced methods, properties, fields, and such, are available to your code. In addition, since the interceptor class is a descendant of the original, any protected&amp;nbsp;(other than strict protected) members of the original class are visible to it. This is important, since Row and TopRow, which are protected members of the Vcl.DBGrids.TDBGrid class, need to be access from within the RecNoFromVisibleRow method.&lt;br /&gt;
&lt;br /&gt;
In&amp;nbsp;my code sample, the interceptor class is declared prior to the TForm class, which results in any TDBGrid instances appearing on the form being instances of my interceptor class. This class declaration looks like the following (in which I have included a little bit of the TForm declaration as well):&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;type
  TDBGrid = class(DBGrids.TDBGrid)
  public
    function RecNoFromVisibleRow(Value: Integer): Integer;
  end;
  TForm1 = class(TForm)
    ListBox: TListBox;
    DBGrid: TDBGrid;

&lt;/pre&gt;
Of course, you must implement the RecNoFromVisibleRow method in the interceptor class. In this case, since the interceptor class is named TDBGrid, the only difference between the implementation of the interceptor method and class helper method is the class name (TDBGrid versus TDBGridHelper). As a result, I will not repeat that code here. Otherwise, the remaining code is exactly the same. A helper class adds the RecNoFromVisibleRecord method to the Vcl.DBGrids.TDBGrid class, while the interceptor class introduces this method, and TDBGrid instances on the form are instances of the interceptor, instead of the interceptor&#39;s ancestor.&lt;br /&gt;
&lt;br /&gt;
One final note. While I declared the interceptor class in the same unit as my form declaration, I could have just as easily declared it in some other unit. The only requirement for the use of the interceptor class in my form is that the unit in which the interceptor class is declared must appear in the interface section uses clause, and later in that uses clause than the Vcl.DBGrids unit.&lt;br /&gt;
&lt;br /&gt;
Here is the link to the &lt;a href=&quot;http://jensendatasystems.com/dbgriddragdrop/&quot; target=&quot;_blank&quot;&gt;updated code&lt;/a&gt;. Please enjoy.</description><link>http://caryjensen.blogspot.com/2013/08/dragging-and-dropping-in-dbgrids.html</link><author>noreply@blogger.com (Unknown)</author><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6222893893652665733.post-232642791015531443</guid><pubDate>Fri, 19 Apr 2013 09:56:00 +0000</pubDate><atom:updated>2013-04-19T02:56:00.137-07:00</atom:updated><title>Delphi Developer Days 2013 Course Book</title><description>Over the past month and a half, Bob Swart and I have been writing the material for Delphi Developer Days 2013 (&lt;a href=&quot;http://www.delphideveloperdays.com/&quot;&gt;http://www.DelphiDeveloperDays.com&lt;/a&gt;). In all we produced seven chapters each. Bob and I each wrote two of the joint sessions, and we each wrote our own four individual sessions. We also each wrote our half of the Tips, Tricks, and Techniques session. This is why the course book has 14 chapters while Delphi Developer Days includes 13 unique sessions.&lt;br /&gt;
&lt;br /&gt;
Loy Anderson, who manages Delphi Developer Days, had given us an early April deadline in order to have the course books printed in time for Chicago. It was a lot of work, but we did it, and Loy worked hard to compile our chapters into a unified book as we finished each chapter. She submitted the book for printing on April 7th, and we fully anticipated getting the books in time for our Chicago event, which begins on May 6th.&lt;br /&gt;
&lt;br /&gt;
To our amazement, the books arrived this week, both those intended for Chicago as well as a European delivery of books for our Frankfurt and Amsterdam events. The book is over 400 pages in length, and we are not talking slideshows here. As you can see in the following picture, our chapters are detailed, and include screenshots and code samples.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxLl85vrY2llaiJTWR9MUalkhiJXssPECn3DjQCVU984edkvQWS38S5dQkWAeNKIaHMhWfn-QKqt3K0PR7A-0Tqo-IQP8V_xiMVj1yNSte1ici9jm_m_VPpNq7UpFdWJtdl5aFJveknU4/s1600/P1060112.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxLl85vrY2llaiJTWR9MUalkhiJXssPECn3DjQCVU984edkvQWS38S5dQkWAeNKIaHMhWfn-QKqt3K0PR7A-0Tqo-IQP8V_xiMVj1yNSte1ici9jm_m_VPpNq7UpFdWJtdl5aFJveknU4/s320/P1060112.JPG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
Of course, this detail is necessary for our individual sessions. During these sessions, Bob and I break out into separate rooms to present our specific topics. If you decide to go to Bob&#39;s presentation, you can always catch up on my presentation by reading my chapter on the topic in the book. But we feel that detailed chapters are also important for our joint sessions, giving you something to refer back to long after Delphi Developer Days is over.&lt;br /&gt;
&lt;br /&gt;
I am especially pleased this year with our content. Like I have done in the past with Marco Cantù, Bob and I worked hard to create a solid selection of topics that should be of interest to almost every Delphi developer. Some of our sessions cover the absolute latest information on Delphi, including Delphi XE4, which was announced just over a week ago. These talks include iOS development, Delphi&#39;s new NextGen compiler, and FireDAC, the new data access component framework.&lt;br /&gt;
&lt;br /&gt;
There is also plenty of material to engage developers using older versions of Delphi. For example, there are talks on multithreaded development, DataSnap, debugging, browser-based clients, and Windows services. When appropriate, these talks discuss features added in recent versions of Delphi. However, the bulk of the information in these chapters applies to older versions of Delphi (some going back as far as the original Delphi).&lt;br /&gt;
&lt;br /&gt;
In addition to working to find a balance of topics, Bob and I also worked to organize the talks intelligently. For example, talks on data access (including FireDAC) and multithreaded development are presented prior to those on DataSnap (which assumes knowledge about data access and multithreaded programming). &lt;br /&gt;
&lt;br /&gt;
Likewise, we tried to pair our individual presentations in a meaningful way. When one of us is speaking about one of the most recent versions of Delphi, the other is presenting a topic that appeals to developers using older versions. Likewise, we tried to match an Internet-related presentation with one that applies to traditional workstation applications.&lt;br /&gt;
&lt;br /&gt;
Although the book is printed (and in our hands), we all continue preparing for the actual events. Loy has a lot of organizational details to complete, including the printing of name badges and onsite signage, as well as arranging for lunches and our various guest speakers. Bob and I continue to work on our talks, creating our slideshows, and adding to, and improving, the demo projects that we&#39;ll use.&lt;br /&gt;
&lt;br /&gt;
We are really looking forward to this year&#39;s event, and I am looking forward to this first year presenting with Bob Swart. For those of you who have already registered, we look forward to seeing your there. While Chicago has sold out, we still have space available in both Frankfurt and Amsterdam, but we expect these cities to sell out as well. Furthermore, at the time of this posting we still have a 10% discount for early registration in Europe, which ends April 30, 2013. See &lt;a href=&quot;http://www.delphideveloperdays.com/&quot;&gt;http://www.DelphiDeveloperDays.com&lt;/a&gt; for details and pricing.&lt;br /&gt;
&lt;br /&gt;
Delphi Developer Days is fun, and we are looking forward to it. We hope you are, too.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVgFEGWEBsdgmoZ1771LvufvDRec7VtiUwohGnvDAap6dBb_2KRaEI6a1yG_QQKoKxYm_xO5F7eO6ZVHOGS0e3UJOAJBJNx65ezJUYxBiX-_MLpQ1C1rEGMuxsY81iRQomrNlT9ZCbDSA/s1600/P1060117.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVgFEGWEBsdgmoZ1771LvufvDRec7VtiUwohGnvDAap6dBb_2KRaEI6a1yG_QQKoKxYm_xO5F7eO6ZVHOGS0e3UJOAJBJNx65ezJUYxBiX-_MLpQ1C1rEGMuxsY81iRQomrNlT9ZCbDSA/s320/P1060117.JPG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
</description><link>http://caryjensen.blogspot.com/2013/04/delphi-developer-days-2013-course-book.html</link><author>noreply@blogger.com (Unknown)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxLl85vrY2llaiJTWR9MUalkhiJXssPECn3DjQCVU984edkvQWS38S5dQkWAeNKIaHMhWfn-QKqt3K0PR7A-0Tqo-IQP8V_xiMVj1yNSte1ici9jm_m_VPpNq7UpFdWJtdl5aFJveknU4/s72-c/P1060112.JPG" height="72" width="72"/><thr:total>7</thr:total></item></channel></rss>