<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns: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'><id>tag:blogger.com,1999:blog-1853768304794693097</id><updated>2026-03-21T11:40:55.122-07:00</updated><category term="Delphi"/><category term="Android"/><category term="Windows"/><category term="CPlusPlus"/><category term="Oxygene for Java"/><category term="Project Cooper"/><category term="iPhone"/><category term="Mac"/><category term=".NET"/><category term="Mono"/><category term="Mono for Android"/><category term="Delphi Prism"/><category term="Misc"/><category term="Oxygene for .NET"/><category term="MonoTouch"/><category term="Java"/><category term="Fitness"/><category term="Language"/><category term="Project Nougat"/><category term="Oxygene for Cocoa"/><title type='text'>It&#39;s a blong, blong, blong road...</title><subtitle type='html'>This is the blog of Brian Long, Windows &amp;amp; mobile trainer, trouble-shooter and consultant.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.blong.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://blog.blong.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>174</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-526828737879656327</id><published>2021-04-08T08:10:00.001-07:00</published><updated>2021-04-08T08:10:12.123-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>Installer tip</title><content type='html'>&lt;div style=&quot;text-align: left;&quot;&gt;I&#39;m really enjoying RAD Studio 10.4.2, but my journey with it got off to a less than wholesome start. I&#39;d installed from the .iso download and put just a basic Windows platform support in. Shortly thereafter I wanted more target platforms installed so I chose Tools, Manage Platforms... and was disturbed to see this message:&lt;/div&gt;&lt;div style=&quot;text-align: left;&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-LE6FWdcKUgDgi1_yj39YrB9LtZmXkyQN8wFL2crp8pWr2BhXeOWYD2pSilWtOBJJisAnqQqsgTkMvlFxDPd2sNEJt5rZbAMdJ6uV85w2mocYiPCBMub2hFcEOXS2bX_vl9AYftnr1MI/s639/GetIt_missing_gof.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;450&quot; data-original-width=&quot;639&quot; height=&quot;450&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-LE6FWdcKUgDgi1_yj39YrB9LtZmXkyQN8wFL2crp8pWr2BhXeOWYD2pSilWtOBJJisAnqQqsgTkMvlFxDPd2sNEJt5rZbAMdJ6uV85w2mocYiPCBMub2hFcEOXS2bX_vl9AYftnr1MI/w640-h450/GetIt_missing_gof.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;i&gt;&lt;b&gt;O NOES!!11111!1!!!one!!&lt;/b&gt;&lt;/i&gt; (or some other geeky response)&lt;/p&gt;&lt;p&gt;Fortunately there was no corruption. This post is simply to pass on the tip of what to do if you happen to see this, instead of following the knee-jerk reaction of immediately uninstalling and reinstalling.&lt;/p&gt;&lt;p&gt;The issue here is misinformation. It&#39;s not &lt;i&gt;necessarily&lt;/i&gt; corrupted at all - the installer displays this message if it cannot find the installation database file. When you installed RAD Studio the location of the installer file is written to the registry within this key:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;HKEY_CURRENT_USER\SOFTWARE\Embarcadero\BDS\21.0\CatalogRepository&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The value &lt;span style=&quot;font-family: courier;&quot;&gt;ServicePath&lt;/span&gt;&amp;nbsp;in that key points to a .gof file, in my case&amp;nbsp;F:\radstudio_10_4_esd_104203a.gof. The thing is, I installed from a .iso file, which I mounted to a drive (F:) at the time and had since unmounted,&amp;nbsp;∴ that path no longer reached anything. Unfortunately the installer responded inappropriately: misinformation.&lt;/p&gt;&lt;p&gt;I gather this issue will be fixed for the 10.5 installer, but hopefully this saves someone the trouble of an uninstall and reinstall at some point.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/526828737879656327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2021/04/installer-tip.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/526828737879656327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/526828737879656327'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2021/04/installer-tip.html' title='Installer tip'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-LE6FWdcKUgDgi1_yj39YrB9LtZmXkyQN8wFL2crp8pWr2BhXeOWYD2pSilWtOBJJisAnqQqsgTkMvlFxDPd2sNEJt5rZbAMdJ6uV85w2mocYiPCBMub2hFcEOXS2bX_vl9AYftnr1MI/s72-w640-h450-c/GetIt_missing_gof.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-4917207648809329426</id><published>2021-04-07T16:06:00.004-07:00</published><updated>2021-04-08T08:10:51.157-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>SAPI (Microsoft Speech API) problems with the IDE</title><content type='html'>&lt;p&gt;Every few months or so someone sends me an email telling me they&#39;ve speech-enabled their application with SAPI (the Microsoft Speech API) after having read &lt;a href=&quot;http://blong.com/Conferences/DCon2002/Speech/Speech.htm&quot; target=&quot;_blank&quot;&gt;my old coverage&lt;/a&gt;&amp;nbsp;(specifically &lt;a href=&quot;http://blong.com/Conferences/DCon2002/Speech/SAPI51/SAPI51.htm&quot; target=&quot;_blank&quot;&gt;that for SAPI 5.1&lt;/a&gt;) from &lt;a href=&quot;http://blong.com/Conferences.htm#DCon2002&quot;&gt;conferences in 2002&lt;/a&gt; and before. It&#39;s always good to hear that stuff you&#39;ve worked on is being found useful, even long after you did it, in this case frighteningly close to 2 decades ago (Ͼ˳Ͽ)..!!!&lt;/p&gt;&lt;p&gt;Sometimes the communications are asking how to do specific things with SAPI - unfortunately those are typically a dead end, as I haven&#39;t used SAPI in anger for a long while.&lt;/p&gt;&lt;p&gt;Sometimes, though, people are stuck on the basics and I was recently contacted by someone with a fairly current version of RAD Studio saying they couldn&#39;t get started at all. It turns out that the current version of SAPI, SAPI 5.4, cannot be imported into RAD Studio!&lt;/p&gt;&lt;p&gt;Uh-oh. Time to investigate...&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;The steps to import SAPI components into the IDE is as follows (and is &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Import_Component_Wizard&quot; target=&quot;_blank&quot;&gt;documented here&lt;/a&gt;):&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Choose &lt;i&gt;Component&lt;/i&gt;, &lt;i&gt;Import Component...&lt;/i&gt; (as mentioned in &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Importing_Type_Library_Information&quot; target=&quot;_blank&quot;&gt;the documentation&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Select &lt;i&gt;Import a Type Library&lt;/i&gt; and press &lt;i&gt;Next&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Choose the Microsoft Speech Object Library that is defined in sapi.dll:&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&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/AVvXsEhkkE7HuhKXih3_PkFeZAY_Nhs4L0qCvLdLmI8HVnkSdmn76e1rUw5Lkog_ADkpG__KjNT2xsybgfvpXdvXC8URNWkGop5dtknPY9G_bIgy7RtQlIzyAnVUBpFXOdDPLz_DMKR8Pc7paJI/s1012/SAPI_import.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;420&quot; data-original-width=&quot;1012&quot; height=&quot;266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkkE7HuhKXih3_PkFeZAY_Nhs4L0qCvLdLmI8HVnkSdmn76e1rUw5Lkog_ADkpG__KjNT2xsybgfvpXdvXC8URNWkGop5dtknPY9G_bIgy7RtQlIzyAnVUBpFXOdDPLz_DMKR8Pc7paJI/w640-h266/SAPI_import.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Press &lt;i&gt;Next&lt;/i&gt; and choose a target &lt;i&gt;Palette Page&lt;/i&gt;:&lt;/li&gt;&lt;/ul&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/AVvXsEhGaaH6Q3yRpz-IEtFqiJTYybRk2CmQUUdMkviA1mVfZEWqIY-XHCsghTSMo0HRLKN-XF0cSJQA6W6Pw5IAs1TSvpy46kgs8zuRkxGnI9gJfDcjbEq7AnRBP8kTfS601dyUJLijwWJMp0A/s685/SAPI_import_2.png&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/AVvXsEhGaaH6Q3yRpz-IEtFqiJTYybRk2CmQUUdMkviA1mVfZEWqIY-XHCsghTSMo0HRLKN-XF0cSJQA6W6Pw5IAs1TSvpy46kgs8zuRkxGnI9gJfDcjbEq7AnRBP8kTfS601dyUJLijwWJMp0A/w447-h274/SAPI_import_2.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Press &lt;i&gt;Next&lt;/i&gt;, select &lt;i&gt;Install to New Package&lt;/i&gt; and press &lt;i&gt;Next&lt;/i&gt; again&lt;/li&gt;&lt;li&gt;Now choose a value for &lt;i&gt;Package name&lt;/i&gt; (and optionally for &lt;i&gt;Description&lt;/i&gt;) and press &lt;i&gt;Finish&lt;/i&gt;:&lt;/li&gt;&lt;/ul&gt;&lt;/div&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/AVvXsEg9hHRHtfgOZnQCeqW1llnJRkKykADKI_P-zND-rDRNQXDePzXKcNZI3GYnCtE-R11-CUPwe-auwyEFcy5iGvSHa3kz0exoP5bLYtHKetBAjc8LGTOy-pCbM5_mnO59JB9AffXsVptM5KI/s685/SAPI_import_3.png&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/AVvXsEg9hHRHtfgOZnQCeqW1llnJRkKykADKI_P-zND-rDRNQXDePzXKcNZI3GYnCtE-R11-CUPwe-auwyEFcy5iGvSHa3kz0exoP5bLYtHKetBAjc8LGTOy-pCbM5_mnO59JB9AffXsVptM5KI/w446-h273/SAPI_import_3.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;At this point the package will be created and a type library import unit is added to it and the IDE will try to build the package. Immediately something is flagged up:&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimlKxOrj4H9qE7cd4woYVepvZ5RLIzqDVZqk7Y2ztBfwppuM_8eiAWmDipbWMatFFM2dfbrDGt3pAZAjZ8fN9bd5JMUWZRZZfhwdgCJtV964Cqath6p45wYjKW4iyXxYA8ZRfcyLZL5yQ/s1029/SAPI_import_4.png&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/AVvXsEimlKxOrj4H9qE7cd4woYVepvZ5RLIzqDVZqk7Y2ztBfwppuM_8eiAWmDipbWMatFFM2dfbrDGt3pAZAjZ8fN9bd5JMUWZRZZfhwdgCJtV964Cqath6p45wYjKW4iyXxYA8ZRfcyLZL5yQ/w630-h115/SAPI_import_4.png&quot; width=&quot;630&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Click &lt;i&gt;Yes&lt;/i&gt; and the package will start building proper. This is where it all falls apart:&lt;/p&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/AVvXsEjfjAMcteGdepkNZZHJrZkO2gP-jBT-z0mX9jsgssveY-k9FlYpYRKFQG810bDAw3fCu8vaiL_fqU6PVKFk3q_sg44sspQwzFunKpxySrh9MB6kwoGyhvXbVjmljbnoBxn6rxr36IyzgHQ/s586/SAPI_import_5.png&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/AVvXsEjfjAMcteGdepkNZZHJrZkO2gP-jBT-z0mX9jsgssveY-k9FlYpYRKFQG810bDAw3fCu8vaiL_fqU6PVKFk3q_sg44sspQwzFunKpxySrh9MB6kwoGyhvXbVjmljbnoBxn6rxr36IyzgHQ/w540-h281/SAPI_import_5.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&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/AVvXsEjNYc3VXp_MVC6rS0m8erLA1SXc5eWRiLXDSyKejTG-GPxtR7dLUG6_MOMrVeAxBh8Ymu4sKO1F4veXAGSVQpbZbSIeAkU1jEd29uHhTYgfK-gDxDyIN7Tuuqy_bx5PBIOZZG9pDoRyL2Y/s590/SAPI_import_6.png&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/AVvXsEjNYc3VXp_MVC6rS0m8erLA1SXc5eWRiLXDSyKejTG-GPxtR7dLUG6_MOMrVeAxBh8Ymu4sKO1F4veXAGSVQpbZbSIeAkU1jEd29uHhTYgfK-gDxDyIN7Tuuqy_bx5PBIOZZG9pDoRyL2Y/w496-h443/SAPI_import_6.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Hmm, is there a massive FUBAR in the type library importer? Sure looks like that could be the case....&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;However, upon closer inspection the issue actually comes up thanks to the SAPI type library defining its own versions of the already-defined-in-Delphi interfaces &lt;span style=&quot;font-family: courier;&quot;&gt;IStream&lt;/span&gt; and&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;ISequentialStream&lt;/span&gt;. In the SAPI versions they have extra methods, references to which then fail to compile thanks to those methods not being imported.&lt;/div&gt;&lt;p&gt;Why are those &#39;known&#39; interfaces not imported? Well, the idea is to avoid ambiguity with having multiple definitions, but that&#39;s not important as... we can override this omission!&lt;/p&gt;&lt;p&gt;In your RAD Studio bin folder (e.g.&amp;nbsp;C:\Program Files (x86)\Embarcadero\Studio\21.0\bin) you will find a file called&amp;nbsp;&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Mapping_Symbol_Names_in_a_Type_Library&quot; target=&quot;_blank&quot;&gt;tlibimp.sym&lt;/a&gt;. This is the configuration file for the type library importers (both the one in the IDE we just used and also the command-line utility &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/TLIBIMP.EXE&quot; target=&quot;_blank&quot;&gt;TLibImp.exe&lt;/a&gt;). The content of this configuration file affect the way type libraries get imported to help cover various trouble areas. In this case we need to remove some settings to get the SAPI type library imported.&lt;/p&gt;&lt;p&gt;Here is a part of tlibimp.sym:&lt;/p&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;;;===================================================================;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;;; Names listed in this section are skipped by the importer&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;;; Built-in Interfaces, such as IUnknown and IDispatch are listed&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;;; here&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;;;===================================================================;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;[BuiltInInterfaces]&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;{00020400-0000-0000-C000-000000000046}=IDispatch&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;{00000000-0000-0000-C000-000000000046}=IUnknown&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;{0000000C-0000-0000-C000-000000000046}=IStream&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;{0C733A30-2A1C-11CE-ADE5-00AA0044773D}=ISequentialStream&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;We need to comment out the &lt;span style=&quot;font-family: courier;&quot;&gt;IStream&lt;/span&gt; and &lt;span style=&quot;font-family: courier;&quot;&gt;ISequentialStream&lt;/span&gt; lines to get a successful import. Once those 2 lines have semicolons inserted at their start we can try again.&lt;/div&gt;&lt;p&gt;Remove the emitted import unit SpeechLib_TLB.pas from the package still open in the IDE, then delete that unit from disk and close the package project.&lt;/p&gt;&lt;p&gt;Now you can go through the steps above again, but this time instead of selecting&amp;nbsp;&lt;i&gt;Install to New Package&lt;/i&gt;&amp;nbsp;you select&amp;nbsp;&lt;i&gt;Install to Existing Package&lt;/i&gt;. After pressing &lt;i&gt;Next&lt;/i&gt; you press Browse and locate the original DCLSAPI54.dpk project file, which by default will have been saved in the default Delphi projects folder (Embarcadero\Studio\Projects within your Documents folder tree).&lt;/p&gt;&lt;p&gt;This time the package will build and you will be told of the component wrappers now installed in the IDE:&lt;/p&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/AVvXsEhNS38M1TdCz7sERkk4ucBJo8wyaRcW9sHLv526zEsOKV1seplbdq5O2pxeGtVhMyUSQ_GzMCjYHux9-UeLrC85Xf5i4SFjHTHB4C8VH-3cr8288tf5ROCBkgVcyea8-5Mhqk3rYISQhFE/s365/SAPI_import_7.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;353&quot; data-original-width=&quot;365&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNS38M1TdCz7sERkk4ucBJo8wyaRcW9sHLv526zEsOKV1seplbdq5O2pxeGtVhMyUSQ_GzMCjYHux9-UeLrC85Xf5i4SFjHTHB4C8VH-3cr8288tf5ROCBkgVcyea8-5Mhqk3rYISQhFE/s16000/SAPI_import_7.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;If you want to import the SAPI type library from a RAD Studio Command Prompt you can run this command:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;tlibimp -P -Yh+ -Yr+ -HpsActiveX C:\WINDOWS\System32\Speech\Common\sapi.dll&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;Note that the SAPI 5.x sample applications from the 2002 conference paper have been updated and are available along with an updated import package at these URLs:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;a href=&quot;http://blong.com/Conferences/DCon2002/Speech/SAPI51/SpeechDemosXE7.7z&quot;&gt;RAD Studio XE7 versions&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;a href=&quot;http://blong.com/Conferences/DCon2002/Speech/SAPI51/SpeechDemos10.4.2.7z&quot;&gt;RAD Studio 10.4.2 versions&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/4917207648809329426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2021/04/sapi-microsoft-speech-api-problems-with.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4917207648809329426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4917207648809329426'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2021/04/sapi-microsoft-speech-api-problems-with.html' title='SAPI (Microsoft Speech API) problems with the IDE'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkkE7HuhKXih3_PkFeZAY_Nhs4L0qCvLdLmI8HVnkSdmn76e1rUw5Lkog_ADkpG__KjNT2xsybgfvpXdvXC8URNWkGop5dtknPY9G_bIgy7RtQlIzyAnVUBpFXOdDPLz_DMKR8Pc7paJI/s72-w640-h266-c/SAPI_import.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-852111942742721407</id><published>2020-10-20T11:20:00.002-07:00</published><updated>2020-10-21T01:27:02.314-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>Deleaker: memory / resource leak detection and identification</title><content type='html'>&lt;p&gt;As I&#39;ve made clear many times in conference talks I’m a big fan of &lt;a href=&quot;https://github.com/pleriche/FastMM4&quot; target=&quot;_blank&quot;&gt;FastMM4&lt;/a&gt;, the full version Delphi’s built-in memory manager (I haven’t yet tried out &lt;a href=&quot;https://github.com/pleriche/FastMM5&quot; target=&quot;_blank&quot;&gt;FastMM5&lt;/a&gt;, which is fully rewritten but now has either a GPL or a commercial license). FastMM4 is great for identifying memory leaks, memory corruption, interface misuse and so on, and locating the source of the problem via a call stack. However it is true that the business of working through the FastMM4 reports is somewhat manual – reports and call stacks are sent out via debug strings or log flies and then you have to pore over the details and work things backward to the source of the problem. It does the job, but takes a back seat once the details have been discovered.&lt;/p&gt;
&lt;p&gt;Some while back I got pointed in the direction of another leak detection tool, &lt;a href=&quot;https://www.deleaker.com/&quot; target=&quot;_blank&quot;&gt;Deleaker&lt;/a&gt; from &lt;a href=&quot;https://www.softanics.com/&quot; target=&quot;_blank&quot;&gt;Softanics&lt;/a&gt;, of which I hadn&#39;t heard at that point. It’s taken me a while to clear my desk sufficiently to check it out but I’m pleased to have done so, as it’s a very nice and helpful tool.&lt;/p&gt;
&lt;p&gt;I should mention up front that this is a commercial tool, like &lt;a href=&quot;https://github.com/pleriche/FastMM5&quot; target=&quot;_blank&quot;&gt;FastMM5&lt;/a&gt; (when not used with the GPL license) and unlike &lt;a href=&quot;https://github.com/pleriche/FastMM4&quot; target=&quot;_blank&quot;&gt;FastMM4&lt;/a&gt;, &lt;a href=&quot;https://bitbucket.org/shadow_cs/delphi-leakcheck/src/master/&quot; target=&quot;_blank&quot;&gt;Delphi LeakCheck&lt;/a&gt;, &lt;a href=&quot;http://v.mahon.free.fr/pro/freeware/memcheck/&quot; target=&quot;_blank&quot;&gt;MemCheck&lt;/a&gt; &lt;sup&gt;&lt;a name=&quot;Ref_1&quot;&gt;&lt;/a&gt;&lt;a href=&quot;#Footnote_1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; and &lt;a href=&quot;https://web.archive.org/web/20200128234431/edn.embarcadero.com/article/28344&quot; target=&quot;_blank&quot;&gt;TCondom&lt;/a&gt; &lt;sup&gt;&lt;a name=&quot;Ref_2&quot;&gt;&lt;/a&gt;&lt;a href=&quot;#Footnote_2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. It costs $99 for a home license and $399 for a single developer license.&lt;/p&gt;
&lt;p&gt;Some key points about Deleaker:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;It is not just a tool for EMBT development languages: it supports Delphi, C++Builder, Visual C++ and &lt;a href=&quot;https://www.qt.io/product/development-tools&quot; target=&quot;_blank&quot;&gt;Qt Creator&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;It’s not just a memory leak detector, but also supports resource leak detection for a pleasing array of resource types&lt;/li&gt;
  &lt;li&gt;It is not just a library, but offers a full UI experience, either integrated into the IDE (RAD Studio, Visual Studio, Qt Creator) or standalone, or even controlled through a command-line utility for use in Continuous Integration setups&lt;/li&gt;
  &lt;li&gt;It supports Win32 and Win64 targets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you and/or your development team happens to dabble in C++Builder or Visual C++ then this tool would be a common weapon to deploy against leaks of all sorts.&lt;/p&gt;
&lt;p&gt;The list of entity types that can be tracked looking for leaks is impressive:&lt;/p&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;ul&gt;
  &lt;li&gt;Memory blocks allocated by heap functions, virtual memory, OLE memory: &lt;code&gt;BSTR&lt;/code&gt;, &lt;code&gt;SAFEARRAY&lt;/code&gt;, etc.&lt;/li&gt;
  &lt;li&gt;GDI objects: &lt;code&gt;HBITMAP&lt;/code&gt;, &lt;code&gt;HDC&lt;/code&gt;, &lt;code&gt;HPEN&lt;/code&gt;, etc.&lt;/li&gt;
  &lt;li&gt;User32 objects: &lt;code&gt;HICON&lt;/code&gt;, &lt;code&gt;HCURSOR&lt;/code&gt;, etc.&lt;/li&gt;
  &lt;li&gt;Handles: file handles, events, mutexes, etc.&lt;/li&gt;
  &lt;li&gt;File views&lt;/li&gt;
  &lt;li&gt;Activation context cookies&lt;/li&gt;
  &lt;li&gt;Fibers&lt;/li&gt;
  &lt;li&gt;Critical sections&lt;/li&gt;
  &lt;li&gt;Environment strings&lt;/li&gt;
  &lt;li&gt;FLS (fiber-local storage) slots&lt;/li&gt;
  &lt;li&gt;TLS (thread-local storage) slots&lt;/li&gt;
  &lt;li&gt;Atoms&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The typical way a Delphi or C++Builder developer would use Deleaker is using the IDE integration – there is a Deleaker menu added between Run and Component in the main menu. This menu allows you to enable or disable Deleaker’s interest in your project, set some options via a dialog and display the Deleaker window (the UI is the same in the standalone tool as it is in the IDE integration). When not debugging the window looks like this (note that when using this from within RAD Studio this is a dockable window, so you can tuck it away in your preferred area of the IDE’s UI):&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiievq0FVNYcrHHKsOyzUPOV8_Vqg1hKjEPUS9eu83HFn-j830UCP3A_YpBNwFuRgjygnTGtm0HJnOP7VI-npfpUL38jWBkCOMiGZZVskGKQ7KfqupMYxWByVDtd_o2wRAN98pzXWUjTDQ/s867/Deleaker1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;442&quot; data-original-width=&quot;867&quot; height=&quot;326&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiievq0FVNYcrHHKsOyzUPOV8_Vqg1hKjEPUS9eu83HFn-j830UCP3A_YpBNwFuRgjygnTGtm0HJnOP7VI-npfpUL38jWBkCOMiGZZVskGKQ7KfqupMYxWByVDtd_o2wRAN98pzXWUjTDQ/w640-h326/Deleaker1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Here you get a flavour of what is on offer. You can see we have support for taking and comparing snapshots, which is the mechanism we use to identify leaks in the application. There is a button to invoke the resource usage graph, which allows you to see a dynamic representation of resource consumption over the last 60 seconds.&lt;/p&gt;
&lt;p&gt;Let’s do a simple test on a simple memory leak by some code like this:&lt;/p&gt;
&lt;pre&gt;procedure TForm1.Button1Click(Sender: TObject);
begin
  var P: PByte;
  GetMem(P, 1024 * 1024);
end;&lt;/pre&gt;
&lt;p&gt;Running this up and battering Button1 shows this in the resource graph. The initial slope up was the application startup and the addition rise was the memory allocations caused by the button presses.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBNT5eTWkbKn-qh_HuuRWLYST5s4ek5tt521FXcAe2VWbTwqXhBpkoIETou9QOghWU0UY0UU0qesMOBElD9GRt1WDo0MF9cg3_1s7hTVHH0V8uDTw6To6sHEnJ9xi9XJs6aT0CZeXup3o/s867/Deleaker2.png&quot; style=&quot;clear: left; display: block; float: left; margin-bottom: 1em; margin-right: 1em; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;495&quot; data-original-width=&quot;867&quot; height=&quot;364&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBNT5eTWkbKn-qh_HuuRWLYST5s4ek5tt521FXcAe2VWbTwqXhBpkoIETou9QOghWU0UY0UU0qesMOBElD9GRt1WDo0MF9cg3_1s7hTVHH0V8uDTw6To6sHEnJ9xi9XJs6aT0CZeXup3o/w640-h364/Deleaker2.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;OK, that gives a view of consumption and in a real application potentially indicates an issue, so now we can use snapshots to look for a potential problem.&lt;/p&gt;
&lt;p&gt;The idea is to take an initial snapshot (using the Take Snapshot button) as a baseline, then shortly thereafter take another snapshot and compare the two. You can then see all the allocations that have not been deallocated and look for any you weren’t expecting.&lt;/p&gt;
&lt;p&gt;When you press Take Snapshot Deleaker briefly freezes the information and collates a whole bunch of information it requires. This includes building up call stacks for each allocation that has not been freed. Deleaker understands about the symbol information format used by Delphi and C++Builder. But additionally, since it also operates within Visual Studio it understands Microsoft’s symbol format and has support for using the Microsoft Symbol Servers. This means that where necessary call stacks will include detailed information about Microsoft OS DLLs.&lt;/p&gt;
&lt;p&gt;This animated GIF shows Deleaker acquiring its data for the first snapshot.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6YdeZ4U6LvVDJogVKIL7VfvCx9GgwUzK_IMM3wJuUAmiRUtB7a2k7AZ8QJlF1aQXdFmq6CnGd6ys9l0udxo-nY885cprz8qEwazlwz6fJMxQ-YqcjaQ5NhuEi0O4ZF2BWH2d1VkTiyPM/s920/DeleakerSnapshot.gif&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;664&quot; data-original-width=&quot;920&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6YdeZ4U6LvVDJogVKIL7VfvCx9GgwUzK_IMM3wJuUAmiRUtB7a2k7AZ8QJlF1aQXdFmq6CnGd6ys9l0udxo-nY885cprz8qEwazlwz6fJMxQ-YqcjaQ5NhuEi0O4ZF2BWH2d1VkTiyPM/s16000/DeleakerSnapshot.gif&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Note that the symbols shown towards the bottom of the screen at the end of the animation are not representative of what you will actually see. Current versions of Deleaker will &quot;demangle&quot; these &quot;mangled&quot; symbol names to provide a more readable stack trace.&lt;/p&gt;&lt;p&gt;After the first snapshot I press Button1 and then take a second snapshot. Now I have Snapshot #1 and Snapshot #2. The Compare with… button can then instigate the comparison between the current snapshot and another one:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjj6_wS2RCDZtJqxX9-5g8i9iQxoEb2KEgeUS__A6HMhhpMTqZCC5VSwhQ7nTklhAcsgL05vQbPByblO8nYD3XQQ-1ef9YbgZyxOu5orbVVonYiNG-soYERUL8X6XdvTyUR4G-fVxbsHrc/s866/Deleaker3.png&quot; style=&quot;clear: left; display: block; float: left; margin-bottom: 1em; margin-right: 1em; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;336&quot; data-original-width=&quot;866&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjj6_wS2RCDZtJqxX9-5g8i9iQxoEb2KEgeUS__A6HMhhpMTqZCC5VSwhQ7nTklhAcsgL05vQbPByblO8nYD3XQQ-1ef9YbgZyxOu5orbVVonYiNG-soYERUL8X6XdvTyUR4G-fVxbsHrc/s16000/Deleaker3.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;This now shows the differences between the two.&lt;/p&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/AVvXsEjYSkFVXzfiAYewrXOYBAL1PTCnB06xaTgcdX7MUif9IUiiA6NipDzwZ2bhUsJzWA4WYb0znMn8FkWSR84mrLbSY-y8utyxb_IKb5GttHwg1gn2xop6insRAPAClh_1tR6XgJnLBTjyh4w/s888/Deleaker4.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;614&quot; data-original-width=&quot;888&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYSkFVXzfiAYewrXOYBAL1PTCnB06xaTgcdX7MUif9IUiiA6NipDzwZ2bhUsJzWA4WYb0znMn8FkWSR84mrLbSY-y8utyxb_IKb5GttHwg1gn2xop6insRAPAClh_1tR6XgJnLBTjyh4w/s16000/Deleaker4.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;Here we see a single unfreed allocation of Heap memory of size 1048576 (which is 1024 x 1024) and Deleaker shows the source file and line number of the allocation as well as the call stack leading up the allocation.&lt;/div&gt;
&lt;p&gt;Double-clicking on any entry in the call stack (either your code or RTL/VCL code) will take you to the relevant location in the relevant source file (or you can use the Show Source Code button).&lt;/p&gt;
&lt;p&gt;In leaks coming just out of your own code the fact that MS symbols are available is neither here nor there. By default Deleaker doesn’t even trouble you with them in the call stack: the Show Full Stack checkbox is unchecked above. However if you need the extra detail then you can enable that option. Here is an unfreed memory allocation coming from a callback routine being invoked by the Windows API &lt;code&gt;EnumWindows&lt;/code&gt; with full stack shown:&lt;/p&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/AVvXsEgurGCNZ4kOgg1Re1kw13zFUQ-LEA1LrEB9m_Y9UPV7aUgoZtS5P3JErOEKROBDU3HJiJnvqZ7cliUPRKN3VmOeEg1EA6nTIk-03lqlKIuRNphy7V4AlKQ-5_6r75wPu6pEETO3Zd2qpCE/s934/Deleaker5.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;934&quot; data-original-width=&quot;808&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgurGCNZ4kOgg1Re1kw13zFUQ-LEA1LrEB9m_Y9UPV7aUgoZtS5P3JErOEKROBDU3HJiJnvqZ7cliUPRKN3VmOeEg1EA6nTIk-03lqlKIuRNphy7V4AlKQ-5_6r75wPu6pEETO3Zd2qpCE/s16000/Deleaker5.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;This time I’ll leak a Delphi object: a &lt;code&gt;TList&lt;/code&gt;. If used as before the Allocations list shows that there is an unfreed allocation of a Delphi object.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&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/AVvXsEhkDgPnE6RnQwLiJbORs1F3eMOkDrl8GnjPTRJNn2t7n5sDlbXmeLpl_nMUgS_nxZdKy-SR-sV2WtEc95NC8RR8OHqyIfRlYwjhJCDH0dudG9Vjp-PG_PAGYWxUa2ewuzfZDnt1g9bupsY/s939/Deleaker6.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;551&quot; data-original-width=&quot;939&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkDgPnE6RnQwLiJbORs1F3eMOkDrl8GnjPTRJNn2t7n5sDlbXmeLpl_nMUgS_nxZdKy-SR-sV2WtEc95NC8RR8OHqyIfRlYwjhJCDH0dudG9Vjp-PG_PAGYWxUa2ewuzfZDnt1g9bupsY/s16000/Deleaker6.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;However if we go to the Delphi Objects view we can see that the unfreed item is confirmed as a &lt;code&gt;TList&lt;/code&gt;:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&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/AVvXsEgLQACCR193AxhaJDY-ppM77aUCyCHSBlOXIiqDnqm7JDwXQp2hl3E9rJMEZ7Hq87XclUEyG1RJ5izpaNGh-_tO2Y33xGi1eouBfkCyP-7AbX5P1WvO3JSCRSPXNX4G3RKSJZXSBgimHuk/s830/Deleaker7.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;551&quot; data-original-width=&quot;830&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLQACCR193AxhaJDY-ppM77aUCyCHSBlOXIiqDnqm7JDwXQp2hl3E9rJMEZ7Hq87XclUEyG1RJ5izpaNGh-_tO2Y33xGi1eouBfkCyP-7AbX5P1WvO3JSCRSPXNX4G3RKSJZXSBgimHuk/s16000/Deleaker7.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;Of course if a more complex object is leaked, such as a component like a &lt;code&gt;TButton&lt;/code&gt;, which itself creates a number of objects for its own purposes, then the list of unfreed objects becomes larger, but all these have the same call stack:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&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/AVvXsEhmXXSf4Z-UZk3aG-qqVCVeA9aHDTaWHk5Il9Jgn6qC8-jOl4AiACm4gGFmniIe422BBitfVbGFp3NIG0H50ztOpXLggO7PQBdyBtpnMWejGFypI5a5ACpYxM3YngewiyEHGZfOurS4EBY/s689/Deleaker8.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;613&quot; data-original-width=&quot;689&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmXXSf4Z-UZk3aG-qqVCVeA9aHDTaWHk5Il9Jgn6qC8-jOl4AiACm4gGFmniIe422BBitfVbGFp3NIG0H50ztOpXLggO7PQBdyBtpnMWejGFypI5a5ACpYxM3YngewiyEHGZfOurS4EBY/s16000/Deleaker8.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;So far we’ve just looked at heap allocations, be they of basic memory or of object instances. One of the compelling features of Deleaker is that it also tracks various Windows resources not tracked by many other utilities (see list from earlier). Here, for example is a GDI handle leak:&lt;/div&gt;
&lt;pre&gt;const
  pattern: array[0..3] of cardinal = (10, 1, 1, 1);
var
  lb: TLogBrush;
  pen, oldpen: HPEN;
begin
  lb.lbStyle := BS_SOLID;
  lb.lbColor := RGB(255, 0, 0);
  pen := ExtCreatePen(
    PS_COSMETIC or PS_USERSTYLE, 1, lb, length(pattern), @pattern);
  if pen &amp;lt;&amp;gt; 0 then
    try
      oldpen := SelectObject(Canvas.Handle, pen);
      try
        Canvas.MoveTo(0, 0); Canvas.LineTo(ClientWidth, ClientHeight);
      finally
        SelectObject(Canvas.Handle, oldpen);
      End;
    finally
      // DeleteObject(pen); // Oops! We forgot to deallocate the handle!
    end;
end;&lt;/pre&gt;
&lt;p&gt;In this case the snapshot comparison shows up 3 unfreed allocations for a block of heap memory and two &lt;code&gt;HPEN&lt;/code&gt;s (pen handles) with the Leak type set to &amp;lt;All Leaks&amp;gt;. Note that the Leak type dropdown could be set to GDI objects to focus in on the&amp;nbsp;&lt;code&gt;HPEN&lt;/code&gt;s.&lt;/p&gt;&lt;p&gt;Looking at the call stacks for each I can readily see the one I forced:&lt;/p&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/AVvXsEgjVkDWhXReSyVpHjgndBvFDCHsBXGFIM36Syw38cqaZXY3JJ-OrEYFsVewBaXMPl0wW4f0Xhil9KKQJ0kJ5xOTqJJgPlHHwS8WWsNntdQRMJVHLvq8DaJ_yba6jd-d0rxYSLMfGqNolwo/s616/Deleaker9.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;613&quot; data-original-width=&quot;616&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjVkDWhXReSyVpHjgndBvFDCHsBXGFIM36Syw38cqaZXY3JJ-OrEYFsVewBaXMPl0wW4f0Xhil9KKQJ0kJ5xOTqJJgPlHHwS8WWsNntdQRMJVHLvq8DaJ_yba6jd-d0rxYSLMfGqNolwo/s16000/Deleaker9.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;Incidentally the resource usage graph will track whatever resource type you wish. Here it is showing my test app consuming more and more &lt;code&gt;HPEN&lt;/code&gt;s as I keep pressing my button.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1OVmQREHWLPeN5VK19DYCRueiCOuTcFIDbC33qN14wvriIIvhpfdTHvXL9DTPVqhv9sI98FhmACpgR_8xriOwz12YmcSSYuMfceUez0BZ3DkofLYbWZ9ReHe28TQP6yIVt4tapmVyiWw/s867/Deleaker10.png&quot; style=&quot;clear: left; display: block; float: left; margin-bottom: 1em; margin-right: 1em; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;495&quot; data-original-width=&quot;867&quot; height=&quot;364&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1OVmQREHWLPeN5VK19DYCRueiCOuTcFIDbC33qN14wvriIIvhpfdTHvXL9DTPVqhv9sI98FhmACpgR_8xriOwz12YmcSSYuMfceUez0BZ3DkofLYbWZ9ReHe28TQP6yIVt4tapmVyiWw/w640-h364/Deleaker10.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;During my experimenting with Deleaker I have bumped into several bugs and shortcomings and have passed them all along to Artem from Softanics, who is usually quick to respond. One issue had already been fixed by the time I reported it and another was fixed quite promptly. A couple of shortcomings (Delphi mangled symbol names not demangled, and RTL/VCL source files not being automatically located) were also addressed in version 2020.27.0.0. This responsive experience was reassuring.&lt;/p&gt;
&lt;p&gt;I like Deleaker – the IDE integration of the UI (especially the call stack entry support for double-clicking to see the source code) makes it much more straightforward to work with that FastMM4. But of course for all that convenience there is a price tag.&lt;/p&gt;
&lt;p&gt;Whether you can justify spending out for the sake of convenience will be a personal decision, but if you can I think you will be happy you did. Additionally, if you fear you are leaking resource handles and are having trouble tracking down how this is happening then making use of this sort of tool will expedite the resolution of such issues.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a name=&quot;Footnote_1&quot;&gt;&lt;/a&gt;&lt;a href=&quot;#Ref_1&quot;&gt;1&lt;/a&gt;. OK, that hasn’t been updated in some years...&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;Footnote_2&quot;&gt;&lt;/a&gt;&lt;a href=&quot;#Ref_2&quot;&gt;2&lt;/a&gt;. Yeah, this one is also somewhat stale, and required a cached Google page as the EDN page it was on is no longer available&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/852111942742721407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2020/10/deleaker-memory-resource-leak-detection.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/852111942742721407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/852111942742721407'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2020/10/deleaker-memory-resource-leak-detection.html' title='Deleaker: memory / resource leak detection and identification'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiievq0FVNYcrHHKsOyzUPOV8_Vqg1hKjEPUS9eu83HFn-j830UCP3A_YpBNwFuRgjygnTGtm0HJnOP7VI-npfpUL38jWBkCOMiGZZVskGKQ7KfqupMYxWByVDtd_o2wRAN98pzXWUjTDQ/s72-w640-h326-c/Deleaker1.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-8526300883776777046</id><published>2020-09-06T08:33:00.005-07:00</published><updated>2021-04-08T11:23:21.200-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>Delphi and the WinRT API</title><content type='html'>&lt;h2 style=&quot;text-align: left;&quot;&gt;WinRT&lt;/h2&gt;
&lt;p&gt;The WinRT (Windows Runtime) API was introduced with Windows 8, although it’s fair to say that most of us have tried our level best to forget that particular Windows release and pretend it never happened. Anyway, Microsoft has been trying to convince us that new Windows APIs will be introduced in the WinRT API and what we normally refer to as the Windows API might well remain as it is. We’ll see how true that becomes. The WinRT API reference can be found &lt;a href=&quot;https://docs.microsoft.com/en-us/uwp/api/?view=winrt-19041&quot; target=&quot;_blank&quot;&gt;documented here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The nice thing about WinRT is that it is not another step on the .NET journey; indeed it is nothing to do with .NET whatsoever. WinRT is implemented as native code and it is made available to whatever language wishes to consume it by &lt;i&gt;language projections&lt;/i&gt;. Microsoft offers a C# language projection to consume it in .NET but it also offers a native C++ language projection (C++/WinRT).&lt;/p&gt;
&lt;p&gt;Each WinRT class implements various interfaces to offer up methods and properties to call. There may also be static methods (i.e. class methods) and factory methods through which you can create an instance of the class. The Microsoft language projections make all the methods implemented through all the supported interfaces directly available once you create an instance of a WinRT class.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot;&gt;WinRT metadata&lt;/h2&gt;
&lt;p&gt;Anyone else can make their own language projections by analysing the API metadata (which are available in .winmd files in the C:\Windows\System32\WinMetadata folder). Metadata files are rather like COM type libraries in that they describe all the WinRT classes and methods etc., but they are actually files that share the same format as Win32 executables and .NET assemblies: PE files. You can find detailed information on these files &lt;a href=&quot;https://docs.microsoft.com/en-us/uwp/winrt-cref/winmd-files&quot; target=&quot;_blank&quot;&gt;from Microsoft here&lt;/a&gt;. Microsoft’s C++ .winmd file parser is open-sourced and &lt;a href=&quot;https://github.com/microsoft/winmd&quot; target=&quot;_blank&quot;&gt;available on github&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;WinRT and Delphi&lt;/h2&gt;
&lt;p&gt;Embarcadero folks started looking at how to consume the WinRT API back in 2011 and Thom Gerdes wrote a few posts on how got on. He talks about these metadata files in &lt;a href=&quot;https://web.archive.org/web/20191124015654/http://www.thomgerdes.com/2011/12/winrt-internals-winmd-files.html&quot; target=&quot;_blank&quot;&gt;this old post available on the Wayback Machine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, do we have a Delphi language projection? Well, kinda... We have import units that pull in a good chunk of the WinRT API, but things aren’t &lt;i&gt;quite&lt;/i&gt; as transparent and trivial to use as they are in C++and C#. However, depending on how persistent we are we can get results. Indeed there are some uses of the WinRT API in the Delphi / C++Builder RTL; it is used for Windows desktop notifications and for share contracts.&lt;/p&gt;
&lt;p&gt;This post looks into how we might use the WinRT API directly to perform a simple task, namely to trigger a Windows notification message. This might seem an odd thing to do, given the RTL already covers this quite nicely in the &lt;code&gt;&lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/en/System.Notification.TNotificationCenter&quot; target=&quot;_blank&quot;&gt;TNotificationCenter&lt;/a&gt;&lt;/code&gt; class but it serves as a simple, visual example.&lt;/p&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;
&lt;p&gt;If you want you can also jump right to a sample from Marco Cantu that does the same thing, but that sample has more code in that somewhat camouflages the detail of what is required for the job. Marco’s code is &lt;a href=&quot;https://github.com/marcocantu/DelphiSessions/tree/master/Win10Session/WinRTDirect&quot; target=&quot;_blank&quot;&gt;on github&lt;/a&gt; and is mentioned a bit in the post &lt;a href=&quot;https://community.idera.com/developer-tools/b/blog/posts/a-tale-of-3-apis-vcl-integration-with-winapi-com-shellapi-winrt&quot; target=&quot;_blank&quot;&gt;A tale of 3 APIs: VCL integration with WinAPI, COM &amp;amp; ShellAPI, WinRT&lt;/a&gt;, which itself is a post summarising &lt;a href=&quot;https://community.idera.com/developer-tools/b/blog/posts/windows-10-modernize-webinar-series#h905sk1wiuao2i76p2d19r7ph2sq0gee&quot; target=&quot;_blank&quot;&gt;a webinar of the same title available for replay&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The WinRT import units were added to the RTL in RAD Studio 10 Seattle, so far as I can tell. You can find them in this subfolder of the installation folder: source\rtl\win\winrt. These were &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/What_Was_New_in_Berlin#Bluetooth_LE_and_Beacon_Support_on_Windows_10&quot; target=&quot;_blank&quot;&gt;extended in 10.1 Berlin&lt;/a&gt;, and &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/Rio/en/What%27s_New#WinRT_API_Updates&quot; target=&quot;_blank&quot;&gt;extended again in 10.3 Rio&lt;/a&gt;. In the 10.2 Tokyo timeframe Al Mannarino wrote &lt;a href=&quot;https://community.idera.com/developer-tools/b/blog/posts/rad-studio-10-2-windows-10-vcl-uwp-winrt-support&quot; target=&quot;_blank&quot;&gt;a post on using the WinRT support&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;WinRT and toast notifications in Delphi&lt;/h2&gt;
&lt;p&gt;To create a toast requires the toast content to be represented in XML. Something like this will do the trick:&lt;/p&gt;
&lt;pre&gt;var LToastXml := &#39;&amp;lt;toast duration=&quot;short&quot;&amp;gt;&#39; +
                   &#39;&amp;lt;visual&amp;gt;&#39; +
                     &#39;&amp;lt;binding template=&quot;ToastText02&quot;&amp;gt;&#39; +
                       &#39;&amp;lt;text id=&quot;1&quot;&amp;gt;Windows 10 Notification&amp;lt;/text&amp;gt;&#39; +
                       &#39;&amp;lt;text id=&quot;2&quot;&amp;gt;RAD Studio 10.4 Sydney Update 1&amp;lt;/text&amp;gt;&#39; +
                     &#39;&amp;lt;/binding&amp;gt;&#39; +
                   &#39;&amp;lt;/visual&amp;gt;&#39; +
                 &#39;&amp;lt;/toast&amp;gt;&#39;;
&lt;/pre&gt;
&lt;p&gt;To pass this into a toast notification we need to load it into a &lt;code&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/uwp/api/windows.data.xml.dom.xmldocument?view=winrt-19041&quot; target=&quot;_blank&quot;&gt;Windows.Data.Xml.Dom.XmlDocument&lt;/a&gt;&lt;/code&gt; class. In the Winapi.DataRT.pas unit there is a representation of this class in the proxy class &lt;code&gt;TXml_Dom_XmlDocument&lt;/code&gt;, which looks like this:&lt;/p&gt;
&lt;pre&gt;  // Windows.Data.Xml.Dom.XmlDocument
  // WinRT Only
  // WhiteListed
  // Implements: Windows.Data.Xml.Dom.IXmlDocument
  // Implements: Windows.Data.Xml.Dom.IXmlNode
  // Implements: Windows.Data.Xml.Dom.IXmlNodeSerializer
  // Implements: Windows.Data.Xml.Dom.IXmlNodeSelector
  // Implements: Windows.Data.Xml.Dom.IXmlDocumentIO
  // Implements: Windows.Data.Xml.Dom.IXmlDocumentIO2
  // Statics: &quot;Windows.Data.Xml.Dom.IXmlDocumentStatics&quot;
  // Instantiable: &quot;Xml_Dom_IXmlDocument&quot;
  TXml_Dom_XmlDocument = class(TWinRTGenericImportSI&amp;lt;Xml_Dom_IXmlDocumentStatics, Xml_Dom_IXmlDocument&amp;gt;)
  public
    // -&amp;gt; Xml_Dom_IXmlDocumentStatics
    class function LoadFromUriAsync(uri: IUriRuntimeClass): IAsyncOperation_1__Xml_Dom_IXmlDocument; overload; static; inline;
    class function LoadFromUriAsync(uri: IUriRuntimeClass;
      loadSettings: Xml_Dom_IXmlLoadSettings): IAsyncOperation_1__Xml_Dom_IXmlDocument; overload; static; inline;
    class function LoadFromFileAsync(&amp;amp;file: IStorageFile): IAsyncOperation_1__Xml_Dom_IXmlDocument; overload; static; inline;
    class function LoadFromFileAsync(&amp;amp;file: IStorageFile;
      loadSettings: Xml_Dom_IXmlLoadSettings): IAsyncOperation_1__Xml_Dom_IXmlDocument; overload; static; inline;
  end;
&lt;/pre&gt;
&lt;p&gt;There is a static &lt;code&gt;Create&lt;/code&gt; method available in a proxy class such as this, which is expected to create the corresponding WinRT class and return an interface reference to the instantiable class &lt;code&gt;Xml_Dom_IXmlDocument&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Disappointingly, while this works with many WinRT proxy classes it does not work with this one. This is because the &lt;code&gt;Xml_Dom_IXmlDocument&lt;/code&gt; interface, which is in the WinAPI.CommonTypes.pas unit rather than the Winapi.DataRT.pas unit has lost an important attribute. It should have an attribute defined like this:&lt;/p&gt;
&lt;pre&gt;[WinRTClassNameAttribute(SXml_Dom_XmlDocument)]
&lt;/pre&gt;
&lt;p&gt;where &lt;code&gt;SXml_Doc_XmlDocument&lt;/code&gt; is defined like this in Winapi.CommonNames.pas:&lt;/p&gt;
&lt;pre&gt;SXml_Dom_XmlDocument = &#39;Windows.Data.Xml.Dom.XmlDocument&#39;;
&lt;/pre&gt;
&lt;p&gt;But alas all the interfaces in Winapi.CommonTypes seem to have lost attributes like this. As a consequence a function like this one does not work at runtime:&lt;/p&gt;
&lt;pre&gt;unit XMLHelper;

interface

uses
  Winapi.CommonTypes;

function GetXmlDocument: Xml_Dom_IXmlDocument;

implementation

uses
  Winapi.DataRT;

function GetXmlDocument: Xml_Dom_IXmlDocument;
begin
  // This fails because Xml_Dom_IXmlDocument in Winapi.CommonTypes does not have this attribute
  // as the other interfaces involved in XmlDocument from Winapi.DataRT do:
  // [WinRTClassNameAttribute(SXml_Dom_XmlDocument)]
  // Might work in 10.5...? If we cross our fingers...
  Result := TXml_Dom_XmlDocument.Create
end;

end.
&lt;/pre&gt;
&lt;p&gt;It triggers an exception due to the lack of attribute, as the relevant code therefore does not know which WinRT class to instantiate.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYdm9FTaN9uSWvo_Xsaz44bxPenge6PBpfDocQjLM55LIfBGZXX_Y7nKJXJNmtyGoJriW-Lgx_Gs6ZE2ULm5qYEp9RnNq15tdJYj2e9FBAUcx-CWMfhd3swHAaI_KZhMhwxONE5Z8QEc4/s0/WinRT_Error.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;156&quot; data-original-width=&quot;599&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYdm9FTaN9uSWvo_Xsaz44bxPenge6PBpfDocQjLM55LIfBGZXX_Y7nKJXJNmtyGoJriW-Lgx_Gs6ZE2ULm5qYEp9RnNq15tdJYj2e9FBAUcx-CWMfhd3swHAaI_KZhMhwxONE5Z8QEc4/s0/WinRT_Error.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;By the way, I have made enquiries and I am reliably informed that this issue is known within Embarcadero and is recorded in an internal JIRA.&lt;/p&gt;
&lt;p&gt;All that notwithstanding, it turns out that we can do what that proxy class wanted to do for ourselves, manually filling in the missing information. Here’s an alternative implementation of the same function:&lt;/p&gt;
&lt;pre&gt;unit XMLHelper;

interface

uses
  Winapi.CommonTypes;

function GetXmlDocument: Xml_Dom_IXmlDocument;

implementation

uses
  System.Win.WinRT,
  Winapi.WinRT,
  Winapi.CommonNames;

function GetXmlDocument: Xml_Dom_IXmlDocument;
begin
  var LWinRTClassName := TWindowsString.Create(SXml_Dom_XmlDocument);
  var LWinRTClassNameHString: HString := LWinRTClassName;
  var LXmlDocumentInsp := TWinRTImportHelper.CreateInstance(TypeInfo(Xml_Dom_IXmlDocument), LWinRTClassNameHString);
  Result := LXmlDocumentInsp as Xml_Dom_IXmlDocument;
end;

end.&lt;/pre&gt;
&lt;p&gt;This code takes the aforementioned WinRT class name and creates a &lt;code&gt;HSTRING&lt;/code&gt; version of it. &lt;code&gt;HSTRING&lt;/code&gt; is a string handle and is the string type of choice in the WinRT API (&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/winrt/hstring&quot; target=&quot;_blank&quot;&gt;documentation available here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Some RTL helper can take the type information for the target instantiable interface along with the WinRT class name and do the ‘magic’ required to create the WinRT object instance and return us an &lt;code&gt;IInspectable&lt;/code&gt; interface reference to it. This interface reference will gladly offer up the sought &lt;code&gt;Xml_Dom_IXmlDocument&lt;/code&gt; interface when asked.&lt;/p&gt;
&lt;p&gt;If we wanted to do the WinRT object instantiation manually, using Windows native routines then we can swap out the RTL helper for a WinRT API primitive &lt;code&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/roapi/nf-roapi-roactivateinstance&quot; target=&quot;_blank&quot;&gt;RoActivateInstance&lt;/a&gt;&lt;/code&gt;. As you can see it actually slightly reduces the required typing:&lt;/p&gt;
&lt;pre&gt;function GetXmlDocument: Xml_Dom_IXmlDocument;
begin
  var LWinRTClassName := TWindowsString.Create(SXml_Dom_XmlDocument);
  var LXmlDocumentInsp: IInspectable;
  RoActivateInstance(LWinRTClassName, LXmlDocumentInsp);
  Result := LXmlDocumentInsp as Xml_Dom_IXmlDocument;
end;
&lt;/pre&gt;
&lt;p&gt;OK, so now we have a couple of options for instantiating a WinRT XML document and the helper can be called:&lt;/p&gt;
&lt;pre&gt;var LXmlDocument := GetXmlDocument;&lt;/pre&gt;
&lt;p&gt;In addition to the XML defining the toast notification we also need to use the &lt;code&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotificationmanager?view=winrt-19041&quot; target=&quot;_blank&quot;&gt;ToastNotificationManager&lt;/a&gt;&lt;/code&gt; to create a &lt;code&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotifier?view=winrt-19041&quot; target=&quot;_blank&quot;&gt;ToastNotifier&lt;/a&gt;&lt;/code&gt; object via which we will raise the toast notification. We maybe want to react to the user clicking the toast notification so we might want an event handler involved as well.&lt;/p&gt;
&lt;pre&gt;uses
  System.Hash,
  System.Win.WinRT,
  Winapi.UI.Notifications,
...
const
  AppId = &#39;Blong.WinRT.&#39;;

function GetAppUserModelID: string;
begin
  Result := AppID + THashBobJenkins.GetHashString(ParamStr(0))
end;
...
  var LWSAppID := TWindowsString.Create(GetAppUserModelID);
  var LToastNotifier := TToastNotificationManager.Statics.CreateToastNotifier(LWSAppID);
  DoToast(LXmlDocument, LToastXml, LToastNotifier, OnToastActivated);
...
procedure TfrmMain.OnToastActivated(Sender: IToastNotification; const Args: IInspectable);
begin
  ShowMessage(&#39;Hello from Delphi!&#39;);
end;&lt;/pre&gt;
&lt;p&gt;That sets us up passing everything into the &lt;code&gt;DoToast&lt;/code&gt; routine. It looks like this:&lt;/p&gt;
&lt;pre&gt;procedure DoToast(const XmlDoc: Xml_Dom_IXmlDocument; const ToastXML: string;
  const ToastNotifier: IToastNotifier; ActivatedEventHandler: TToastActivatedEvent);
begin
  (XmlDoc as Xml_Dom_IXmlDocumentIO).LoadXml(TWindowsString.Create(ToastXml));
  // If we want to view the XML we can do this:
  //var LWSXML := (XmlDoc as Xml_Dom_IXmlNodeSerializer).GetXml;
  //var LXML := TWindowsString.HStringToString(LWSXML);
  var LToastNotification := TToastNotification.Factory.CreateToastNotification(XmlDoc);
  var LDelegateActivated := TToastActivated.Create(ActivatedEventHandler);
  LToastNotification.add_Activated(LDelegateActivated);
  ToastNotifier.Show(LToastNotification);
end;&lt;/pre&gt;
&lt;p&gt;The first statement loads in the XML to the XML document. You’ll notice that since we are working from an interface reference, then in order to call other methods in the WinRT class we have to use the relevant interface reference type that defines the methods we wish to use. The XML document is then passed along while creating a &lt;code&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification?view=winrt-19041&quot; target=&quot;_blank&quot;&gt;ToastNotification&lt;/a&gt;&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;The passed in event handler method is handed to a new delegate object that is given to the &lt;code&gt;ToastNotification&lt;/code&gt; as a handler for the &lt;code&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification.activated?view=winrt-19041&quot; target=&quot;_blank&quot;&gt;Activated&lt;/a&gt;&lt;/code&gt; event. Finally the &lt;code&gt;ToastNotifier&lt;/code&gt; is used to display the notification.&lt;/p&gt;
&lt;p&gt;The only thing left not filled in from what we’ve seen so far is the delegate class, which looks like this:&lt;/p&gt;
&lt;pre&gt;type
  TToastActivatedEvent = procedure(Sender: IToastNotification; const Args: IInspectable) of object;

  // Here we have 2 interfaces implemented for the delegate
  TToastActivated = class(TInspectableObject,
    TypedEventHandler_2__IToastNotification__IInspectable,
    TypedEventHandler_2__IToastNotification__IInspectable_Delegate_Base)
  private
    FToastActivated: TToastActivatedEvent;
  public
    constructor Create(EventHandler: TToastActivatedEvent);
    procedure Invoke(Sender: IToastNotification; Args: IInspectable); safecall;
  end;
...
constructor TToastActivated.Create(EventHandler: TToastActivatedEvent);
begin
  inherited Create;
  FToastActivated := EventHandler;
end;

procedure TToastActivated.Invoke(Sender: IToastNotification; Args: IInspectable);
begin
  if Assigned(FToastActivated) then
    FToastActivated(Sender, Args)
end;&lt;/pre&gt;
&lt;p&gt;Notice the dual interfaces implemented in this delegate class. This is &#39;a thing&#39; that you have to do with Delphi interfaces that represent WinRT instantiated template interface types. The interface type that describes itself as the base type has the IID that you need to be bringing in for the delegate to work, but the other type (inherited from the base one) defines the method(s) you need to implement...&lt;/p&gt;
&lt;p&gt;If you run this sort of code you do indeed get a desktop notification sweeping in from the bottom right edge of the screen:&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ2Z0iTx4EUXzfWFwwh34oDmaRy_45stolbzpvaO962Z68vcJ-pts_uylSkT2pU7VX_Mpb1T-7BgmttSXlvt_s4VdwCCYtJFl8PKc1gVFyyVpgp1VFp8GbmjoMCrAW0Rm4rc0DyFnS2ys/s0/WinRT_Toast_1.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;65&quot; data-original-width=&quot;291&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ2Z0iTx4EUXzfWFwwh34oDmaRy_45stolbzpvaO962Z68vcJ-pts_uylSkT2pU7VX_Mpb1T-7BgmttSXlvt_s4VdwCCYtJFl8PKc1gVFyyVpgp1VFp8GbmjoMCrAW0Rm4rc0DyFnS2ys/s0/WinRT_Toast_1.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Hmm, but something is missing….. The general look of these notifications is that, at the very least, they show the application icon. Where is it?&lt;/p&gt;
&lt;p&gt;Well, there is a requirement that must be met in order to get this to appear as discussed &lt;a href=&quot;https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/hh802762(v=vs.85)#instructions&quot; target=&quot;_blank&quot;&gt;in this&lt;/a&gt; – you need to create a shortcut (as in a .lnk file). This shortcut file must have been set up with an Application User Model ID (&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/shell/appids&quot; target=&quot;_blank&quot;&gt;more information here&lt;/a&gt;) assigned, which is the app-specific hashed string returned by the &lt;code&gt;GetAppKey&lt;/code&gt; function above. This is all illustrated with some C++ code in this Microsoft page, &lt;a href=&quot;https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/hh802762(v=vs.85)&quot; target=&quot;_blank&quot;&gt;How to enable desktop toast notifications through an AppUserModelID&lt;/a&gt;. If we implement a routine to ensure a suitable shortcut exists (code below), called on app start, then the notification does manage to pick up the app icon.&lt;/p&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB509eqTwhbt1_5GDRDDHTj4tP8dLf6KsZmsDjB1VmI3I43o8F4eUDh0yKE8BegSPLBwA4nPEvHiNMwOkIcgPBnRPivJC7_svsEVGZ5JnisKYKzFA4XrI-r6D0g6-X934FI_5xYORY82E/s0/WinRT_Toast_2.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;65&quot; data-original-width=&quot;291&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB509eqTwhbt1_5GDRDDHTj4tP8dLf6KsZmsDjB1VmI3I43o8F4eUDh0yKE8BegSPLBwA4nPEvHiNMwOkIcgPBnRPivJC7_svsEVGZ5JnisKYKzFA4XrI-r6D0g6-X934FI_5xYORY82E/s0/WinRT_Toast_2.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;pre&gt;uses
  System.SysUtils,
  System.Hash,
  Winapi.Windows,
  Winapi.ShlObj,
  Winapi.ActiveX,
  Winapi.KnownFolders,
  Winapi.PropKey,
  Winapi.PropSys;

const
  AppId = &#39;Blong.WinRT.&#39;;

function GetAppUserModelID: string;
begin
  Result := AppID + THashBobJenkins.GetHashString(ParamStr(0))
end;

function CreateShortcut: Boolean;
var
  Path: PChar;
  LBufferPath: array [0..MAX_PATH] of Char;
  LShellLink: IShellLink;
  LAppIdPropVar: TPropVariant;
  LFindData: TWin32FindData;
begin
  Result := False;
  if Succeeded(SHGetKnownFolderPath(FOLDERID_Programs, 0, 0, Path)) then
  begin
    var ShortcutPath := string(Path) + &#39;\&#39; + ChangeFileExt(ExtractFileName(ParamStr(0)), &#39;.lnk&#39;);
    if FileExists(ShortcutPath) and
       Succeeded(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, LShellLink)) and
       Succeeded((LShellLink as IPersistFile).Load(PChar(ShortcutPath), 0)) and
       Succeeded(LShellLink.GetPath(LBufferPath, MAX_PATH, LFindData, 0)) and
       (LBufferPath = ParamStr(0)) then
        Result := True
    else
      if Succeeded(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, LShellLink)) then
      begin
        LShellLink.SetPath(PChar(ParamStr(0)));
        LShellLink.SetWorkingDirectory(PChar(ExtractFilePath(ParamStr(0))));
        var LPropertyStore := LShellLink as IPropertyStore;
        ZeroMemory(@LAppIdPropVar, SizeOf(LAppIdPropVar));
        if Succeeded(InitPropVariantFromString(PChar(GetAppUserModelID), LAppIdPropVar)) then
          try
            if Succeeded(LPropertyStore.SetValue(PKEY_AppUserModel_ID, LAppIdPropVar)) and
               Succeeded(LPropertyStore.Commit) then
            begin
              var LSaveLink := True;
              if FileExists(ShortcutPath) then
                LSaveLink := System.SysUtils.DeleteFile(ShortcutPath);
              if LSaveLink then
                Result := Succeeded((LShellLink as IPersistFile).Save(PChar(ShortcutPath), True));
            end;
          finally
            PropVariantClear(LAppIdPropVar);
          end;
      end;
  end;
end;&lt;/pre&gt;
&lt;p&gt;Note that because the RTL supports Windows 10 desktop notifications (aka toast notifications), then it does all this stuff as well (look in System.Win.Notification.pas). The &lt;code&gt;GetAppUserModelID&lt;/code&gt; function is much the same as &lt;code&gt;TNotificationCenterWinRT.GetAppNotificationKey&lt;/code&gt; and &lt;code&gt;CreateShortcut&lt;/code&gt; is very similar to &lt;code&gt;TNotificationCenterWinRT.CreateShortcut&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I am hoping to come back to this general subject soon to look at doing more with WinRT, but this is time-dependent and I have a few other things to write about first. But hopefully this has given a general idea of how you can make use of WinRT API from a Delphi application.&lt;/p&gt;

</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/8526300883776777046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2020/09/delphi-and-winrt-api.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/8526300883776777046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/8526300883776777046'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2020/09/delphi-and-winrt-api.html' title='Delphi and the WinRT API'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYdm9FTaN9uSWvo_Xsaz44bxPenge6PBpfDocQjLM55LIfBGZXX_Y7nKJXJNmtyGoJriW-Lgx_Gs6ZE2ULm5qYEp9RnNq15tdJYj2e9FBAUcx-CWMfhd3swHAaI_KZhMhwxONE5Z8QEc4/s72-c/WinRT_Error.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-4801172506271619820</id><published>2020-02-14T06:21:00.000-08:00</published><updated>2020-02-14T08:49:30.453-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>25 Delphi Tips for 25 Years of Delphi</title><content type='html'>It seems funny to think Delphi is 25 years old, and yet sure enough the celebrations are ongoing for the 25th Anniversary of its unveiling on 14th February 1995.&lt;br /&gt;
&lt;br /&gt;
As it happens I&#39;ve been part of the Delphi world for around 26 years now, as I used to work at Borland and was involved with testing and experimenting with and working with the pre-release versions.&lt;br /&gt;
&lt;br /&gt;
What can I say other than Happy Birthday, Delphi? You&#39;ve been a good friend to me over this last quarter of a century and I&#39;ve been happy to be part of your world.&lt;br /&gt;
&lt;br /&gt;
Some number of posts ago I wrote up &lt;a href=&quot;http://blog.blong.com/2013/06/10-tips-for-delphi-users.html&quot; target=&quot;_blank&quot;&gt;10 Tips for Delphi Users&lt;/a&gt;. When I checked I was horrified to find this was 7 years ago! (My, my, how time flies when you&#39;re having fun...) Anyway, I thought I&#39;d take that list and build upon it, expanding it up to 25 tips for Delphi users, which is what we have here. So without further ado let&#39;s get straight into the list.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;h4&gt;
1) Running apps from network shares&lt;/h4&gt;
&lt;br /&gt;
Sometimes people like to put executables on network drives and run them from there – it allows potentially many users to launch a single executable. However if the program is running and the network connection breaks there is a more than reasonable chance that the program will crash is a quite ghastly manner, understandably enough.&lt;br /&gt;
&lt;br /&gt;
Given users are at liberty to launch there apps like this it may be an idea to make habit a simple step that alleviates the aforementioned crash scenario. You can have the Delphi linker set a special bit in a 32-bit Windows executable header to instruct Windows that in the event of being launched off a network drive the executable should first be copied to the local paging file and then be launched from there. This flag was introduced in Windows NT 4.0 and described in &lt;a href=&quot;https://web.archive.org/web/20171028012803/http://www.microsoft.com/msj/archive/S413.aspx&quot; target=&quot;_blank&quot;&gt;this old Microsoft Systems Journal article&lt;/a&gt;&amp;nbsp;(recorded for posterity in the Internet Wayback machine now Microsoft has droped all its old MSJ content) by Matt Pietrek from 1996.&lt;br /&gt;
&lt;br /&gt;
This is quite straightforward. You can do this with a compiler directive in the project file or you can change the linker setting (at least in recent versions of Delphi).&lt;br /&gt;
&lt;br /&gt;
To change the project file, you must make sure that Windows (or Winapi.Windows, if you prefer) is in the &lt;code&gt;uses&lt;/code&gt; clause and then add in &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/PE_(portable_executable)_header_flags_(Delphi)&quot; target=&quot;_blank&quot;&gt;this compiler directive&lt;/a&gt; &lt;em&gt;after&lt;/em&gt; the &lt;code&gt;uses&lt;/code&gt; clause:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;{$SetPEFlags IMAGE_FILE_NET_RUN_FROM_SWAP}&lt;/pre&gt;
&lt;br /&gt;
To set the linker option directly, open the project options dialog (&lt;code&gt;Ctrl+Shift+F11&lt;/code&gt;), go to the Linking options, ensure you are looking at options for a 32-bit build configuration and then give a value of 2048 to the Set extra PE Header flags option. This is passed along to the compiler as the &lt;code&gt;--peflags:2048&lt;/code&gt; command-line switch and does the same thing.&lt;br /&gt;
&lt;br /&gt;
You could work out the value to pass along yourself by looking in Winapi.Windows.pas and seeing that &lt;code&gt;IMAGE_FILE_NET_RUN_FROM_SWAP&lt;/code&gt; has a value of $800, which in decimal in 2048.&lt;br /&gt;
&lt;br /&gt;
To clarify some points that have come up in comments, this linker setting does not affect operation of the program in terms of how .ini files shipped alongside the .exe get loaded or what the value is returned by &lt;code&gt;Application.ExeName&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
2) Getting the type of an object when you only have its address&lt;/h4&gt;
&lt;br /&gt;
If we just have the address of an object, say in a pointer, how do we get its type? Well, we simply cast the address to a &lt;code&gt;TObject&lt;/code&gt; and call its &lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/en/System.TObject.ClassName&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;ClassName&lt;/code&gt;&lt;/a&gt; method. You can do the exercise in a Watch expression (&lt;code&gt;Ctrl+F5&lt;/code&gt;) with the address directly, so long as you remember to allow side effects and function calls &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Watch_Properties&quot; target=&quot;_blank&quot;&gt;when adding it&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Jaf29hqwwX9_RNrDhCDEJv8PWxrZ6jyVvVOZSy86pp8rUeubVwK2809p2bkGU-3YhOeQJf7VMwaRetLm5V5hwDWhMoL8p4elbmKh1roANLwQumniH37fkvLsUqdDCJ1xEG2o691MUhs/?imgmax=800&quot;&gt;&lt;img alt=&quot;TList3&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIOPkaYnYv20ohA5hvE8kbArP2MA3_y9dGhY0IZyILx3ClgR-GyH0wZ2p5iku4H0kRSmzKUzD9a6CHRH4iBVL896jRUmg6eUXn4CNCMD7w5gOjl2HTuE5cGkc56ab65dFBbNVMqjE0g_c/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;TList3&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
For bonus points you can identify the type in the CPU window’s memory pane rather than the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Watch_List_Window&quot;&gt;Watch List window&lt;/a&gt;. Invoke the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/CPU_Windows_Index&quot; target=&quot;_blank&quot;&gt;CPU window&lt;/a&gt; with &lt;code&gt;Ctrl+Alt+C&lt;/code&gt; and pay attention just to the memory pane at the bottom left. In recent IDEs you can also just invoke a solitary memory pane using View, Debug Windows, CPU Windows, Memory 1 (&lt;code&gt;Ctrl+Alt+E&lt;/code&gt;) or Memory 2 (&lt;code&gt;Ctrl+Alt+2&lt;/code&gt;) or Memory 3 (&lt;code&gt;Ctrl+Alt+3&lt;/code&gt;) or Memory 4 (&lt;code&gt;Ctrl+Alt+4&lt;/code&gt;).&lt;br /&gt;
&lt;br /&gt;
In the memory pane, firstly have the memory displayed in 8 byte chunks of data by right-clicking and choosing Display As, DWords.&lt;br /&gt;
&lt;br /&gt;
Now right-click again and choose Go to address… (&lt;code&gt;Ctrl+G&lt;/code&gt;) and enter a suitable expression based on the pointer value or object address. For this example let&#39;s say the object address is $27E2C20. This is an object reference – the address of an object’s instance data. So if we de-reference the pointer we’ll be at the start of the instance data. But the address of the class name string is a little way into the instance data, a distance given by the constant &lt;code&gt;vmtClassName&lt;/code&gt;, so the required expression will be:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;PInteger($27E2C20)^+vmtClassName&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2iyo0SpKpwm-JvTsjuNQx1pV3K5GJ7rTL0sIrN-oCppltB9wRp8wPPXvuGyFVBZ0CrNZD65jYkihQUWFUUVU0j9RwAao5rgvojtm0JN_cQKzRc4kLjFkTSDgud7U8fMYlONgv0KcBjCs/s1600-h/TList6%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;TList6&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj72jeVo2G7yY_BAPhzDMszjmMX2_HtEprQaetDQMZeUouUPwumlVUFn8E96d3uOnsHvTFwZkWUWmOWNYQ-SGrg8abZlFyvEArHJU3swbDWLWoay_Bg9cCbsdykbQLidjGNcTrMu_bRVW0/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;TList6&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
As mentioned, we’re now looking at the address of the class name, which is stored as a short string. To follow (de-reference) this address, right-click on it and choose Follow, Offset to Data or press &lt;code&gt;Ctrl+D&lt;/code&gt;. This takes us to the information we seek: &lt;code&gt;TFoo&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVJIKT-9dGHEKH0pCqeAbqWqY6pL2pn2aveX_B7t2aZ7r4Jwk6yr5I_BIUmiu7z77Vn7wkW_dskD0Y8s57Okg5euJicXr1UrzxWWlno72k7Rq5KDpfDxW0j4mTNQjwnftlgcTNpqI0eGY/s1600-h/TList7%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;TList7&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihAR9tuAUcBSZAiMVXjvj2CKtDPXLZWbAYdzquDP7ZR7j7FNw6v_URD67w_D86sXhQVDm3HPbZGAnk0JrlsrnT45t1QNnJh63Xs7LnMJXQybBUxjnfz7Bb21ppHPZXrM38fRl7ngMFzMU/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;TList7&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
If you wish you can change the display back to bytes (right click, Display As, Bytes) and then the short string is more obvious – you can see the length prefix byte for the 4 character string is indeed 4.&lt;br /&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0VTX64rympfJSQxwr_vrvy_XT4Y7ZzDWzs1DrPJduNcp1hK6gzJYTE8WDKsuTVSwGjtr08NCfSh4qxMtqNRng5IbgzBFC_0W1QuL1OdoqSVIKZqW5yj2GfKz3wDMIVamUeaPqTC1bia4/s1600-h/TList8%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;TList8&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_GQaBBKmkhUQGoc9pbhquhNtbm7eX1GlYqPijY2mCiqqYXee0FM64X0s7JseJ_7gzWWRG0vxlLrwvfmDiOJJSUAPrWQqh69txtreynjxRWX-l0P43Gz7DmSbGuj7hS3R-01r3FLVSVmw/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;TList8&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
3) Inspecting an item in a TList&lt;/h4&gt;
&lt;br /&gt;
The old&amp;nbsp;&lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/en/System.Classes.TList&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;TList&lt;/code&gt;&amp;nbsp;class&lt;/a&gt;&amp;nbsp;is still a useful beast, even if in many cases we should be using the&amp;nbsp;&lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/en/System.Generics.Collections.TList&quot; target=&quot;_blank&quot;&gt;newer generic&amp;nbsp;&lt;code&gt;TList&lt;t&gt;&lt;/t&gt;&lt;/code&gt;&lt;/a&gt;.&amp;nbsp;&lt;code&gt;TList&lt;/code&gt;&amp;nbsp;is useful when the list will potentially contain objects of different types, with suitable backup code that knows to check the type and cast appropriately.&lt;br /&gt;
&lt;br /&gt;
In the debugger, if you want to inspect an item in a&amp;nbsp;&lt;code&gt;TList&lt;/code&gt;&amp;nbsp;things can be a bit of a challenge. When you inspect your&amp;nbsp;&lt;code&gt;TList&lt;/code&gt;&amp;nbsp;variable (&lt;code&gt;Alt+F5&lt;/code&gt;) you get a debug inspector that hints at the items contained therein in its&amp;nbsp;&lt;code&gt;FList&lt;/code&gt;&amp;nbsp;field.&lt;br /&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgj0BdFHt7g-y7oSM5zR6AmjFcJrFVskhe8olNgZxKeL-iqLfxYM9RDzMYxsAlT7lNMAOXxn8mCmlj_8WS0SVRoO9aNv-0nKD0pbz0wr-PbupNsxQRhuDAfaYTPVRw_mVaq2mSXWOtT9Mo/s1600-h/TList1%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;TList1&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxUYXJ2CGvDqsUCfWiP7LkI0oyVphKrsBwM-zR11rsiI-kk9rIq_2qmOns73RrYH74_36E42zpXRf03YxRbPtrKlWU0q8HLyAgdZnDTs8yxfOEkb0qF-h15yvhjZWEjwbm15bVW5A5WZQ/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;TList1&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
If you right-click on&amp;nbsp;&lt;code&gt;FList&lt;/code&gt;&amp;nbsp;and choose Descend (or&amp;nbsp;&lt;code&gt;Ctrl+D&lt;/code&gt;, to make this inspector inspect that field) or Inspect (or&amp;nbsp;&lt;code&gt;Ctrl+I&lt;/code&gt;, to launch a new inspector showing that field) you’ll see the addresses of the items in the list.&lt;br /&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5rQuQBwI4DDS6bhFq-NqZRm6SYaYidBuQ2BfGfOmMkuy4n4JfhXx2wLdPfsCQdFtIWlwRHrzPFPrOnJghwJ9k8kB4G5Ei_-KrRAOEOqNSvTOu_7hzKU9G4Rgf333axXJt3tN8osIAZ8Y/s1600-h/TList2%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;TList2&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFFeNWlpbAUZQyhgljXqtNgwHNwIgH7IRKZOX73pTZudXA5ZdxR0HqgqvjlmJhJt2VvxGmQ6Ey5Ysfak7Za3qZcBD0f_s6II79faNhWS6Tf55V94x72SZG0fgJFlgIMdY1jAWT8eX8nPg/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;TList2&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
These aren’t much use though; being as this is the type-unsafe general&amp;nbsp;&lt;code&gt;TList&lt;/code&gt;&amp;nbsp;these values are just pointers. Indeed if you look in the definition of&amp;nbsp;&lt;code&gt;TList&lt;/code&gt;&amp;nbsp;you’ll see this&amp;nbsp;&lt;code&gt;FList&lt;/code&gt;&amp;nbsp;field is a&amp;nbsp;&lt;code&gt;TPointerList&lt;/code&gt;&amp;nbsp;– an array of pointers.&lt;br /&gt;
&lt;br /&gt;
So what do we do to inspect the item underlying a pointer variable? Well, we cast the pointer to the right type and inspect that. To work out what type that is, as Tip 2 above suggests, we cast the address shown in the inspector to a&amp;nbsp;&lt;code&gt;TObject&lt;/code&gt;&amp;nbsp;and call its&amp;nbsp;&lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/en/System.TObject.ClassName&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;ClassName&lt;/code&gt;&lt;/a&gt;&amp;nbsp;method.&lt;br /&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Jaf29hqwwX9_RNrDhCDEJv8PWxrZ6jyVvVOZSy86pp8rUeubVwK2809p2bkGU-3YhOeQJf7VMwaRetLm5V5hwDWhMoL8p4elbmKh1roANLwQumniH37fkvLsUqdDCJ1xEG2o691MUhs/?imgmax=800&quot;&gt;&lt;img alt=&quot;TList3&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIOPkaYnYv20ohA5hvE8kbArP2MA3_y9dGhY0IZyILx3ClgR-GyH0wZ2p5iku4H0kRSmzKUzD9a6CHRH4iBVL896jRUmg6eUXn4CNCMD7w5gOjl2HTuE5cGkc56ab65dFBbNVMqjE0g_c/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;TList3&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This tells you the type. Now you can bring up an inspector for the currently unhelpful pointer by selecting it in the inspector and pressing&amp;nbsp;&lt;code&gt;Ctrl+I&lt;/code&gt;, or maybe just double-clicking it.&lt;br /&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3rWH776wQmRW-rPtGP9UMcfQ1iRr7UYxiJ5DZwGISK8cPthEbTCamAuEt3Nz9guB6qnD0dd-CEDHno0F8PDmyulrKqPDCjpCDreXI8fGpCYscvv3su43vMPA9Dz2aUQk5DNU4lsNd06U/s1600-h/TList4%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;TList4&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVVgNMOWvbz9k1WQC8WVxr2vlxzuW6RhDrWByMq3ZQlYOphyphenhyphenKnKKzYJgJ58U-g1y4_9X1NR-nB5DixhRhWU4TQsMUyAX3dASqbS79dl15js7w9Zzu0z9LDcfPTBp-LEhrDZBgf4V_ESNs/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;TList4&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Then you can apply the typecast by right-clicking and choosing Type Cast... or pressing&amp;nbsp;&lt;code&gt;Ctrl+T&lt;/code&gt;, and entering the target type of&amp;nbsp;&lt;code&gt;TFoo&lt;/code&gt;&amp;nbsp;(in this example’s case). And then you have what you sought:&lt;br /&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi59Vxu29m6sdr3tKLh7j7yb15SBsUiFoi7UFIbLa_ws05HkI-80y-ci2Hl7u6PrLV9kukmmtOOx2JA9rzcCjVtHCqOCvANofnSfP9ZCMr47HhLCDm6rdGO4Juo4l5gkhJLtBBo5eo4Ko0/s1600-h/TList5%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;TList5&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdgZVRm_nHyqsXKK3FQfcRCJrh6_N75BfrFJlC5Hc2kIjApAEVcw4WXefLV-p13sQoMkBWq0tfD_RjbRYitO3nLmHbgeas7Ta-VJc5BO8LLULqUNlJNNSueAZxd0U_PQWEQGV-zbMK1xk/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;TList5&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
4) Loop failure iteration detection&lt;/h4&gt;
&lt;br /&gt;
You’ve doubtless encountered this scenario while debugging. There’s an issue in a loop. The loop executes *loads* of times but you need to look into the problem so you need to know how many times round the loop the problem occurs. Stepping through the loop, or using a breakpoint and pressing &lt;code&gt;F9&lt;/code&gt; or clicking on the last line of the loop and pressing &lt;code&gt;F4&lt;/code&gt;, counting in your head – all such options are mind-numbing and hugely prone to losing count or messing up in some regard, so how about letting the system work it out for you?&lt;br /&gt;
&lt;br /&gt;
Place a breakpoint at the end of the loop with a massive pass count – say 1000000. Now run the app and make the problem occur. Now look in the breakpoints window and check the current pass count – it will tell you how many times the breakpoint has been passed without actually breaking.&lt;br /&gt;
&lt;br /&gt;
Once you know how many iterations it has been through, modify the properties of the breakpoint and set the pass count to that value. Restart the program and the when the breakpoint triggers the error will occur on the next iteration of the loop. Nice!&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
5) Breakpoint logging&lt;/h4&gt;
&lt;br /&gt;
Breakpoints had their advanced properties added many, many versions ago. You can use advanced breakpoint properties for a variety of cunning debugging scenarios, but a simple usage is to enable cheap logging without writing additional code statements.&lt;br /&gt;
&lt;br /&gt;
Wherever you want to log some information, add a breakpoint and bring up the breakpoint properties. Press the Advanced button, set the breakpoint to not actually break and then specify the log message. For bonus points you can also choose to have an expression evaluated and (optionally) logged at the same time.&lt;br /&gt;
&lt;br /&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7DP0rMDn_WuT7FOCct_IQ65IY_93gkMFvq7NvNjCVBh55CtoyS7mDyRPWarDTSTcCQD3PTLAhdxATNYSqlTJyi-sfXD2Z-WJBWCGlQ_y2CUxINAWhPcZaTUIYBtXo3E182195wHZP8Pc/s1600-h/AdvancedBreakpoints%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;AdvancedBreakpoints&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNDI37lX-MnMxm_slKWj4xAIR2KjRumCXhY3AKe2cEJpNJYbTkH8od23inz2pa6DDZj53vZJuQ9FmH1DN6YHknxjbM55Od2uC_ms3R73on7hFa5iOvM_KwcU_rzrcQ2pgpGQ4pbDmt04o/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;AdvancedBreakpoints&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This log information will be added to the Event Log window during your debug session in the same way that &lt;code&gt;OutputDebugString&lt;/code&gt; messages are, but with the benefit of not having written any code. If you have the IDE set to save your project desktop then the breakpoints will be saved when you close the project and reappear next time you open it.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
6) Leaving RTL assembler code&lt;/h4&gt;
&lt;br /&gt;
When stepping through code with Debug DCUs enabled you often inadvertently end up in RTL assembly code. In most instances &lt;code&gt;Shift+F8&lt;/code&gt; (Run, Run Until Return) will run the rest of the code through and take you back to where you were so you can try &lt;code&gt;F7&lt;/code&gt; again.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;Shift+F8&lt;/code&gt; doesn’t always work. For example if you use &lt;code&gt;F7&lt;/code&gt; on a call to a dynamic method you end up in the System unit’s &lt;code&gt;_CallDynaInst&lt;/code&gt; routine. This doesn’t exit in the normal manner, but by jumping off to the located method address stored in the ESI register.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvk8b7jPqjTKc6R6idTYd_zIRuy8MmW7R1e50TEFppBWH8qJYwwHF9R4xV0mzFT-JUevl6zxa9xfw25YMCV9Gq63nrS_Lr-NLRKIU1S5Vdz4HQD6ehhyphenhyphenW-fQK3KdfoxDVgotOhhpBD3kM/s1600-h/CallDynaInst%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;CallDynaInst&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz-U292ChekwUfzmMoKGpM6Bz89Js9Y0gJGHNrtWJzenA_5O0uZhUwFQC3zzVt3ux9SY6HZyGoXu8kwk5-ZX4LdR6C5Qt2aVG2CLGring6Yc8hxt1yLFV2atddbjHDdPekgntwe4D6hS0/?imgmax=800&quot; style=&quot;background-image: none; border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;CallDynaInst&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The best way forward here is to click on the &lt;code&gt;JMP ESI&lt;/code&gt; line, press &lt;code&gt;F4&lt;/code&gt; to run up to that point and then press &lt;code&gt;F7&lt;/code&gt; – that will take you into the dynamic method that was called.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
7) Find declaration while debugging&lt;/h4&gt;
&lt;br /&gt;
Seasoned Delphi developers know that you can locate the definition of a symbol by right-clicking it in the editor and choosing Find Declaration. Rather annoyingly there is no shortcut listed next to it, but it is commonly known that if you hold down &lt;code&gt;Ctrl&lt;/code&gt; and wave your mouse around the editor, anything that the IDE thinks it can locate the definition/declaration of turns into a hyperlink – this &lt;code&gt;Ctrl+&lt;/code&gt;click hyperlink feature is &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Code_Insight_(IDE_Tutorial)#Code_Browsing_.E2.80.94_Ctrl.2BClick&quot; target=&quot;_blank&quot;&gt;Code Browsing&lt;/a&gt; and links to the Code Browsing History keystrokes of &lt;code&gt;Alt+←&lt;/code&gt; and &lt;code&gt;Alt+→&lt;/code&gt; that allow you to go back and forth though the links you’ve clicked.&lt;br /&gt;
&lt;br /&gt;
The problem with &lt;code&gt;Ctrl+&lt;/code&gt;click is that it doesn’t work in a debug session. Many times it would be handy to find the definition of a symbol in a debug session but &lt;code&gt;Ctrl+&lt;/code&gt;click just doesn’t cut it. Fortunately, however, &lt;code&gt;Alt+↑&lt;/code&gt; *does* work in a debug session (yay!)… (or at least should do – it generally does for me). Why &lt;code&gt;Alt+↑&lt;/code&gt; isn’t listed in the editor context menu against Find Declaration baffles me. It’s a very little-known but useful shortcut.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
8) Non-destructively locally disable a compiler option&lt;/h4&gt;
&lt;br /&gt;
Often-times a build configuration has range-checking enabled to ensure problems show up when they occur as tangible issues rather than vague Access Violations through memory overwrites way down the line during an execution. That said, it can still be important to selectively turn off range-checking for specific small sections of code that are valid, but will flag up range-check errors thanks to, say, the pointer types involved.&lt;br /&gt;
&lt;br /&gt;
Clearly you can turn range-checking (or overflow-checking or whatever) off and on using local compiler directives, as in:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;{$R-}&lt;br /&gt;//code that requires range-checking off&lt;br /&gt;{$R+}&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
but what about if you then build the code with a build configuration that has range-checking globally disabled? This use of compiler directives means the file in question will have range-checking *enabled* from that point onwards, despite the intent being to have it disabled throughout the project.&lt;br /&gt;
&lt;br /&gt;
This is where this tip comes in. You can selectively change a compiler option using code like this, where this example disables range-checking if it was enabled, and then ensures it gets enabled again if appropriate:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;{$IFOPT R+}&lt;br /&gt;&amp;nbsp; {$DEFINE RANGE_CHECKING_WAS_ON}&lt;br /&gt;&amp;nbsp; {$R-}&lt;br /&gt;{$ENDIF}&lt;br /&gt;//code that requires range-checking to be disabled&lt;br /&gt;{$IFDEF RANGE_CHECKING_WAS_ON}&lt;br /&gt;&amp;nbsp; {$R+}&lt;br /&gt;{$ENDIF}&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Here we define a conditional symbol if we toggle range-checking off, and we use that symbol’s existence to decide whether to enable range-checking later.
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
9) Building a Delphi project at the command-line&lt;/h4&gt;
&lt;br /&gt;
For quite a few versions now, Delphi has used the MSBuild format for its project files and project group files. This means &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Building_a_Project_Using_an_MSBuild_Command&quot; target=&quot;_blank&quot;&gt;you can use MSBuild to build your projects&lt;/a&gt; and project groups, using appropriate MSBuild command-lines to pass in options or specify build targets (the targets include &lt;code&gt;clean&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt; and &lt;code&gt;build&lt;/code&gt;). So if you have a project Foo.dproj and you want to clean up the previously produced binaries (compiled units and executable output) and then build it in Release and Debug configurations for Win32 and Win64 you could run these commands in a RAD Studio Command Prompt:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;msbuild -t:clean -p:Config=Debug -p:Platform=Win32 Foo.dproj
msbuild -t:build -p:Config=Debug -p:Platform=Win32 Foo.dproj
msbuild -t:clean -p:Config=Release -p:Platform=Win32 Foo.dproj
msbuild -t:build -p:Config=Release -p:Platform=Win32 Foo.dproj
msbuild -t:clean -p:Config=Debug -p:Platform=Win64 Foo.dproj
msbuild -t:build -p:Config=Debug -p:Platform=Win64 Foo.dproj
msbuild -t:clean -p:Config=Release -p:Platform=Win64 Foo.dproj
msbuild -t:build -p:Config=Release -p:Platform=Win64 Foo.dproj
&lt;/pre&gt;
&lt;br /&gt;
See also &lt;a href=&quot;http://blog.blong.com/2017/10/delphi-buildinstall-to-android-from.html&quot;&gt;my post on building, installing and launching an Android app from the command line&lt;/a&gt; for additional Android-specific details.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
10) Formatting entire projects&lt;/h4&gt;
&lt;br /&gt;
Recent versions of Delphi have offered pretty printing, as it used to be called, or &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Formatting_Source_Code&quot; target=&quot;_blank&quot;&gt;source formatting&lt;/a&gt; as the process is now described. It’s invoked by Edit, Format Source (or &lt;code&gt;Ctrl+D&lt;/code&gt;) and can be fully customised in the Tools, Options dialog. Your custom settings can be saved into &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Profiles_and_Status&quot; target=&quot;_blank&quot;&gt;formatter profile files&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
It’s less well known that the formatter is also available through &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Formatter.EXE,_the_Command_Line_Formatter&quot; target=&quot;_blank&quot;&gt;a command-line tool&lt;/a&gt;. You can use this to run it across all files in a project directory tree.&lt;br /&gt;
&lt;br /&gt;
Assuming you’ve saved your custom IDE formatter options in a formatter profile called Formatter_MyProfile.config then you start by running up a RAD Studio Command Prompt. Now issue some commands along these lines and it’s all done for you:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;set CONFIG=&quot;Formatter_MyProfile.config&quot;
set LOG=Format.log
del %LOG%
formatter -delphi -config %CONFIG% -r –d . &amp;gt; %LOG%
&lt;/pre&gt;
&lt;br /&gt;
&lt;h4&gt;
11) Case toggle&lt;/h4&gt;
&lt;br /&gt;
If you are not a touch typist and occasionally type a whole bunch of code in with CAPS LOCK on you should become familiar with the keystroke that toggles the case of a marked block: &lt;code&gt;Ctrl+O, U&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
12) Disable Error Insight to lower blood pressure&lt;/h4&gt;
&lt;br /&gt;
I’ve said this before in talks and in writing. I’m very happy to say it again. Please, *please*, don’t suffer the shame of Error Insight and its hopeless and hapless efforts in working out what might compile and what might not. Yes, it gets the simple ones right. But any vaguely interesting project that you work within is pretty much guaranteed to be besmirched with lots of red squiggles over perfectly good code and perfectly locatable units in the uses clause all within a fully compilable code base. The fact that Error Insight continues to be enabled by default, despite the growing problem of its inaccurate problem detection is really rather surprising. I urge you to disable Error Insight by going to Tools, Options… and then locating the Code Insight options within the User Interface and then Editor nodes on the tree of categories on the left.&lt;br /&gt;
&lt;br /&gt;
Yes, yes, there are reasons why it gets it wrong – it’s not using the exact same parsing code as the compiler does and doesn’t know all the things that the compiler does. But this has been the case for years, and it still offends my eyes with its tenacity of squiggling over code that has just compiled cleanly.&lt;br /&gt;
&lt;br /&gt;
Ease your annoyance at Error Insight by turning it off. Then pick any of &lt;a href=&quot;https://quality.embarcadero.com/browse/RSP-21631?jql=text%20~%20%22error%20insight%22&quot;&gt;the plethora of Error Insight bugs&lt;/a&gt; logged on &lt;a href=&quot;https://quality.embarcadero.com/&quot;&gt;the Quality Portal&lt;/a&gt; and vote for it/them.&lt;br /&gt;
&lt;br /&gt;
One day, maybe one day soon, Error Insight will function again and will a useful programming ally. But until then it deserves no place in any self-respecting programmer&#39;s IDE.&lt;br /&gt;
&lt;br /&gt;
Seriously though, on very large projects, disabling anything that executes and isn’t useful/productive is a benefit. When working with clients’ large projects I disable Error Insight, Tooltip Help Insight and automatic Code Completion.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
13) IDE Insight shorter shortcut&lt;/h4&gt;
&lt;br /&gt;
A great IDE navigation feature called &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/IDE_Insight&quot;&gt;IDE Insight&lt;/a&gt;&amp;nbsp;was &lt;a href=&quot;https://community.embarcadero.com/blogs/entry/rad-studio-2010--ide-insight-part-1-3&quot;&gt;introduced in RAD Studio 2010&lt;/a&gt;. It was inspired by the ability to search for things in Windows by pressing the Start button and simply typing what you wanted.&lt;br /&gt;
&lt;br /&gt;
In the IDE there is similar functionality to find any window, option, preference, file (recent or current), project (recent or current), form, property, menu command, new item, desktop, code template or component (if the form designer is active). IDE Insight is commonly invoked by &lt;code&gt;Ctrl+.&lt;/code&gt; (&lt;code&gt;Ctrl&lt;/code&gt; and period), indeed that keystroke was introduced in that feature introduction post linked above. Note that rather than popping up in a separate window as it did when introduced, IDE Insight now manifests as a drop down list from an edit field embedded in the RAD Studio caption bar.&lt;br /&gt;
&lt;br /&gt;
However as a means of saving 50% of the keys required to trigger IDE Insight I&#39;d like to ensure you know that &lt;code&gt;F6&lt;/code&gt; does the same thing - it also fires IDE Insight. So there we have a productivity improvement in accessing a productivity improvement :)&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/AVvXsEh4alwx3L6GkawIWxqlxgwhNqx5Y_ZBgkR-eXjZSAYtk2kKPyG9Msd-j2unbQI5S74rlsevhrDQqJorrVmRG6_LPnVKEqRXFlpVxbOUkPxMX2oL1CfTXv-mFWsDsQeXBL-Q6iTmKL0tNqE/s1600/IDE_Insight.gif&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;540&quot; data-original-width=&quot;960&quot; height=&quot;360&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4alwx3L6GkawIWxqlxgwhNqx5Y_ZBgkR-eXjZSAYtk2kKPyG9Msd-j2unbQI5S74rlsevhrDQqJorrVmRG6_LPnVKEqRXFlpVxbOUkPxMX2oL1CfTXv-mFWsDsQeXBL-Q6iTmKL0tNqE/s640/IDE_Insight.gif&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
14) Synchronising declaration and implementation&lt;/h4&gt;
&lt;br /&gt;
When RAD Studio 10 Seattle &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/Seattle/en/What%27s_New#Integration_of_the_Castalia_Features_in_the_IDE&quot;&gt;brought some of the Castalia features on-board&lt;/a&gt; into the IDE I missed a really useful one for a couple of years. It is common to implement a routine, e.g. declaring a method with its parameter list in a class definition and implementing it in the implementation section of the unit. Furthermore it is not uncommon to realise you need slightly different parameters in the parameter list.&lt;br /&gt;
&lt;br /&gt;
Having 2 parameter lists to edit is a bit of a bind. Or at least it used to be! This is what the new(-ish) feature called&amp;nbsp;&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Code_Editor#Synchronizing_Prototypes&quot;&gt;Sync Prototypes&lt;/a&gt;&amp;nbsp;is for. As soon as you update one of the routine signatures (or its prototype) then you simply invoke Sync prototypes with &lt;code&gt;Ctrl+Shift+Alt+P&lt;/code&gt; and the other one will be updated to match. It doesn&#39;t matter whether you edit the one in the interface section or the one in the implementation section - &lt;code&gt;Ctrl+Shift+Alt+P&lt;/code&gt; will update the other.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
15) Hiding non-visual components&lt;/h4&gt;
&lt;br /&gt;
One drawback of Delphi&#39;s form designer is that both visual components and non-visual components are placed on the form&#39;s UI area. The problem is that as you start using more and more non-visual components in the designer (and don&#39;t elect to partition them off onto non-visual data modules) it becomes harder and harder to see the underlying UI of the form.&lt;br /&gt;
&lt;br /&gt;
At last we have a means to mitigate this glaring issue. Another &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/Seattle/en/What%27s_New#New_Option_to_Hide_Non-visual_Components_at_Design-time&quot;&gt;feature added by RAD Studio 10 Seattle&lt;/a&gt; was the option to&amp;nbsp;&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Hide_Non-Visual_Components&quot;&gt;Hide Non-Visual Components&lt;/a&gt;, which can be triggered on the form designer using the &lt;code&gt;Ctrl+H&lt;/code&gt; shortcut. You can also find the option in the menu and context menu, on one of the toolbars and, for good measure, in the Tools, Options... dialog - see &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Hide_Non-Visual_Components&quot;&gt;the docwiki page&lt;/a&gt; for details.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
16) Working out from where a message box was called&lt;/h4&gt;
&lt;br /&gt;
The following scenario might be a rarity for you, but for me it happens surprisingly frequently.&lt;br /&gt;
&lt;br /&gt;
While debugging an application a message box pops up and I need to know its provenance - where in the code was it invoked from? Searching the code base for the message string might work, but the message may be dynamically constructed so it&#39;s certainly not a given that would work. I tend to use the following technique to help me get to the point of origin.&lt;br /&gt;
&lt;br /&gt;
First of all pause the application with the Run, Program Pause menu item or equivalent toolbutton.&lt;br /&gt;
&lt;br /&gt;
At this point you might think the call stack would help out but alas not. As we see here the call stack is barren:&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/AVvXsEhgEm3iM1S0HpHJMs6bPQIZNdRVUB6KxwDWsrxK54xctJkFBwwGgOPRLT4DY1CYrLmu53mK7TDq0oVPhvQ9DBLLDX10Ogd50ZtijXk6I0XQHdzqoLVDE1I4hPGo5MXZ2KySNSu3TKh8mAk/s1600/call_stack_1.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;794&quot; data-original-width=&quot;1178&quot; height=&quot;431&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgEm3iM1S0HpHJMs6bPQIZNdRVUB6KxwDWsrxK54xctJkFBwwGgOPRLT4DY1CYrLmu53mK7TDq0oVPhvQ9DBLLDX10Ogd50ZtijXk6I0XQHdzqoLVDE1I4hPGo5MXZ2KySNSu3TKh8mAk/s640/call_stack_1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
However the crucial piece of information here is that the debugger is looking at the wrong thread in terms of what we are interested in. If you switch to the Threads window (&lt;code&gt;Ctrl+Alt+T&lt;/code&gt;) you can see that the active thread in terms of what the debugger is looking at is the last one in the list.&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/AVvXsEiBbN0abSppyQWoSaBbPgM5Rek7GheFONPksQnlNNhD7MuzKw8FxcUAFuNE4vt6zA9cT5RM0PSwz0LU7iyxTLRk6mRV0BdT9u5hkhq7wNWsoESdUI4agrAEtrgA3AM7SP4nPETkKyMx9ao/s1600/call_stack_2.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;276&quot; data-original-width=&quot;495&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBbN0abSppyQWoSaBbPgM5Rek7GheFONPksQnlNNhD7MuzKw8FxcUAFuNE4vt6zA9cT5RM0PSwz0LU7iyxTLRk6mRV0BdT9u5hkhq7wNWsoESdUI4agrAEtrgA3AM7SP4nPETkKyMx9ao/s1600/call_stack_2.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This thread is of no interest to us. We need the main thread, the UI thread, which is the first in the list. Double-click on that first thread and the call stack is immediately replete with lots of entries:&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/AVvXsEiMgMIiIGwNB9b_SYpmS4bD3XEjRN_WHJDKGeG-WGOu9Tpt5KqwCE2viLPmKD2YgQVtQtXMQLjxSSAGLli1q72CB_hud8WkKsKRauOSWEOU70x0mm9A5iVizoT569diJjXoEdtNF1t4vgY/s1600/call_stack_3.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;686&quot; data-original-width=&quot;448&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMgMIiIGwNB9b_SYpmS4bD3XEjRN_WHJDKGeG-WGOu9Tpt5KqwCE2viLPmKD2YgQVtQtXMQLjxSSAGLli1q72CB_hud8WkKsKRauOSWEOU70x0mm9A5iVizoT569diJjXoEdtNF1t4vgY/s1600/call_stack_3.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
If you scan down from the top you will start to see entries suspiciously looking related to message box work and eventually (and hopefully) you come to entries related to your code. In the case below the first entry in &quot;user code&quot; (my code) is &lt;code&gt;TForm2.Five&lt;/code&gt;. If you double-click that entry you will be taken to the relevant code, with the editor highlighting the point we will return to (after the invocation) in red (by default), Sure enough the red line is just after my call to &lt;code&gt;ShowMessage&lt;/code&gt;.&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/AVvXsEhQ-RuxRsLgYySCoGEyHs0UWe-iJVFpJjUHJyDhzgUw0IP4ZlNZZwAK2WyKw5DQ4KWUgYt1i16Z_d5Hv4GiV0K1rvTv246e7scjxZ1_q1SQCj1PdzX-GBPOAKD0ElJtNXfWbxfQfO4sNU0/s1600/call_stack_4.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;205&quot; data-original-width=&quot;583&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ-RuxRsLgYySCoGEyHs0UWe-iJVFpJjUHJyDhzgUw0IP4ZlNZZwAK2WyKw5DQ4KWUgYt1i16Z_d5Hv4GiV0K1rvTv246e7scjxZ1_q1SQCj1PdzX-GBPOAKD0ElJtNXfWbxfQfO4sNU0/s1600/call_stack_4.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
17) Listing out DLL exports&lt;/h4&gt;
&lt;br /&gt;
When you need to find what routines are exported from a DLL you can use the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/TDUMP.EXE,_the_File_Dumping_Utility&quot;&gt;TDump.exe&lt;/a&gt; utility, or alternatively &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/TDUMP64.EXE,_the_File_Dumping_Utility_for_64-bit_Windows&quot;&gt;TDump64.exe&lt;/a&gt;. Either work fine in producing a lot of information on an executable file, .exe or .dll. To just list out the PE exports use the -ee command line switch, e.g.&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/AVvXsEgH-QiN2xTguzxXzZ3ONwx4ew3TQqg-_al-PFVGm6fMlRHa5G1YCO1pyrNxG-rSCdPDdZxzsbndYxPtfJdTfy-BzxMs3s0gejGB8n51cmn2daEitp5ViumA_bUKXdOIJMuqZpe-eGUP3iw/s1600/exports_1.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;364&quot; data-original-width=&quot;688&quot; height=&quot;337&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH-QiN2xTguzxXzZ3ONwx4ew3TQqg-_al-PFVGm6fMlRHa5G1YCO1pyrNxG-rSCdPDdZxzsbndYxPtfJdTfy-BzxMs3s0gejGB8n51cmn2daEitp5ViumA_bUKXdOIJMuqZpe-eGUP3iw/s640/exports_1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
If you are working with Android apps and want to get the exported symbols from a .so library file then TDump et al fall short. However you will already have the NDK installed with comes with a lot of Linux-y utilities that can do this sort of thing.&lt;br /&gt;
&lt;br /&gt;
Assuming you set an environment variable &lt;code&gt;NDK_ROOT&lt;/code&gt; to point at your Android NDK folder and then set another variable &lt;code&gt;NDK_TOOLS&lt;/code&gt; to be the subfolder of &lt;code&gt;NDK_ROOT&lt;/code&gt;&#39;s value containing all the pre-built tools that work on Android binaries then we can run some vaguely concise commands.&lt;br /&gt;
&lt;br /&gt;
Incidentally, once in a command prompt these commands (with path modified to suit your installation) will set up the variables as described:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;set NDK_ROOT=%PUBLIC%\Documents\Embarcadero\Studio\20.0\PlatformSDKs\android-ndk-r17b
set NDK_TOOLS=%NDK_ROOT%\toolchains\arm-linux-androideabi-4.9\prebuilt\windows\bin
&lt;/pre&gt;
&lt;br /&gt;
nm is a utility to list file symbols, objdump is a utility to dump information from various types of object (binary) files and readelf is a utility to dump information about ELF files (ELF being the format for executables in Unix-land, the &lt;i&gt;E&lt;/i&gt;xecutable and &lt;i&gt;L&lt;/i&gt;inkable &lt;i&gt;F&lt;/i&gt;ormat). To invoke these utilities and get the exported symbols from a .so file we can use any of these commands:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;%NDK_TOOLS%\arm-linux-androideabi-nm.exe -gD libandroid.so&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%NDK_TOOLS%\arm-linux-androideabi-objdump.exe -T libAndroid.so&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%NDK_TOOLS%\arm-linux-androideabi-readelf.exe -W --dyn-syms libAndroid.so&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
Here is some sample output:&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/AVvXsEg39rxpXt7rWGFY33KNfZc9L1fHvFyvJoDZMoG6pzlVumBKW7luNeHJYLC_0Pucr0eGvwVZNUBIaF6EpcbQQNbwJgND9nucDXBBlJUAYr3KmxbbM8kd19ePx7W83RkzqvNPnHxPrIVkOQU/s1600/exports_2.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;482&quot; data-original-width=&quot;1387&quot; height=&quot;220&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg39rxpXt7rWGFY33KNfZc9L1fHvFyvJoDZMoG6pzlVumBKW7luNeHJYLC_0Pucr0eGvwVZNUBIaF6EpcbQQNbwJgND9nucDXBBlJUAYr3KmxbbM8kd19ePx7W83RkzqvNPnHxPrIVkOQU/s640/exports_2.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&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/AVvXsEjn3W91aTfBJXPyk3gdJaZ0oYqlZIHmW90J-qOSLgPVUI2vI7gPRxXMR8rjbcZUsu0eToy_4sy79DZvyvAWxxDQoJkqnwabkaGfuWAxFXG4gc_Oyw6JoaT43_vQP-FJ2gkeYJOp5x7WMmg/s1600/exports_3.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;519&quot; data-original-width=&quot;1270&quot; height=&quot;259&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn3W91aTfBJXPyk3gdJaZ0oYqlZIHmW90J-qOSLgPVUI2vI7gPRxXMR8rjbcZUsu0eToy_4sy79DZvyvAWxxDQoJkqnwabkaGfuWAxFXG4gc_Oyw6JoaT43_vQP-FJ2gkeYJOp5x7WMmg/s640/exports_3.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&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/AVvXsEjQyjYHG384P0jYjfOPDs_XNGgGSyOT3oducuT3tsA8dczpoIUddClrucUgfG2Z550GhlYRAUejSyWviRfwgltg9XlHOdALdkd4ScUkAvRm2S8dT33mZd04rFHYRMtbfRr132w2HrRe4vc/s1600/exports_4.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;399&quot; data-original-width=&quot;1360&quot; height=&quot;185&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQyjYHG384P0jYjfOPDs_XNGgGSyOT3oducuT3tsA8dczpoIUddClrucUgfG2Z550GhlYRAUejSyWviRfwgltg9XlHOdALdkd4ScUkAvRm2S8dT33mZd04rFHYRMtbfRr132w2HrRe4vc/s640/exports_4.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
18) Save additional global desktops for better working arrangements&amp;nbsp;&lt;/h4&gt;
&lt;br /&gt;
RAD Studio ships with 4 &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/Rio/en/Desktops&quot;&gt;Desktops&lt;/a&gt; to work with, with one set to become active in a debug session (Debug Layout). Normal editing starts in the Default Layout and those who yearn for days gone by can choose Classic Undocked to make the IDE look a little bit like Delphi 7.&lt;br /&gt;
&lt;br /&gt;
The Startup Layout is a nice option to switch to as a convenient way to undock all the tool windows taking up most of the editor space: Object Inspector, Structure, Project Manager and Tool Palette. With those shrunk down to the edges of the main window you can see much more of your code lines.&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/AVvXsEgIwTeUyxia7PYgAB4uNzQErlCM-Ez1AZIbv3Ku6nCtHbS1zFkWlwbx9mePDEvXqYQfMWlAsLeuXx1O6Oba0La4bsEHpmuuqbDAPDx8BJ32vJQokfKXstW0e9SwA0rdm7cgePewa60zA3g/s1600/desktops_1.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;129&quot; data-original-width=&quot;201&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIwTeUyxia7PYgAB4uNzQErlCM-Ez1AZIbv3Ku6nCtHbS1zFkWlwbx9mePDEvXqYQfMWlAsLeuXx1O6Oba0La4bsEHpmuuqbDAPDx8BJ32vJQokfKXstW0e9SwA0rdm7cgePewa60zA3g/s1600/desktops_1.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This tip is really just to make sure you know you can lay out the IDE windows any way you like and save &lt;i&gt;new&lt;/i&gt; Desktops. For example for developing you might want to undock the Object Inspector, Structure pane, Project Manager and Tool Palette, position them on your second monitor, thereby having a near full-screen editor but still having the other tool windows available. You might also want the Message window (View, Tool Windows, Messages or &lt;code&gt;Shift+Alt+M&lt;/code&gt;) visible but shrunk back to the bottom of the editor.&lt;br /&gt;
&lt;br /&gt;
Whatever your preferred window layout you can organise things as you like and then save it as a new Desktop to select as and when you choose:&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/AVvXsEgk9gMy9oGT9-hYReDVRH8m-YGvGLSFWdbBDbTcptnlFlbTywX4KEX3UnJtILCJ-jD7Aoofo6sI4TRYqHTEeDUrKcNTCZIfnQ9ApQLb9D5tXi4dvJjJ4FYc0AIhLVY-ZTOdmvVm-MkQrcI/s1600/desktops_2.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;225&quot; data-original-width=&quot;279&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgk9gMy9oGT9-hYReDVRH8m-YGvGLSFWdbBDbTcptnlFlbTywX4KEX3UnJtILCJ-jD7Aoofo6sI4TRYqHTEeDUrKcNTCZIfnQ9ApQLb9D5tXi4dvJjJ4FYc0AIhLVY-ZTOdmvVm-MkQrcI/s1600/desktops_2.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
19) Better editor font&lt;/h4&gt;
&lt;br /&gt;
RAD Studio still installs with Courier New as its default editor font.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbIc_0n_nkDHyzn-DAQI4CcXmxkSDBCfedSvqbGeuLRGRUt-xTmYY-WDhYAdOoyqfs_yuNDbb1SPaQek7Ocjplfsg4seiIkqj92NPP-6h042KSNCc-U0KEYmH7Hn07UPGAszjHMp89LHw/s1600/font_courier_new.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;302&quot; data-original-width=&quot;820&quot; height=&quot;233&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbIc_0n_nkDHyzn-DAQI4CcXmxkSDBCfedSvqbGeuLRGRUt-xTmYY-WDhYAdOoyqfs_yuNDbb1SPaQek7Ocjplfsg4seiIkqj92NPP-6h042KSNCc-U0KEYmH7Hn07UPGAszjHMp89LHw/s640/font_courier_new.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
That&#39;s a bit &quot;old hat&quot; these days so here are a few options that don&#39;t cost anything. Choose your favourite!&lt;br /&gt;
&lt;br /&gt;
Since Windows Vista we have a nicer monospaced IDE-friendly font called Consolas built right into Windows:&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/AVvXsEh-YCyYEdmLAxZpNNbMc1-IpoSfw0NACVwKqMUVTrjZ2rF5TteXI6XyLX6n_RVHwMxApeLmkpHZLFHM3uIykfcnRpruhglw6nL_SOHviU7RmVGgm48ny1H6C2iYdMS5Sx3-HKs3ulZb1ss/s1600/font_consolas.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;301&quot; data-original-width=&quot;819&quot; height=&quot;234&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-YCyYEdmLAxZpNNbMc1-IpoSfw0NACVwKqMUVTrjZ2rF5TteXI6XyLX6n_RVHwMxApeLmkpHZLFHM3uIykfcnRpruhglw6nL_SOHviU7RmVGgm48ny1H6C2iYdMS5Sx3-HKs3ulZb1ss/s640/font_consolas.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
For a longstanding programmer&#39;s font you could try &lt;a href=&quot;https://github.com/adobe-fonts/source-code-pro&quot;&gt;Source Code Pro&lt;/a&gt;:&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/AVvXsEi-asvK7e6k1g5rVo44YFW_bpMVpyXS1sbcMHDeaPqbAXGioHoK2BVSw0kVSw0arzfgQzOGx0jPjt0Zsi4XdEwGy9ztCYx8sJMA8i1xyDrkP30wTvgWI61aD3ZmASvFbNiLpvNEaY5sQvU/s1600/font_source_code_pro.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;301&quot; data-original-width=&quot;820&quot; height=&quot;233&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-asvK7e6k1g5rVo44YFW_bpMVpyXS1sbcMHDeaPqbAXGioHoK2BVSw0kVSw0arzfgQzOGx0jPjt0Zsi4XdEwGy9ztCYx8sJMA8i1xyDrkP30wTvgWI61aD3ZmASvFbNiLpvNEaY5sQvU/s640/font_source_code_pro.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want something more tailored to modern IDEs then you could try&amp;nbsp;&lt;a href=&quot;http://sourcefoundry.org/hack&quot;&gt;Hack&lt;/a&gt;:&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/AVvXsEhfosaxDhQARxViD62fU_-iQ1QmCw356cy2YIIXS6_eSai28HUQzw4BDxovmYk1ek6bmHqKclNWWPwRDl9usFBAKkEPP3P6pJqncNfkTNNcuuo8N4Kqkz0ZggXz_Dkr_mqJhU9M8pGcw98/s1600/font_hack.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;301&quot; data-original-width=&quot;820&quot; height=&quot;234&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfosaxDhQARxViD62fU_-iQ1QmCw356cy2YIIXS6_eSai28HUQzw4BDxovmYk1ek6bmHqKclNWWPwRDl9usFBAKkEPP3P6pJqncNfkTNNcuuo8N4Kqkz0ZggXz_Dkr_mqJhU9M8pGcw98/s640/font_hack.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Alternatively a new player in the field is&amp;nbsp;&lt;a href=&quot;https://www.jetbrains.com/lp/mono/&quot;&gt;JetBrains Mono&lt;/a&gt;:&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/AVvXsEgDq4CO0rVqx5YRuzdUzvrz_CBqNmIsJ1EossFFp_kE6PbXTCyelrYQ3o8DCNSBf2dtmMYsFspq1JGBqq3y1_-LZxIQ9n4jNFTq8whDJfOSW7U3RnGxOmMhcNPtLdSbHwti_58bA2aR198/s1600/font_jetbrains_mono.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;301&quot; data-original-width=&quot;819&quot; height=&quot;234&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDq4CO0rVqx5YRuzdUzvrz_CBqNmIsJ1EossFFp_kE6PbXTCyelrYQ3o8DCNSBf2dtmMYsFspq1JGBqq3y1_-LZxIQ9n4jNFTq8whDJfOSW7U3RnGxOmMhcNPtLdSbHwti_58bA2aR198/s640/font_jetbrains_mono.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
20) Alternate IDE profiles&lt;/h4&gt;
&lt;br /&gt;
Sometimes I feel the IDE is way too big and full of stuff I have no interest in. But I don&#39;t want to disable anything &lt;i&gt;just in case&lt;/i&gt;. Under these circumstances we do have the option to set up a whole new IDE profile within the registry that we can use to play and experiment with cutting down the &#39;bloat&#39; in the IDE, and also to set various different default options that we might want to try.&lt;br /&gt;
&lt;br /&gt;
The IDE supports various command-line switches as &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/IDE_Command_Line_Switches_and_Options&quot;&gt;documented in the docwiki&lt;/a&gt;. When you run RAD Studio no command-line switches are used. If you have the full RAD Studio then your Start menu group for RAD Studio will contain a Delphi shortcut and a C++Builder shortcut. These pass a personality command-line switch, either &lt;code&gt;-pDelphi&lt;/code&gt; or &lt;code&gt;-pCBuilder&lt;/code&gt;, when starting bds.exe.&lt;br /&gt;
&lt;br /&gt;
Another command-line switch that we can use to specify a registry profile is &lt;code&gt;-r&lt;/code&gt;. If I set up a shortcut to start bds.exe with a &lt;code&gt;-r TinyBDS&lt;/code&gt; command-line switch (or run it from a command prompt with that switch) then it will not use the default &lt;code&gt;HKEY_CURRENT_USER\Software\Embarcadero\BDS\20.0&lt;/code&gt; registry path but instead will use &lt;code&gt;HKEY_CURRENT_USER\Software\Embarcadero\TinyBDS\20.0&lt;/code&gt;, creating the new profile with a full set of defaults if necessary.&lt;br /&gt;
Now, to remove &#39;bloat&#39; we pick and choose IDE packages that we feel aren&#39;t giving us what we want and disable them. How do we do that? Well the IDE packages are all listed in this registry key (for my sample &lt;code&gt;TinyBDS&lt;/code&gt; registry profile): &lt;code&gt;HKEY_CURRENT_USER\Software\Embarcadero\TinyBDS\20.0\Known IDE Packages&lt;/code&gt;. There is also a subkey for the Delphi personality and a subkey for the C++Builder personality.&lt;br /&gt;
&lt;br /&gt;
To disable a package we either move the entry from this Known IDE Packages key and move it into the sibling &lt;code&gt;Disabled IDE Packages&lt;/code&gt; key, or we edit the package description and prefix it with an underscore. Either way it&#39;s a bit fiddly, so why don&#39;t we find a tool to help us?&lt;br /&gt;
&lt;br /&gt;
In Code Central there is &lt;a href=&quot;https://cc.embarcadero.com/Item/30127&quot;&gt;just such a tool&lt;/a&gt;, uploaded by the ever helpful Ray Vecchio. Download this IDE ad-in package source code, start up your IDE in the experimental registry profile, open the package, compile and install it.&lt;br /&gt;
&lt;br /&gt;
Now make sure you really started the IDE to use the new, experimental, expendable registry profile before you go and mess up your normal, default installation profile. Don&#39;t say I didn&#39;t warn you!&lt;br /&gt;
&lt;br /&gt;
To use the add-in choose Tools, Options... and select Third Party, Package Editor, Packages. Now you can go to the tabs labelled Known IDE Packages\Delphi and Known IDE Packages and check all the packages you feel like disabling. When you are done press Save, exit the IDE and restart it against the same registry profile. If you&#39;ve been too gung go the IDE might not start, in which case you&#39;ll need to try again with another registry profile.&lt;br /&gt;
&lt;br /&gt;
While testing this out to slim down my current Win32/64-targeting and VCL-only IDE I disabled these packages in Known IDE Packages\Delphi:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;delphifmxmobile260.bpl&lt;/li&gt;
&lt;li&gt;delphifmxide260.bpl&lt;/li&gt;
&lt;li&gt;delphierrorinsite260.bpl - this one goes back to Tip 12 (see above)&lt;/li&gt;
&lt;li&gt;delphiandroidservices260.bpl&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
and these in Known Packages:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;gdbdebugcore260.bpl&lt;/li&gt;
&lt;li&gt;gdbdebugide260.bpl&lt;/li&gt;
&lt;li&gt;ios32debugide260.bpl&lt;/li&gt;
&lt;li&gt;ios64debugide260.bpl&lt;/li&gt;
&lt;li&gt;tgide260.bpl&lt;/li&gt;
&lt;li&gt;DeviceManager260.bpl&lt;/li&gt;
&lt;li&gt;GuidedTour260.bpl&lt;/li&gt;
&lt;li&gt;MultiDevicePreview260.bpl&lt;/li&gt;
&lt;li&gt;LivePreview260.bpl&lt;/li&gt;
&lt;li&gt;MirrorHub260.bpl&lt;/li&gt;
&lt;li&gt;android64debugide260.bpl&lt;/li&gt;
&lt;li&gt;androiddebugide260.bpl&lt;/li&gt;
&lt;li&gt;delphiandroid260.bpl&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;
It may be that I can also remove some of the profile and SDK related packages, I haven&#39;t tried yet. What I do know is that when I start Delphi now (&lt;code&gt;bds.exe -pDelphi -r TinyBDS&lt;/code&gt;) it feels much quicker :)&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
21) Switch to FastMM4 for additional features&lt;/h4&gt;
&lt;br /&gt;
Long ago when Delphi 2006 came out the original Delphi memory manager was retired and replaced with the open source FastMM, written by Pierre Le Riche. Well, to be precise it was replaced with a cut down version of FastMM, the current version of which is FastMM4.&lt;br /&gt;
&lt;br /&gt;
FastMM improves upon the abilities of the original Delphi memory manager in typical application scenarios does a great job. That is, assuming you are looking at a Win32 or Win64 application - FastMM is used for Win32 and Win64. For other platforms the underlying POSIX memory manager is used.&lt;br /&gt;
&lt;br /&gt;
If it turns out your application has specific requirements that make FastMM not behave as well as you&#39;d like there are other memory managers out there that target specific usage scenarios; go and search them out.&lt;br /&gt;
&lt;br /&gt;
One of the benefits offered by FastMM is it includes the ability to spot when your application has leaked memory and can tell you on exit, and this is enabled by assigning True to the &lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/Rio/en/System.ReportMemoryLeaksOnShutdown&quot;&gt;&lt;code&gt;ReportMemoryLeaksOnShutdown&lt;/code&gt;&lt;/a&gt; System unit variable. Once you&#39;ve done this (as the first statement in your project file code block) any leaks get reported thus:&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/AVvXsEhSBbVRDnj-SVcIf72NqLAlBMFgFq5ZUO_zKYkhHGPE0ujrlQmnz098zUOuOSfbQ-Dc_mESWHmpaxnqAOiXQ2LtBeTGVygpBmJYsmQbfT8kzedquHk8KPAK8UmC2_zb4TltX4Nyb1nbiOo/s1600/fastmm_1.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;193&quot; data-original-width=&quot;397&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSBbVRDnj-SVcIf72NqLAlBMFgFq5ZUO_zKYkhHGPE0ujrlQmnz098zUOuOSfbQ-Dc_mESWHmpaxnqAOiXQ2LtBeTGVygpBmJYsmQbfT8kzedquHk8KPAK8UmC2_zb4TltX4Nyb1nbiOo/s1600/fastmm_1.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
This is good inasmuch as you know you have one or more memory leaks, but then leaves you high and dry. Where are they?!&lt;br /&gt;
&lt;br /&gt;
Fortunately the full version of FastMM improves things greatly on this score. If you download the full FastMM4 and add the FastMM4 unit as the first unit used in your project file and re-run you now get this message:&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/AVvXsEhdvi6IwTd5WA1ZYhUQw99jCLivHB5NxqAsdjrAXwC1ZcqRKiKkiOQ4EWGveJUiA4coz00-1VIqDFoB8nU8vEb-30XKQ6-uRVKaTyAnK-kO-hjxMqb_hhikl2sx8z2ihpvJD-q6KpvTuzM/s1600/fastmm_2.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;276&quot; data-original-width=&quot;412&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdvi6IwTd5WA1ZYhUQw99jCLivHB5NxqAsdjrAXwC1ZcqRKiKkiOQ4EWGveJUiA4coz00-1VIqDFoB8nU8vEb-30XKQ6-uRVKaTyAnK-kO-hjxMqb_hhikl2sx8z2ihpvJD-q6KpvTuzM/s1600/fastmm_2.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Open FastMM4&#39;s FastMM4Options.inc file and locate the comment that says &lt;i&gt;Option Grouping&lt;/i&gt; you can see where various symbols can be defined for Release and for Debug builds. In the Debug build section ensure that &lt;code&gt;FullDebugMode&lt;/code&gt; and &lt;code&gt;EnableMemoryLeakReporting&lt;/code&gt; are defined. Now make sure the FastMM_FullDebugMode.dll file is available in the folder your Debug build executable is created into and re-run. On exit it now says:&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/AVvXsEjSxXpW_TwXUxTl7c_ow7ASKB0FBasqQIjrvSYmiMzH3wRrob_xUUm2pgO5nk6pSb3YB3TqgvP3s8ntGWi0DP21OPX7CrOWB5VrwFznVEkP1dxknzGRI-k7UsKYkngqFgrkbyfzEQqSUL0/s1600/fastmm_3.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;250&quot; data-original-width=&quot;412&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSxXpW_TwXUxTl7c_ow7ASKB0FBasqQIjrvSYmiMzH3wRrob_xUUm2pgO5nk6pSb3YB3TqgvP3s8ntGWi0DP21OPX7CrOWB5VrwFznVEkP1dxknzGRI-k7UsKYkngqFgrkbyfzEQqSUL0/s1600/fastmm_3.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
If you locate that specified file and open it you will see similar information to what was on the message box:&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/AVvXsEg1nhEjm4YM5aJiHQ91_YtLI1gDxUaJjJQyRE0_LGYqWUC99sFZ0qARWKDOjShKGdS4ayrkKLGHiX6uRdCJbcQbMv2G4vMuEY2Oi0SxNZCzE8P5kDLmzvmMnMGqEBjnboD-9bcPjLh7GMk/s1600/fastmm_4.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;232&quot; data-original-width=&quot;813&quot; height=&quot;182&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1nhEjm4YM5aJiHQ91_YtLI1gDxUaJjJQyRE0_LGYqWUC99sFZ0qARWKDOjShKGdS4ayrkKLGHiX6uRdCJbcQbMv2G4vMuEY2Oi0SxNZCzE8P5kDLmzvmMnMGqEBjnboD-9bcPjLh7GMk/s640/fastmm_4.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
If you scroll further up the file you will see more detailed information about each leak, for example the string list leak is announced like this, complete with a call stack:&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/AVvXsEiCgfIDEltQb2sH_ItyuOoa0CQGfF4NrUDoORfidsOPxDvhSdJO25BoY7CDh6aX5Yg-Lf-rH-Mn5bL6CTK0I2azuJa6f27LjC-_5_dm3SZwdTphbilQUo9hETRS-uMmhlM28DyM8LCISOE/s1600/fastmm_5.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;729&quot; data-original-width=&quot;813&quot; height=&quot;571&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCgfIDEltQb2sH_ItyuOoa0CQGfF4NrUDoORfidsOPxDvhSdJO25BoY7CDh6aX5Yg-Lf-rH-Mn5bL6CTK0I2azuJa6f27LjC-_5_dm3SZwdTphbilQUo9hETRS-uMmhlM28DyM8LCISOE/s640/fastmm_5.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
This now arms us with much more information that we had with the default version of FastMM used by Delphi so we can head directly to the source of the leak and fix it.&lt;br /&gt;
The full FastMM also offers options for detecting heap corruption, interface misuse and more besides. Do yourself a favour and start using it if you haven&#39;t already done so.&lt;br /&gt;
&lt;br /&gt;
Note that what we are looking at here are handy benefits of the full version of the default memory manager. There are other leak detection tools and utilities that offer more than we get with FastMM4. I hope to look at one or two of them in the near future, but in the mean time reap the rewards of FastMM4.&lt;br /&gt;
&lt;br /&gt;
Useful links in the docwiki include:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Memory_Management&quot;&gt;Memory Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Configuring_the_Memory_Manager&quot;&gt;Configuring the Memory Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Registering_Memory_Leaks&quot;&gt;Registering Memory Leaks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;h4&gt;
22) Rebuild RTL source&lt;/h4&gt;
&lt;br /&gt;
If you need to make a tweak to a VCL or FMX file, this is feasible and (in some senses) reasonably common. You either copy that file, or maybe the whole VCL or FMX source directory (C:\Program&amp;nbsp;Files&amp;nbsp;(x86)\Embarcadero\Studio\20.0\source\vcl or C:\Program&amp;nbsp;Files&amp;nbsp;(x86)\Embarcadero\Studio\20.0\source\fmx) to somewhere else, add that location to your project source path, make your tweaks and rebuild.&lt;br /&gt;
&lt;br /&gt;
Rebuilding the RTL is slightly trickier due to the System.pas unit being something of a &#39;special case&#39;. If you want to rebuild the Win32 or Win64 RTL, or even the OSX RTL then there is a build batch file supplied in the RAD Studio installation that can assist.&lt;br /&gt;
&lt;br /&gt;
As before copy the RTL folder, C:\Program&amp;nbsp;Files&amp;nbsp;(x86)\Embarcadero\Studio\20.0\source\rtl, to somewhere else and make your tweaks. Then start a RAD Studio Command Prompt, use &lt;code&gt;CD&lt;/code&gt; to navigate to that RTL copy folder and run buildrtl.bat passing it a debug or a release command line parameter. If you want to build the RTL in a regular command prompt rather than a RAD Studio command prompt then modify where the batch file goes looking for RSVars.bat, which it calls if it can find it, to set the same environment variables up.&lt;br /&gt;
&lt;br /&gt;
I&#39;ll leave you there to pore over the contents of the batch file, which seems to be a little out of date now we have support for rather more platforms than Win32, Win64 and OSX, but it may be of use.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
23) Rebuild RTL Android Java source&lt;/h4&gt;
&lt;br /&gt;
Deeper down that the Pascal RTL source files, on occasion intrepid Android developers need to tweak the Java files that underlie RAD Studio&#39;s FireMonkey foundations. Sometimes a bug needs fixing, or an extension needs to be added to the raw GireMonkey Android activity to achieve a certain goal.&lt;br /&gt;
&lt;br /&gt;
Rebuilding those Java files can be done, but it&#39;s not necessarily obvious how to do it. This is why I went through the whole process recently in a dedicated post:&amp;nbsp;&lt;a href=&quot;http://blog.blong.com/2020/02/rebuilding-delphi-cbuilder-android-java.html&quot;&gt;Rebuilding the Delphi &amp;amp; C++Builder Android Java files&lt;/a&gt;. If you ever need to change the Java files you now know where to go for instructions on how to do it.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
24) RTL Easter Eggs&lt;/h4&gt;
&lt;br /&gt;
When you have had a hard day&#39;s programming and are looking for a little light relief, try perusing through the RTL, VCL and FMX source code seeing what you can find. As the ex-Borland R&amp;amp;D wizard Danny Thorpe used to say: &quot;&lt;i&gt;Use The Source, Luke&lt;/i&gt;&quot;. Sometimes you&#39;ll learn of new features and functions. Other times you might happen upon something that prompts a wry smile. Here are a couple of examples.&lt;br /&gt;
&lt;br /&gt;
Have you encountered the&amp;nbsp;&lt;code&gt;&lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/en/System.SysUtils.EProgrammerNotFound&quot;&gt;EProgrammerNotFound&lt;/a&gt;&lt;/code&gt;&amp;nbsp;exception class type, defined in System.SysUtils? I think I will be using that from time to time in the future.&lt;br /&gt;
&lt;br /&gt;
Also, the &lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/en/System.Devices.TDeviceInfo.TDeviceClass&quot;&gt;&lt;code&gt;TDeviceClass&lt;/code&gt;&lt;/a&gt; enumerated type in System.Devices.pas, which as well as sensible members such as &lt;code&gt;Phone&lt;/code&gt;, &lt;code&gt;Tablet&lt;/code&gt; and &lt;code&gt;Watch&lt;/code&gt; also has some more interesting members: &lt;code&gt;Elf&lt;/code&gt;&amp;nbsp;(no relation to the &lt;a href=&quot;https://en.wikipedia.org/wiki/Executable_and_Linkable_Format&quot;&gt;ELF&lt;/a&gt; Unix executable file format), &lt;code&gt;Dwarf&lt;/code&gt; and &lt;code&gt;Wizard&lt;/code&gt;&amp;nbsp;as explained &lt;a href=&quot;http://docwiki.embarcadero.com/Libraries/en/System.Devices.TDeviceInfo.TDeviceClass#Description&quot;&gt;in the docwiki&lt;/a&gt;:&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/AVvXsEgvBh-daZu1S954C_rKNLCWB5T8l8UOFRjEE5RwoODyZwPDwDPpqbE4-yezrul1RHzr51EtrOSoTpEWAJ3Q_gYqJuchRa4PliXDz25TdIo3ZD4kkt-agboD0evzbGL6sGGRaXPd3WojTEU/s1600/egg_1.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;778&quot; data-original-width=&quot;893&quot; height=&quot;555&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvBh-daZu1S954C_rKNLCWB5T8l8UOFRjEE5RwoODyZwPDwDPpqbE4-yezrul1RHzr51EtrOSoTpEWAJ3Q_gYqJuchRa4PliXDz25TdIo3ZD4kkt-agboD0evzbGL6sGGRaXPd3WojTEU/s640/egg_1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvBh-daZu1S954C_rKNLCWB5T8l8UOFRjEE5RwoODyZwPDwDPpqbE4-yezrul1RHzr51EtrOSoTpEWAJ3Q_gYqJuchRa4PliXDz25TdIo3ZD4kkt-agboD0evzbGL6sGGRaXPd3WojTEU/s1600/egg_1.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
25) IDE Easter Egg&lt;/h4&gt;
&lt;br /&gt;
Invoke the About box with Help, About..., then hold down &lt;code&gt;Alt&lt;/code&gt; whilst typing &lt;code&gt;TEAM&lt;/code&gt;. This produces a scrolling team list of members of the development team. You can also hold&amp;nbsp;&lt;code&gt;Al&lt;/code&gt;&lt;code&gt;t+KUDOS&lt;/code&gt;&amp;nbsp;for a list of those who have contributed to the product:&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;http://blong.com/images/Eggs/Delphi10.3Rio_Kudos.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://blong.com/images/Eggs/Delphi10.3Rio_Kudos.png&quot; width=&quot;600&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Double-click on any name in the development team list and you get some team pictures:&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;http://blong.com/images/Eggs/Delphi10.3Rio_Carnival.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://blong.com/images/Eggs/Delphi10.3Rio_Carnival.png&quot; width=&quot;600&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
If you hold &lt;code&gt;Alt&lt;/code&gt; and type &lt;code&gt;GUNGLA&lt;/code&gt; you get to see Tequila Joe Monkey on a surfboard:
&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;http://blong.com/images/Eggs/Gungla.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://blong.com/images/Eggs/Gungla.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
And why is this? Well, who knows? But a little monkey business is a good way to wrap this post up.</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/4801172506271619820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2020/02/25-delphi-tips-for-25-years-of-delphi.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4801172506271619820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4801172506271619820'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2020/02/25-delphi-tips-for-25-years-of-delphi.html' title='25 Delphi Tips for 25 Years of Delphi'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIOPkaYnYv20ohA5hvE8kbArP2MA3_y9dGhY0IZyILx3ClgR-GyH0wZ2p5iku4H0kRSmzKUzD9a6CHRH4iBVL896jRUmg6eUXn4CNCMD7w5gOjl2HTuE5cGkc56ab65dFBbNVMqjE0g_c/s72-c?imgmax=800" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-1394105944213464924</id><published>2020-02-12T01:55:00.000-08:00</published><updated>2020-02-12T01:57:34.689-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>The Enter key and the OnKeyDown/OnKeyUp events on Android</title><content type='html'>A problem surfaced &lt;a href=&quot;https://stackoverflow.com/questions/59851405&quot;&gt;on Stack Overflow&lt;/a&gt; recently from a Delphi developer, Tom Byrnes, who discovered that on Android, the Enter (or Return) key no longer triggers the &lt;code&gt;OnKeyDown&lt;/code&gt; and &lt;code&gt;OnKeyUp&lt;/code&gt; events. This was unfortunate as Tom wanted to code to run in (one of) those handlers.&lt;br /&gt;
&lt;br /&gt;
The problem had been reported as&amp;nbsp;&lt;a href=&quot;https://quality.embarcadero.com/browse/RSP-27496&quot;&gt;RSP-27496&lt;/a&gt; but alas it had been closed at the time Tom was hunting for a solution (to my mind closed wrongly).&lt;br /&gt;
&lt;br /&gt;
What to do?&lt;br /&gt;
&lt;br /&gt;
Well, after some valiant fighting with the problem accompanied with the inevitable wailing and gnashing of teeth, Tom found &lt;a href=&quot;https://stackoverflow.com/a/59940492/2817399&quot;&gt;a workaround of sorts&lt;/a&gt;. Setting the &lt;code&gt;TEdit&lt;/code&gt; control&#39;s &lt;code&gt;ReturnKeyType&lt;/code&gt; property &lt;code&gt;Go&lt;/code&gt;, &lt;code&gt;Search&lt;/code&gt; or &lt;code&gt;Send&lt;/code&gt; allows the &lt;code&gt;OnKeyDown&lt;/code&gt; event to fire for the Enter key. Good stuff! But not ideal....&lt;br /&gt;
&lt;br /&gt;
I sent a note to a relevant party within EMBT and after reviewing the report it has since been re-opened. That&#39;s a start.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;To try and be a bit more helpful I&#39;d like to offer a solution to having the Enter key get &lt;code&gt;OnKeyDown&lt;/code&gt; and &lt;code&gt;OnKeyUp&lt;/code&gt; events triggered. This involves editing one of the Java files that underpins the Delphi Android FireMonkey. implementation&lt;br /&gt;
&lt;br /&gt;
The default RAD Studio installation for 10.3.3 is to &lt;code&gt;C:\Program&amp;nbsp;Files&amp;nbsp;(x86)\Embarcadero\Studio\20.0&lt;/code&gt;. If we assume an environment variable &lt;code&gt;BDS&lt;/code&gt; is set to that value (as it is in a RAD Studio Command Prompt) then the Java source files can be found in:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;%BDS%\source\rtl\androiddex\java\fmx\src\com\embarcadero\firemonkey&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
The file of interest is in a subfolder and is:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;text\FMXEditText.java&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
so to put it another way:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;%BDS%\source\rtl\androiddex\java\fmx\src\com\embarcadero\firemonkey\text\FMXEditText.java&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
In this file just over halfway down is a routine called &lt;code&gt;onEditorAction&lt;/code&gt;, which needs a slight tweak. It&#39;s only a short subroutine, but if you examine the logic you&#39;ll appreciate that it contains a condition with some logic in the &lt;code&gt;if&lt;/code&gt; section and some more logic in the &lt;code&gt;else&lt;/code&gt; section.&lt;br /&gt;
&lt;br /&gt;
The required change is to remove the else section and leave the logic currently contained there to run unconditionally. I don&#39;t want to copy out code from the RTL to avoid transgressing any inappropriate boundaries, but if the code currently looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background: rgb(255, 255, 255);&quot;&gt;&lt;span style=&quot;color: maroon; font-weight: bold;&quot;&gt;public&lt;/span&gt; void onEditorAction(int actionCode) &lt;span style=&quot;color: purple;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: maroon; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #808030;&quot;&gt;(&lt;/span&gt;condition&lt;span style=&quot;color: #808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: purple;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: dimgrey;&quot;&gt;// if block&lt;/span&gt;
    &lt;span style=&quot;color: purple;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;color: maroon; font-weight: bold;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: purple;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: dimgrey;&quot;&gt;// else block&lt;/span&gt;
    &lt;span style=&quot;color: purple;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: purple;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;br /&gt;
we want to alter it to look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background: rgb(255, 255, 255);&quot;&gt;&lt;span style=&quot;color: maroon; font-weight: bold;&quot;&gt;public&lt;/span&gt; void onEditorAction(int actionCode) &lt;span style=&quot;color: purple;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: maroon; font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #808030;&quot;&gt;(&lt;/span&gt;condition&lt;span style=&quot;color: #808030;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: purple;&quot;&gt;{&lt;/span&gt;
        &lt;span style=&quot;color: dimgrey;&quot;&gt;// if block&lt;/span&gt;
    &lt;span style=&quot;color: purple;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: dimgrey;&quot;&gt;// else block&lt;/span&gt;
&lt;span style=&quot;color: purple;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;br /&gt;
Assuming this is all done, what next?&lt;br /&gt;
&lt;br /&gt;
Well the next step is to rebuild all the Java files and replace the compiled Java archives with the updated re-compiled ones. Fortunately I can help out there. &lt;a href=&quot;http://blog.blong.com/2020/02/rebuilding-delphi-cbuilder-android-java.html&quot;&gt;I posted yesterday a full command script&lt;/a&gt; that will do just this exact job, so please make use of that to follow the required steps to get the fix.&lt;br /&gt;
&lt;br /&gt;
Once you have run the script to generate new Java archives and re-built and re-run your Android app your events should trigger on Android when you press the soft Enter key.&lt;br /&gt;
&lt;br /&gt;
One final thing: don&#39;t forget to backup the original Java archive files before running the script as mentioned in the post!</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/1394105944213464924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2020/02/the-enter-key-and-onkeydown-event-on.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/1394105944213464924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/1394105944213464924'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2020/02/the-enter-key-and-onkeydown-event-on.html' title='The Enter key and the OnKeyDown/OnKeyUp events on Android'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-8864612851871989335</id><published>2020-02-11T08:41:00.000-08:00</published><updated>2020-02-11T09:53:53.836-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><title type='text'>C++Builder&#39;s Android location sensor woes</title><content type='html'>There is an unfortunate problem with RAD Studio 10.3.3 for anyone using C++Builder building Android applications. However it has a quite straightforward resolution, so let&#39;s look at what the issue is.&lt;br /&gt;
&lt;br /&gt;
If you make a new Multi-Device Application in C++Builder and build it, all will be well, of course. The basics work very nicely.&lt;br /&gt;
&lt;br /&gt;
If you now drop a &lt;code&gt;TLocationSensor&lt;/code&gt; component on the form and try to build now, the result will be different. Compilation goes fine. Linking &lt;i&gt;looks&lt;/i&gt; like it is going fine.... until it fails with a rather unhelpful message:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;[ldandroid Error] &quot;ld&quot; exited with code 1.&lt;/pre&gt;
&lt;br /&gt;
Let&#39;s look at how we can get more useful feedback from this rather opaque and somewhat 1990s error message and see how to resolve the underlying problem.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;If you examine the Message window closely you will see immediately above that error message there is an expandable item that says:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;gt; ldandroid command line&lt;/pre&gt;
&lt;br /&gt;
No need to expand it, just right-click on that entry and choose Copy. Paste that into a text editor (preferably something better than Notepad). Depending on the editor and the options enabled within it you&#39;ll be looking at something approximately like this:&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/AVvXsEis9aRUBtvdPlwK3wTNZHt7AGWiACd-sa25KQWGIfCpPAm3PVeJhBLLg73kwmy1FIfKwUlf51HkS2evOmE9gUzpZ5YbJVVIBVHYZbhcexF4odFp5mVYbWMdLQuzSBYjSzLBsmAjPUqiSFE/s1600/bcb_link_cmd_line_1.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;256&quot; data-original-width=&quot;1580&quot; height=&quot;103&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis9aRUBtvdPlwK3wTNZHt7AGWiACd-sa25KQWGIfCpPAm3PVeJhBLLg73kwmy1FIfKwUlf51HkS2evOmE9gUzpZ5YbJVVIBVHYZbhcexF4odFp5mVYbWMdLQuzSBYjSzLBsmAjPUqiSFE/s640/bcb_link_cmd_line_1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
You&#39;ll notice that we have a command-line broken into multiple shorter lines with a prefix line that is not part of the command-line proper. You&#39;ll need to delete the top line, then conjoin all the subsequent lines into one long command line, leaving you with a single long line, which when wrapped in my same editor looks like this:&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/AVvXsEi8sTxqmEPHy00QwSs36gsZ5Csu6kqlZlz0va11HJFHVFTuPn0j0WUZQ1c3ems66JZ2P7wthhyphenhyphenHX418un0ZiCs8VDTu9rmM2x9Vp3YMPFD75XrcRXSRqX0NzVY_FBmtRy1Wn0t9peO4GXE/s1600/bcb_link_cmd_line_2.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;225&quot; data-original-width=&quot;1586&quot; height=&quot;91&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8sTxqmEPHy00QwSs36gsZ5Csu6kqlZlz0va11HJFHVFTuPn0j0WUZQ1c3ems66JZ2P7wthhyphenhyphenHX418un0ZiCs8VDTu9rmM2x9Vp3YMPFD75XrcRXSRqX0NzVY_FBmtRy1Wn0t9peO4GXE/s640/bcb_link_cmd_line_2.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Now launch a RAD Studio Command Prompt (hit the Windows Start button and start typing in RAD and it should be offered to you as an option).&lt;br /&gt;
&lt;br /&gt;
Use the &lt;code&gt;CD /D&lt;/code&gt; command to change to the drive and folder in which your project resides&lt;br /&gt;
&lt;br /&gt;
Go back to the long command-line in your editor and copy it into the clipboard and then paste it into the command prompt window.&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/AVvXsEjYPeFTvLl-Ql6Ng8ldG66A-gRfSa6pJy87D6jpEFjiG3tllwjDWufcOLX3O52a7fPRk7laJIRjcxs4gLVkmeeRf2S1fd0LyZHgWxCsklzvzlMzaOc2EYLLSFqiowzsGGxxcd0DBMgngVc/s1600/bcb_link_cmd_line_3.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;512&quot; data-original-width=&quot;979&quot; height=&quot;334&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYPeFTvLl-Ql6Ng8ldG66A-gRfSa6pJy87D6jpEFjiG3tllwjDWufcOLX3O52a7fPRk7laJIRjcxs4gLVkmeeRf2S1fd0LyZHgWxCsklzvzlMzaOc2EYLLSFqiowzsGGxxcd0DBMgngVc/s640/bcb_link_cmd_line_3.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Pressing&amp;nbsp;&amp;nbsp;&lt;code&gt;Enter&lt;/code&gt;. will run the same command outside the IDE giving you a more representative set of error messages that the IDE hasn&#39;t managed to parse and list for you.&lt;br /&gt;
&lt;br /&gt;
Because of the long lines, another screenshot of the resultant command window isn&#39;t the best way to read the errors. Instead I have redirected the error output (the linker&#39;s stderr output) to a text file so I can paste it here making it easier to read. stderr can be redirected to file by adding this to the end of the command line:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;2&amp;gt; a.txt&lt;/pre&gt;
&lt;br /&gt;
The content of the file is 9 errors. Each error consists of a line highlighting the problem module and a brief error message, and a line with a fuller message. The problem module in each case (so I don&#39;t need to repetitively include it) is:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;c:\program files (x86)\embarcadero\studio\20.0\lib\Android\debug\librtl.a(Androidapi.Sensor.o)&lt;/pre&gt;
&lt;br /&gt;
The rest of the error message text looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;In function `Androidapi::Sensor::ASensorManager_getInstanceForPackage(char const*)&#39;:
Androidapi.Sensor:(.text._ZN10Androidapi6Sensor36ASensorManager_getInstanceForPackageEPKc[_ZN10Androidapi6Sensor36ASensorManager_getInstanceForPackageEPKc]+0x4): undefined reference to `ASensorManager_getInstanceForPackage&#39;
In function `Androidapi::Sensor::ASensorManager_getDefaultSensorEx(ASensorManager*, int, bool)&#39;:
Androidapi.Sensor:(.text._ZN10Androidapi6Sensor33ASensorManager_getDefaultSensorExEP14ASensorManagerib[_ZN10Androidapi6Sensor33ASensorManager_getDefaultSensorExEP14ASensorManagerib]+0x4): undefined reference to `ASensorManager_getDefaultSensorEx&#39;
In function `Androidapi::Sensor::ASensorManager_createSharedMemoryDirectChannel(ASensorManager*, int, unsigned int)&#39;:
Androidapi.Sensor:(.text._ZN10Androidapi6Sensor46ASensorManager_createSharedMemoryDirectChannelEP14ASensorManagerij[_ZN10Androidapi6Sensor46ASensorManager_createSharedMemoryDirectChannelEP14ASensorManagerij]+0x4): undefined reference to `ASensorManager_createSharedMemoryDirectChannel&#39;
In function `Androidapi::Sensor::ASensorManager_createHardwareBufferDirectChannel(ASensorManager*, Androidapi::Sensor::AHardwareBuffer_*, unsigned int)&#39;:
Androidapi.Sensor:(.text._ZN10Androidapi6Sensor48ASensorManager_createHardwareBufferDirectChannelEP14ASensorManagerPNS0_16AHardwareBuffer_Ej[_ZN10Androidapi6Sensor48ASensorManager_createHardwareBufferDirectChannelEP14ASensorManagerPNS0_16AHardwareBuffer_Ej]+0x4): undefined reference to `ASensorManager_createHardwareBufferDirectChannel&#39;
In function `Androidapi::Sensor::ASensorManager_destroyDirectChannel(ASensorManager*, int)&#39;:
Androidapi.Sensor:(.text._ZN10Androidapi6Sensor35ASensorManager_destroyDirectChannelEP14ASensorManageri[_ZN10Androidapi6Sensor35ASensorManager_destroyDirectChannelEP14ASensorManageri]+0x4): undefined reference to `ASensorManager_destroyDirectChannel&#39;
In function `Androidapi::Sensor::ASensorManager_configureDirectReport(ASensorManager*, ASensor*, int, int)&#39;:
Androidapi.Sensor:(.text._ZN10Androidapi6Sensor36ASensorManager_configureDirectReportEP14ASensorManagerP7ASensorii[_ZN10Androidapi6Sensor36ASensorManager_configureDirectReportEP14ASensorManagerP7ASensorii]+0x4): undefined reference to `ASensorManager_configureDirectReport&#39;
In function `Androidapi::Sensor::ASensorEventQueue_registerSensor(ASensorEventQueue*, ASensor*, int, long long)&#39;:
Androidapi.Sensor:(.text._ZN10Androidapi6Sensor32ASensorEventQueue_registerSensorEP17ASensorEventQueueP7ASensorix[_ZN10Androidapi6Sensor32ASensorEventQueue_registerSensorEP17ASensorEventQueueP7ASensorix]+0x16): undefined reference to `ASensorEventQueue_registerSensor&#39;
In function `Androidapi::Sensor::ASensor_isDirectChannelTypeSupported(ASensor*, int)&#39;:
Androidapi.Sensor:(.text._ZN10Androidapi6Sensor36ASensor_isDirectChannelTypeSupportedEP7ASensori[_ZN10Androidapi6Sensor36ASensor_isDirectChannelTypeSupportedEP7ASensori]+0x4): undefined reference to `ASensor_isDirectChannelTypeSupported&#39;
In function `Androidapi::Sensor::ASensor_getHighestDirectReportRateLevel(ASensor*)&#39;:
Androidapi.Sensor:(.text._ZN10Androidapi6Sensor39ASensor_getHighestDirectReportRateLevelEP7ASensor[_ZN10Androidapi6Sensor39ASensor_getHighestDirectReportRateLevelEP7ASensor]+0x4): undefined reference to `ASensor_getHighestDirectReportRateLevel&#39;
&lt;/pre&gt;
&lt;br /&gt;
What we are looking at here are a bunch of symbols that are defined in the Delphi RTL file&amp;nbsp;Androidapi.Sensor.pas as symbols to be imported from the Android library&amp;nbsp;libandroid.so, but which are not actually present in the one being linked to from the NDK platform folder specified in your SDK definition, which is likely to be 22.&lt;br /&gt;
&lt;br /&gt;
Huh?&lt;br /&gt;
&lt;br /&gt;
OK, the important thing here is what we can do about the problem. The answer is that you need to take a copy of the files Androidapi.Sensor.pas and Androidapi.inc from C:\Program Files (x86)\Embarcadero\Studio\20.0\source\rtl\android\ and put them in your project folder (or somewhere you can reference).&lt;br /&gt;
&lt;br /&gt;
Add the file to your project using the Project Manager&#39;s context menu (remembering to choose Pascal unit (*.pas) from the list of file type filters in order to see the Delphi unit.&lt;br /&gt;
&lt;br /&gt;
Now open the unit in the editor and hunt down these 14 symbols. For each of them comment out the entirety of the definition (select the whole definition and press &lt;code&gt;Ctrl+/&lt;/code&gt;):&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ASensorManager_getInstanceForPackage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ASensorManager_getDefaultSensorEx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ASensorManager_createSharedMemoryDirectChannel&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ASensorManager_createHardwareBufferDirectChannel&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ASensorManager_destroyDirectChannel&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ASensorManager_configureDirectReport&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ASensorEventQueue_registerSensor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ASensor_isDirectChannelTypeSupported&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ASensor_getHighestDirectReportRateLevel&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
You&#39;ll notice that these APIs are pretty much all commented as new in API 26 (though one seems to be missed, &lt;code&gt;ASensorEventQueue_registerSensor&lt;/code&gt;). It is this fact that causes the issue. Your application is linking against the API 22 library, which does not expose these symbols and so they should not be present in the unit.&lt;br /&gt;
&lt;br /&gt;
You should find that you can now rebuild your project successfully.</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/8864612851871989335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2020/02/cbuilders-android-location-sensor-woes.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/8864612851871989335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/8864612851871989335'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2020/02/cbuilders-android-location-sensor-woes.html' title='C++Builder&#39;s Android location sensor woes'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis9aRUBtvdPlwK3wTNZHt7AGWiACd-sa25KQWGIfCpPAm3PVeJhBLLg73kwmy1FIfKwUlf51HkS2evOmE9gUzpZ5YbJVVIBVHYZbhcexF4odFp5mVYbWMdLQuzSBYjSzLBsmAjPUqiSFE/s72-c/bcb_link_cmd_line_1.png" height="72" width="72"/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-7798134372640972985</id><published>2020-02-11T06:53:00.000-08:00</published><updated>2020-02-12T01:35:35.095-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>Rebuilding the Delphi &amp; C++Builder Android Java files</title><content type='html'>&lt;a href=&quot;http://blog.blong.com/2018/12/rad-studio-103-rios-android-intent.html&quot; target=&quot;_blank&quot;&gt;Some while back I posted&lt;/a&gt; a command script (or &lt;i&gt;batch file&lt;/i&gt; as we used to call them) that could be used by RAD Studio 10.3 users if they felt the need to change any of the few Java files underlying Delphi&#39;s (and C++Builder&#39;s) Android RTL and FireMonkey code.&lt;br /&gt;
&lt;br /&gt;
The script would rebuild all the Java files into the required fmx.dex.jar and fmx.jar archives and copy them into the relevant RAD Studio installation folders to be used on subsequent builds.&lt;br /&gt;
&lt;br /&gt;
When I tried to use the script with RAD Studio 10.3.3 of course it didn&#39;t work as things have changed, different files need to be involved in the process. I have updated the script now to work with RAD Studio 10.3.3 and thought I&#39;d share it in case anyone else needs to do this.&lt;br /&gt;
&lt;br /&gt;
An obvious question is: &lt;i&gt;Why would anyone else want to rebuild the Java Android RTL files?&lt;/i&gt; Well this is normally a necessary step if you find an issue in the code as Embarcadero ships it and you want to try to fix it or enhance it. Indeed the previous post on rebuilding the 10.3 Java files was all about patching the Java code to get Android &lt;code&gt;Intent&lt;/code&gt;&amp;nbsp;support working.&lt;br /&gt;
&lt;br /&gt;
If you have no interest in tweaking the Java code or fixing any issues you encounter in the Java code then you probably won&#39;t be needing this script.&lt;br /&gt;
&lt;br /&gt;
If you do need the script, remember to take a backup of your original compiled archives before you proceed. These are found in:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\debug\fmx.jar&lt;/li&gt;
&lt;li&gt;C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\debug\fmx.dex.jar&lt;/li&gt;
&lt;li&gt;C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\release\fmx.jar&lt;/li&gt;
&lt;li&gt;C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\release\fmx.dex.jar&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
The script needs to be run from an administrative command prompt and before you run it you should double-check the various paths set up in the environment variables at the start are all valid on your system.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;The script can be found below (apologies for any layout issues caused by longer lines than the narrow blog width); hat-tip and thanks to Tom Byrnes for test-driving it:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;@echo off
cls

rem Android RTL Java files rebuilder for RAD Studio 10.3.3

setlocal enabledelayedexpansion

rem Set environment variables
rem *NOTE*: check these folders match your setup

set EMBT=Embarcadero\Studio\20.0
set BDS=%ProgramFiles(x86)%\%EMBT%
set JAVA_PATH=%ProgramFiles%\Java\jdk1.8.0_60\bin
rem This is the default path for the Android SDK when installed from the .iso installer
set SDK_PATH=%PUBLIC%\Documents\%EMBT%\PlatformSDKs\android-sdk-windows
if not exist &quot;%SDK_PATH%\&quot; (
  rem This is the default path for the Android SDK when installed from the web install (aka ESD install)
  set SDK_PATH=%PUBLIC%\Documents\%EMBT%\CatalogRepository\AndroidSDK-2525_20.0.36039.7899
)

rem Set more environment variables based on those above

set DX_PATH=%SDK_PATH%\build-tools\28.0.2
set ANDROID_JAR=%SDK_PATH%\platforms\android-26\android.jar
set BDS_LIB=%BDS%\lib
set BDS_DEBUG_LIB=%BDS%\lib\android\debug
set BDS_RELEASE_LIB=%BDS%\lib\android\release
set FMX_SRC_PATH=%BDS%\source\rtl\androiddex\java\fmx
set CLASS_PATH=%ANDROID_JAR%
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\android-support-v4.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\cloud-messaging.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-base.16.0.1.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-maps.16.1.0.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\debug\com-google-android-gms.play-services-ads.17.2.0.jar
rem For adListener
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-ads-lite.17.2.0.jar
rem For AbstractSafeParcelable
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-basement.16.2.0.jar
rem For ReflectedParcelable
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-basement.16.2.0.jar

echo.
echo Checking environment variables

if not exist &quot;%BDS%\&quot; (
  echo Path used to set BDS environment variable does not exist^^! Is RAD Studio installed elsewhere?
  goto :Error
)

if not exist &quot;%JAVA_PATH%\&quot; (
  echo Path used to set JAVA_PATH environment variable does not exist^^! Is the JDK installed elsewhere?
  goto :Error
)

if not exist &quot;%SDK_PATH%\&quot; (
  echo Path used to set SDK_PATH environment variable does not exist^^! Is the Android SDK installed elsewhere?
  goto :Error
)

if not exist &quot;%ANDROID_JAR%&quot; (
  echo Path used to set ANDROID_JAR environment variable does not exist^^! Is your android.jar in a different platform folder?
  goto :Error
)

echo.
echo Changing to the FMX source folder
echo.

pushd %FMX_SRC_PATH%

echo Getting fully qualified list of all Java source file we need to rebuild
echo.

if not exist bin\classes mkdir bin\classes
if not exist bin\debug mkdir bin\debug
if not exist bin\release mkdir bin\release
dir src\android\bluetooth\*.java /s /b &amp;gt; JavaSources.txt
dir src\android\telephony\*.java /s /b &amp;gt;&amp;gt; JavaSources.txt
dir src\com\*.java /s /b &amp;gt;&amp;gt; JavaSources.txt

echo Ensuring FMX source path ends in a &#39;\&#39;
echo.

set LAST_CHAR=%FMX_SRC_PATH:~-1%
if not &quot;%LAST_CHAR%&quot;==&quot;\&quot; set FMX_SRC_PATH=%FMX_SRC_PATH%\

echo Making Java source file paths relative to current directory
echo.

if exist JavaSources2.txt del JavaSources2.txt
for /F &quot;tokens=*&quot; %%A in (JavaSources.txt) do (
  set STR=%%A
  set &quot;STR=!STR:%FMX_SRC_PATH%=!&quot;
  echo !STR!&amp;gt;&amp;gt;JavaSources2.txt
)

echo Compiling all the FMX Java code into class files with debug info
echo.

&quot;%JAVA_PATH%&quot;\javac -g -d bin\classes -classpath &quot;%CLASS_PATH%&quot; -encoding UTF-8 -g @JavaSources2.txt
if errorlevel 1 (
  echo.
  echo Problem encountered during Java compilation
  goto :Error
)

echo.
echo Creating jar containing the new compiled FMX Java classes with debug info
echo.

&quot;%JAVA_PATH%&quot;\jar cf bin\debug\fmx.jar -C bin\classes .
if errorlevel 1 (
  echo.
  echo Problem encountered during Java archiving
  goto :Error
)

echo Creating DEX jar containing the new compiled FMX Java classes with debug info
echo.

call %DX_PATH%\dx --dex --output=bin\debug\fmx.dex.jar --positions=lines bin\debug\fmx.jar
if errorlevel 1 (
  echo.
  echo Problem encountered during DEXing
  goto :Error
)

echo Compiling all the FMX Java code into class files without debug info
echo.

&quot;%JAVA_PATH%&quot;\javac -g:none -d bin\classes -classpath &quot;%CLASS_PATH%&quot; -encoding UTF-8 @JavaSources2.txt
if errorlevel 1 (
  echo.
  echo Problem encountered during Java compilation
  goto :Error
)

echo.
echo Creating jar containing the new compiled FMX Java classes without debug info
echo.

&quot;%JAVA_PATH%&quot;\jar cf bin\release\fmx.jar -C bin\classes .
if errorlevel 1 (
  echo.
  echo Problem encountered during Java archiving
  goto :Error
)

echo Creating DEX jar containing the new compiled FMX Java classes without debug info
echo.

call %DX_PATH%\dx --dex --output=bin\release\fmx.dex.jar --positions=lines bin\release\fmx.jar
if errorlevel 1 (
  echo.
  echo Problem encountered during DEXing
  goto :Error
)

copy bin\debug\* &quot;%BDS_DEBUG_LIB%&quot;
copy bin\release\* &quot;%BDS_RELEASE_LIB%&quot;

echo Tidying up...
echo.
if exist JavaSources.txt del JavaSources.txt
if exist JavaSources2.txt del JavaSources2.txt
rd /s /q bin

goto :End

:Error
echo.
echo Sorry, we had a problem :(
echo.

:End

echo Changing back to the folder we started in

popd

endlocal
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/7798134372640972985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2020/02/rebuilding-delphi-cbuilder-android-java.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/7798134372640972985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/7798134372640972985'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2020/02/rebuilding-delphi-cbuilder-android-java.html' title='Rebuilding the Delphi &amp; C++Builder Android Java files'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-2643957501729836821</id><published>2019-01-08T11:44:00.001-08:00</published><updated>2019-01-08T11:47:38.520-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="iPhone"/><title type='text'>Solution to iOS Delphi build failure</title><content type='html'>&lt;p&gt;Some Delphi users building iOS applications have been thwarted by a…, well let’s be polite and call it a bit of an annoyance, when building their applications. What should just be an informational message about a warning from the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/C%2B%2B_Linker&quot; target=&quot;_blank&quot;&gt;ld linker&lt;/a&gt; ends up becoming a build breaker. The failure message looks something like this example (taken from &lt;a href=&quot;https://quality.embarcadero.com/browse/RSP-19759&quot; target=&quot;_blank&quot;&gt;RSP-19759&lt;/a&gt;, reported in January 2018):&lt;/p&gt;&lt;pre&gt;[DCC Error] E2597 ld: warning: unknown dwarf DW_FORM_strp (offset=0xFFFFCEE7) is&lt;br&gt;    too big in FBSDKShareKit.a(FBSDKAppInviteContent.o)
  ld: warning: unknown dwarf DW_FORM_strp (offset=0xFFFF6E38) is too big&lt;br&gt;    in C:\Dev\lib\ios\facebook\FBSDKShareKit.framework\FBSDKShareKit.a&lt;br&gt;    (FBSDKAppInviteContent.o)&lt;/pre&gt;
&lt;p&gt;The fact that ld is emitting a warning about something is neither here not there. Or rather it *should* be neither here nor there. Unfortunately when Delphi receives this warning it turns it into a fatal error.&lt;/p&gt;&lt;p&gt;Oh dear… (・_・、)&lt;/p&gt;&lt;p&gt;Delphi 10.3 Rio contains a change to address this issue…. ˚◡˚&lt;/p&gt;&lt;p&gt;Unfortunately, however,  Embarcadero forgot to mention it to anyone ¯\_(ツ)_/¯&lt;/p&gt;&lt;p&gt;This post tries to fix that communications oversight by covering the details of the change, which is an important step as you do need to add in a new compiler / linker switch.&lt;/p&gt;&lt;p&gt;The iOS ld linker now supports a new option &lt;code&gt;–bequiet&lt;/code&gt;, which stops Delphi being able to wrongly interpret the ld warnings (by silencing them).&lt;/p&gt;&lt;p&gt;To use the new option choose Project | Options…&amp;nbsp; (&lt;code&gt;Shift+Ctrl+F11&lt;/code&gt;) and do one of these two things:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;select Building | Delphi Compiler | Compiling | Other Options and add &lt;code&gt;--linker-option:-bequiet&lt;/code&gt; to Additional options to pass to the compiler, or&lt;/li&gt;&lt;li&gt;select Building | Delphi Compiler | Linking and add &lt;font face=&quot;Courier New&quot;&gt;-bequiet&lt;/font&gt; to Options passed to the LD linker&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You should now be able to build your project successfully without this little hindrance.&lt;/p&gt;&lt;p&gt;Good luck!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/2643957501729836821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2019/01/solution-to-ios-delphi-build-failure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/2643957501729836821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/2643957501729836821'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2019/01/solution-to-ios-delphi-build-failure.html' title='Solution to iOS Delphi build failure'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-1124600979167474465</id><published>2018-12-08T14:16:00.001-08:00</published><updated>2018-12-08T14:21:42.443-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>CodeRage 2018 (redux)</title><content type='html'>&lt;p&gt;This year at &lt;a href=&quot;https://www.embarcadero.com/coderage-2018&quot; target=&quot;_blank&quot;&gt;CodeRage 2018&lt;/a&gt; I presented a session on &lt;a href=&quot;http://blong.com/Conferences.htm#CodeRage2018&quot; target=&quot;_blank&quot;&gt;Creative Delphi Debugging Techniques&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Other than my speaking volume being a bit quiet, it generated a number of very nice comments about the subjects covered so I thought it might be useful to mention that it is available for on-demand viewing as part of the &lt;a href=&quot;https://www.embarcaderoacademy.com/courses/coderage-2018&quot; target=&quot;_blank&quot;&gt;CodeRage 2018 Replay&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;There is free enrolment in the conference replay and my session, along with the session slides and sample files, can be &lt;a href=&quot;https://www.embarcaderoacademy.com/courses/coderage-2018/lectures/8461434&quot; target=&quot;_blank&quot;&gt;found here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;If you watch it I hope you turn up your PC volume and get a lot out of it to hopefully help with your debugging exercises!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/1124600979167474465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2018/12/coderage-2018-redux.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/1124600979167474465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/1124600979167474465'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2018/12/coderage-2018-redux.html' title='CodeRage 2018 (redux)'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-6405918326845795707</id><published>2018-12-08T12:32:00.001-08:00</published><updated>2018-12-30T09:38:41.056-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>RAD Studio 10.3 Rio’s Android Intent support (or current lack thereof)</title><content type='html'>&lt;p&gt;Sometimes when a new product is released there are a few ‘teething issues’. That certainly seems to be the case with RAD Studio 10.3 Rio. Both Delphi and C++Builder are hitting a few problems on various fronts. Now, it is true that internally in the product there has been a lot of change in the IDE, the VCL and FireMonkey, and perhaps it is therefore unsurprising a few slip-ups will have occurred.&lt;/p&gt;
&lt;p&gt;It is, however, quite annoying when you fall foul of these slip-ups and have to wait for a fix….&lt;/p&gt;
&lt;p&gt;The issue I want to address in this post is the breakage in the Android support for registering an interest in knowing about certain &lt;code&gt;&lt;a href=&quot;https://d.android.com/reference/android/content/Intent&quot; target=&quot;_blank&quot;&gt;Intent&lt;/a&gt;&lt;/code&gt; objects received by the app. This is normally achieved by a call to &lt;code&gt;MainActivity.registerIntentAction&lt;/code&gt;, as pseudo-documented &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/Seattle/en/What%27s_New#Registering_Your_Application_to_Handle_Android_Intents&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; (when it was introduced in RAD Studio 10 Seattle) and &lt;a href=&quot;http://docwiki.embarcadero.com/CodeExamples/Rio/en/FMX.Android_Intents_Sample&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; (in reference to a sample app) on Embarcadero&#39;s docwiki and illustrated &lt;a href=&quot;http://blong.com/Articles/Delphi10NFC/NFC.htm#ReceivingIntents&quot; target=&quot;_blank&quot;&gt;here in my article on NFC usage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This new &lt;code&gt;Intent&lt;/code&gt; support worked nicely in RAD Studio 10 Seattle, 10.1 Berlin and 10.2 Tokyo. Not so in RAD Studio 10.3 Rio. You get a crash when trying to register a new &lt;code&gt;Intent&lt;/code&gt; that you want to act upon.&lt;/p&gt;

&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;

&lt;p&gt;This issue has already been reported twice, once &lt;a href=&quot;https://quality.embarcadero.com/browse/RSP-21841&quot; target=&quot;_blank&quot;&gt;here as RSP-21841&lt;/a&gt; and again &lt;a href=&quot;https://quality.embarcadero.com/browse/RSP-22877&quot; target=&quot;_blank&quot;&gt;here as RSP-22877&lt;/a&gt;. I’ve had direct contact from someone using my NFC ode who has hit this problem. The cause of the problem was an oversight in a change made to the Java code underlying the FMX Android integration during a refactoring exercise. This is highlighted in the RSP-21841 report by Dave Nottage.&lt;/p&gt;
&lt;p&gt;In short an array used to hold the list of registered &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;Intent&lt;/span&gt;s is now set up as an immutable array instead of a mutable array and this leads to the following unsavoury response to any call to &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;MainActivity.registerIntentAction&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;613&quot; height=&quot;159&quot; src=&quot;data:image/png;base64,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&quot;&gt;&lt;/p&gt;
&lt;p&gt;So, while we await an official fix for this can we generate an unofficial fix? Yes! And what’s more it doesn’t take much effort.&lt;/p&gt;
&lt;p&gt;The steps below assume a default installation with default folders and so on. You’ll need to change any folders that you customised.&lt;/p&gt;
&lt;p&gt;1) First things first, download and install &lt;a href=&quot;https://cc.embarcadero.com/item/30869&quot; target=&quot;_blank&quot;&gt;Code Central download 30869&lt;/a&gt;: December 2018 Missing Files Patch for 10.3. That then gives is the full set of Android Java files within RAD Studio.&lt;/p&gt;
&lt;p&gt;Now we are going to correct the error and rebuild fmx.jar and fmx.dex.jar, which contain the errant code.&lt;/p&gt;
&lt;p&gt;2) Make a backup of fmx.jar and fmx.dex.jar from these two folders (so 4 files in total being backed up):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\debug&lt;/li&gt;
&lt;li&gt;C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\release&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next step is to fix the broken Java source code. The source file in question is in the Program Files (x86) folder tree and so can’t be edited normally. You need to run a text editor (for example RAD Studio or Notepad++) as administrator in order to be allowed to do that.&lt;/p&gt;
&lt;p&gt;3) Anyway, open up C:\Program Files (x86)\Embarcadero\Studio\20.0\source\rtl\androiddex\java\fmx\src\com\embarcadero\firemonkey\FMXNativeActivity.java.&lt;/p&gt;
&lt;p&gt;3a) Now locate the declaration of the field &lt;code&gt;mRegisteredIntentActions&lt;/code&gt;, which is currently declared and (wrongly) initialised like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;private List&amp;lt;String&amp;gt; mRegisteredIntentActions = Arrays.asList(&lt;br&gt;&amp;nbsp; NotificationInfo.ACTION_NOTIFICATION,&lt;br&gt;&amp;nbsp; NotificationPublisher.ACTION_GCM_NOTIFICATION);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Change this to:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;private List&amp;lt;String&amp;gt; mRegisteredIntentActions;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;3b) Next find where the &lt;code&gt;onCreate&lt;/code&gt; method calls it inherited version with this statement:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;super.onCreate(savedInstanceState);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Precede that with these three statements:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mRegisteredIntentActions = new java.util.ArrayList&amp;lt;String&amp;gt;();&lt;br&gt;mRegisteredIntentActions.add(NotificationInfo.ACTION_NOTIFICATION);&lt;br&gt;mRegisteredIntentActions.add(NotificationPublisher.ACTION_GCM_NOTIFICATION);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That’s the code sorted out.&lt;/p&gt;
&lt;p&gt;4) Now that’s done you should save the batch script shown at the end of this post in a text file somewhere (it doesn’t matter where) called BuildFMX.bat. Note that it’s important to ensure the file is stored as either a .bat file or a .cmd file if you prefer – if your Windows File Explorer is still left with its default options you won’t see file extensions and it’s easy to go wrong… I’ll work on the assumption you have saved it into a folder called C:\Scripts as C:\Scripts\BuildFMX.bat&lt;br&gt;
Please ensure that all the paths used to set up variables at the start of the script are valid for your system. They certainly work on mine, and mine was a fresh default Delphi installation on a clean VM. In particular, check these are correct:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BDS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JAVA_PATH&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SDK_PATH&lt;/code&gt; - for me with my ISO install this path needs to be:&lt;br&gt; C:\Users\Public\Documents\Embarcadero\Studio\20.0\PlatformSDKs\android-sdk-windows&lt;br&gt;but I gather you may perhaps find your SDK is installed to:&lt;br&gt;C:\Users\Public\Documents\Embarcadero\Studio\20.0\CatalogRepository\AndroidSDK-2525_20.0.32429.4364&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ANDROID_JAR&lt;/code&gt; - it may be that you have a different platform folder containing your android.jar file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[ Apologies for the lack of eye-pleasing syntax highlighting in the rendering of the script – I don’t really have time to sort out the blog gadgets to make it display nicer, so it’ll just have to do! ]&lt;/p&gt;
&lt;p&gt;5) The final job is to run the batch file BuildFMX.bat. Since it needs to generate and update files in the protected Program Files (x86) folder&lt;em&gt; you will need to run up an administrative command prompt&lt;/em&gt;. The easiest way to do this is to press the Windows key (&lt;span style=&quot;font-family: &amp;quot;wingdings&amp;quot;; font-size: small;&quot;&gt;ÿ&lt;/span&gt;), type cmd and press &lt;code&gt;Ctrl+Shift+Enter&lt;/code&gt;. This will run cmd.exe as Administrator.&lt;/p&gt;
&lt;p&gt;Change to the folder where you stored the batch file, e.g.:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cd C:\Scripts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now run the script:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;BuildFMX&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You should see this:&lt;/p&gt;
&lt;p&gt;&lt;img width=&quot;622&quot; height=&quot;590&quot; src=&quot;data:image/png;base64,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&quot;&gt;&lt;/p&gt;
&lt;p&gt;Just clean your project (right click the output file in the Project Manager and choose Clean) and things will be back as they should be – you can register to respond to &lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot;;&quot;&gt;Intent&lt;/span&gt;s as you might’ve expected to be able to all along.&lt;/p&gt;
&lt;p&gt;Here’s the batch script to be saved into a batch file [ BTW, hat tip to my friend coma_g for employing his Ninja batch script skills to fix my for loop ]:&lt;/p&gt;&lt;p&gt;[ Updated 10/12/2018: added error checking (and reporting) on the environment variables, as this has tripped up one or two people ]&lt;/p&gt;&lt;p&gt;[ Updated 11/12/2018: changed the script to check both likely install paths for the Android SDK before bailing out ]&lt;/p&gt;
&lt;p&gt;
&lt;pre&gt;@echo off
cls

setlocal enabledelayedexpansion

rem Set environment variables
rem *NOTE*: check these folders match your setup

set BDS=%ProgramFiles(x86)%\Embarcadero\Studio\20.0
set JAVA_PATH=%ProgramFiles%\Java\jdk1.8.0_60\bin&lt;br&gt;rem This is the default path for the Android SDK when installed from the .iso installer
set SDK_PATH=%PUBLIC%\Documents\Embarcadero\Studio\20.0\PlatformSDKs\android-sdk-windows&lt;br&gt;if not exist &quot;%SDK_PATH%\&quot; (&lt;br&gt;  rem This is the default path for the Android SDK when installed from the web install (aka ESD install)&lt;br&gt;  set SDK_PATH=%PUBLIC%\Documents\Embarcadero\Studio\20.0\CatalogRepository\AndroidSDK-2525_20.0.32429.4364&lt;br&gt;)

rem Set more environment variables based on those above

set DX_PATH=%SDK_PATH%\build-tools\28.0.2
set ANDROID_JAR=%SDK_PATH%\platforms\android-26\android.jar
set BDS_LIB=%BDS%\lib
set BDS_DEBUG_LIB=%BDS%\lib\android\debug
set BDS_RELEASE_LIB=%BDS%\lib\android\release
set FMX_SRC_PATH=%BDS%\source\rtl\androiddex\java\fmx
set CLASS_PATH=%ANDROID_JAR%
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\android-support-v4.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\cloud-messaging.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\google-play-services-base-7.0.0.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\google-play-services-maps-7.0.0.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\google-play-services-ads-7.0.0.jar

echo.
echo Checking environment variables

if not exist &quot;%BDS%\&quot; (
  echo Path used to set BDS environment variable does not exist^^! Is RAD Studio installed elsewhere?
  goto :Error
)

if not exist &quot;%JAVA_PATH%\&quot; (
  echo Path used to set JAVA_PATH environment variable does not exist^^! Is the JDK installed elsewhere?
  goto :Error
)

if not exist &quot;%SDK_PATH%\&quot; (
  echo Path used to set SDK_PATH environment variable does not exist^^! Is the Android SDK installed elsewhere?
  goto :Error
)

if not exist &quot;%ANDROID_JAR%&quot; (
  echo Path used to set ANDROID_JAR environment variable does not exist^^! Is your android.jar in a different platform folder?
  goto :Error
)

echo.
echo Changing to the FMX source folder
echo.

pushd %FMX_SRC_PATH%

echo Getting fully qualified list of all Java source file we need to rebuild
echo.

if not exist bin\classes mkdir bin\classes
if not exist bin\debug mkdir bin\debug
if not exist bin\release mkdir bin\release
dir src\android\bluetooth\*.java /s /b &amp;gt; JavaSources.txt
dir src\android\telephony\*.java /s /b &amp;gt;&amp;gt; JavaSources.txt
dir src\com\*.java /s /b &amp;gt;&amp;gt; JavaSources.txt

echo Ensuring FMX source path ends in a &#39;\&#39;
echo.

set LAST_CHAR=%FMX_SRC_PATH:~-1%
if not &quot;%LAST_CHAR%&quot;==&quot;\&quot; set FMX_SRC_PATH=%FMX_SRC_PATH%\

echo Making Java source file paths relative to current directory
echo.

if exist JavaSources2.txt del JavaSources2.txt
for /F &quot;tokens=*&quot; %%A in (JavaSources.txt) do (
  set STR=%%A
  set &quot;STR=!STR:%FMX_SRC_PATH%=!&quot;
  echo !STR!&amp;gt;&amp;gt;JavaSources2.txt
)

echo Compiling all the FMX Java code into class files with debug info
echo.

&quot;%JAVA_PATH%&quot;\javac -d bin\classes -classpath &quot;%CLASS_PATH%&quot; -encoding UTF-8 -g @JavaSources2.txt
if errorlevel 1 (
  echo.
  echo Problem encountered during Java compilation
  goto :Error
)

echo.
echo Creating jar containing the new compiled FMX Java classes with debug info
echo.

&quot;%JAVA_PATH%&quot;\jar cf bin\debug\fmx.jar -C bin\classes .
if errorlevel 1 (
  echo.
  echo Problem encountered during Java archiving
  goto :Error
)

echo Creating DEX jar containing the new compiled FMX Java classes with debug info
echo.

call %DX_PATH%\dx --dex --output=bin\debug\fmx.dex.jar --positions=lines bin\debug\fmx.jar
if errorlevel 1 (
  echo.
  echo Problem encountered during DEXing
  goto :Error
)

echo Compiling all the FMX Java code into class files without debug info
echo.

&quot;%JAVA_PATH%&quot;\javac -d bin\classes -classpath &quot;%CLASS_PATH%&quot; -encoding UTF-8 @JavaSources2.txt
if errorlevel 1 (
  echo.
  echo Problem encountered during Java compilation
  goto :Error
)

echo.
echo Creating jar containing the new compiled FMX Java classes without debug info
echo.

&quot;%JAVA_PATH%&quot;\jar cf bin\release\fmx.jar -C bin\classes .
if errorlevel 1 (
  echo.
  echo Problem encountered during Java archiving
  goto :Error
)

echo Creating DEX jar containing the new compiled FMX Java classes without debug info
echo.

call %DX_PATH%\dx --dex --output=bin\release\fmx.dex.jar --positions=lines bin\release\fmx.jar
if errorlevel 1 (
  echo.
  echo Problem encountered during DEXing
  goto :Error
)

copy bin\debug\* &quot;%BDS_DEBUG_LIB%&quot;
copy bin\release\* &quot;%BDS_RELEASE_LIB%&quot;

echo Tidying up...
echo.
if exist JavaSources.txt del JavaSources.txt
if exist JavaSources2.txt del JavaSources2.txt
rd /s /q bin

goto :End

:Error
echo.
echo Sorry, we had a problem :(
echo.

:End

echo Changing back to the folder we started in

popd

endlocal
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/6405918326845795707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2018/12/rad-studio-103-rios-android-intent.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/6405918326845795707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/6405918326845795707'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2018/12/rad-studio-103-rios-android-intent.html' title='RAD Studio 10.3 Rio’s Android Intent support (or current lack thereof)'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-1644271782195020795</id><published>2018-12-02T07:59:00.001-08:00</published><updated>2018-12-02T07:59:36.954-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>CodeRage 2018</title><content type='html'>&lt;p align=&quot;left&quot;&gt;Just when I thought conference season was over, &lt;a href=&quot;https://www.embarcadero.com/coderage-2018&quot; target=&quot;_blank&quot;&gt;CodeRage 2018&lt;/a&gt; came rapidly into view!&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;I like CodeRage – there’s always a good range of session subjects to choose from, and alwyas a range of good speakers to listen to.&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;I’ve had sessions at a few CodeRage conferences over the years, &lt;a href=&quot;http://blong.com/Conferences.htm#CodeRage7&quot; target=&quot;_blank&quot;&gt;CodeRage 7&lt;/a&gt;, &lt;a href=&quot;http://blong.com/Conferences.htm#CodeRage8&quot; target=&quot;_blank&quot;&gt;CodeRage 8&lt;/a&gt;, &lt;a href=&quot;http://blong.com/Conferences.htm#CodeRageXI&quot; target=&quot;_blank&quot;&gt;CodeRage XI&lt;/a&gt; and &lt;a href=&quot;http://blong.com/Conferences.htm#CodeRageXII&quot; target=&quot;_blank&quot;&gt;CodeRage XII&lt;/a&gt;. I’m pleased to continue that trend with a session at &lt;a href=&quot;http://blong.com/Conferences.htm#CodeRage2018&quot; target=&quot;_blank&quot;&gt;CodeRage 2018&lt;/a&gt; – the official web page is at &lt;a href=&quot;https://www.embarcadero.com/coderage-2018&quot;&gt;https://www.embarcadero.com/coderage-2018&lt;/a&gt; and the registration page is at &lt;a title=&quot;http://forms.embarcadero.com/CodeRageRegistration18&quot; href=&quot;http://forms.embarcadero.com/CodeRageRegistration18&quot;&gt;http://forms.embarcadero.com/CodeRageRegistration18&lt;/a&gt;.&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;This year I’m presenting my session on &lt;em&gt;Creative Delphi Debugging Techniques&lt;/em&gt;. This session has been received positively when I’ve presented a trimmed down version of it to audiences at various conferences around Europe so I thought it would be an ideal session to present in full at CodeRage 2018 and have it available online ongoing.&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;I’ll be online on Wednesday 5th December at 5pm CST (UTC-6), which is 11pm GMT and the session will last 90 minutes (an hour and a half!). If you can stop by my session I’d really appreciate it, and hopefully you’ll pick up a few tips about some of the Delphi debugger features and possibly lose some of the fear of the CPU window… (yes, we’ll be spending some time in the CPU window!).&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;Have a fantastic CodeRage 2018!&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;&lt;br&gt;&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/1644271782195020795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2018/12/coderage-2018.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/1644271782195020795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/1644271782195020795'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2018/12/coderage-2018.html' title='CodeRage 2018'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-4711125786382935492</id><published>2018-11-22T03:55:00.001-08:00</published><updated>2018-11-22T04:50:52.071-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>RAD Studio 10.3 Rio supports Android runtime permissions</title><content type='html'>&lt;p align=&quot;left&quot;&gt;RAD Studio 10.3 Rio has just been &lt;a href=&quot;https://www.businesswire.com/news/home/20181121005044/en/Embarcadero-Releases-RAD-Studio-10.3-Enhance-Delphi&quot; target=&quot;_blank&quot;&gt;released for General Availability&lt;/a&gt;, as you’ll have doubtless learned from the spree of blog posts on the subject. This is a great new release with &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/Rio/en/New_features_and_customer_reported_issues_fixed_in_RAD_Studio_10.3#List_of_publicly_reported_bugs_fixed_in_10.3&quot; target=&quot;_blank&quot;&gt;a lot of bug fixes&lt;/a&gt; and some nice updates to &lt;a href=&quot;https://www.embarcadero.com/products/rad-studio/whats-new-in-10-3-rio&quot; target=&quot;_blank&quot;&gt;product behaviour and features&lt;/a&gt;.&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;One feature that seems to have not received its fair share of attention in the documentation is the support for the &lt;a href=&quot;https://developer.android.com/about/versions/marshmallow/android-6.0-changes&quot; target=&quot;_blank&quot;&gt;Android 6.0&lt;/a&gt; (and later) &lt;a href=&quot;https://developer.android.com/about/versions/marshmallow/android-6.0-changes#behavior-runtime-permissions&quot; target=&quot;_blank&quot;&gt;runtime permissions&lt;/a&gt; model. This caused a bit of frustration earlier in the year when &lt;a href=&quot;https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html&quot; target=&quot;_blank&quot;&gt;Google changed the Play Store submission rules&lt;/a&gt; so that from August 2018 new apps have to follow this new permissions model and from November 2018 app updates also new apps have to.&lt;/p&gt;&lt;p&gt;RAD Studio 10.3 enhances the basic Android support to ensure that Android apps built with Delphi or C++ now understand and can support this new model, which may require a bit of change to your application logic.&lt;/p&gt;&lt;p&gt;In essence, instead of all permissions being granted on application installation, so-called &lt;a href=&quot;https://developer.android.com/guide/topics/permissions/overview#permission-groups&quot; target=&quot;_blank&quot;&gt;dangerous permissions&lt;/a&gt; now need to be &lt;a href=&quot;https://developer.android.com/training/permissions/requesting#perm-request&quot; target=&quot;_blank&quot;&gt;requested at runtime&lt;/a&gt; where the user can grant or deny them as they see fit. Additionally the user can change their mind in the app settings and toggle the permissions at any time.&lt;/p&gt;&lt;p&gt;The Android RTL has been enhanced with a framework to support requesting permissions at runtime and being notified of the user’s decision, and potentially offering a little explanation for the need for the permission.&lt;/p&gt;&lt;p&gt;As mentioned &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Android_Permission_Model&quot; target=&quot;_blank&quot;&gt;the documentation for this framework&lt;/a&gt; falls a little short right now (at product launch), but hopefully will improve over time. To try and plug the gap I’ve written an article showing how the permission framework can be used, both in Delphi and in C++. If interested in learning more about the Android runtime permission framework introduced in RAD Studio 10.3 Rio, please follow one of these links:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://blong.com/Articles/AndroidPermissions/DelphiAppPermissions.htm&quot; target=&quot;_blank&quot;&gt;Runtime permissions in Android (new in Delphi 10.3)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://blong.com/Articles/AndroidPermissions/CPlusPlusAppPermissions.htm&quot; target=&quot;_blank&quot;&gt;Runtime permissions in Android (new in C++ 10.3)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Finally, while I have your attention on things Android, I would like to draw your attention to &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/Rio/en/Release_Notes#Android&quot; target=&quot;_blank&quot;&gt;the Android-specific release notes&lt;/a&gt; for RAD Studio 10.3. You should read these to be sure of getting on with your first Android project with the new product release. It needs and uses a later Android SDK and NDK and you mat encounter some teething niggles on installation. These notes should help you!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/4711125786382935492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2018/11/rad-studio-103-rio-supports-android.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4711125786382935492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4711125786382935492'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2018/11/rad-studio-103-rio-supports-android.html' title='RAD Studio 10.3 Rio supports Android runtime permissions'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-7092921638606038611</id><published>2018-09-06T12:05:00.001-07:00</published><updated>2018-09-06T12:05:22.244-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>Conferences in Europe</title><content type='html'>&lt;p&gt;Exciting times – conference season is upon us again and I’m excited to be heading off to a couple of them to talk to Delphi developers around Europe about subjects I’m passionate about.&lt;/p&gt;&lt;p&gt;First off, and it’s nearly here, is the &lt;a href=&quot;https://www.barnsten.com/default/events/details?events_id=327&quot; target=&quot;_blank&quot;&gt;Barnsten Delphi Conference 2018&lt;/a&gt; in Utrecht in the Netherlands on Tuesday, September 18th. This is a one day event with &lt;a href=&quot;https://www.barnsten.com/media/factsheet/Delphi_Conference_2018_Agenda.pdf&quot; target=&quot;_blank&quot;&gt;a busy agenda&lt;/a&gt;. After the opening keynote from Delphi Product Manager Marco Cantú, I’ll be doing a plenary session on creating debugging techniques before the sessions split into 2 parallel tracks. In among these parallel sessions I’ll talk about Android API access and you can also choose from sessions by (among others) Bruno Fierens, Bob Swart, Danny Wind and Marco Cantú (again). These sessions are mostly in English, though a couple are not. This looks to be a great value day of Delphi expertise.&lt;/p&gt;&lt;p&gt;Later in the Autumn (or maybe it’s Winter by then…?) &lt;a href=&quot;https://entwickler-konferenz.de/&quot; target=&quot;_blank&quot;&gt;EKON 22&lt;/a&gt; takes place from November 5th to 7th (Monday to Wednesday, with Wednesday being Workshop day). Again Marco Cantú will be doing the keynote and then we have lots of sessions in 3 parallel tracks, many in German, many in English. I’m presenting my Creative Debugging Techniques session first thing on the Tuesday. Other speakers include Stefan Glienke, Bruno Fierens, Marco Cantú (again), Andrea Magni, Ray Konopka and Cary Jensen (among others). You can peruse &lt;a href=&quot;https://entwickler-konferenz.de/program-en/&quot; target=&quot;_blank&quot;&gt;the full agenda here&lt;/a&gt;.&lt;br&gt;If you are thinking of going to EKON 22 you can get Early Bird discounted pricing until September 27th (see &lt;a href=&quot;https://entwickler-konferenz.de/tickets-en/?go=ok&quot; target=&quot;_blank&quot;&gt;the registration page&lt;/a&gt;). Unfortunately I didn’t get to post about this before the &lt;em&gt;Very&lt;/em&gt; Early Bird pricing ended, but Early Bird discount pricing is a good deal!&lt;/p&gt;&lt;p&gt;I hope to see some of you in Utrecht or Dusseldorf!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/7092921638606038611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2018/09/conferences-in-europe_32.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/7092921638606038611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/7092921638606038611'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2018/09/conferences-in-europe_32.html' title='Conferences in Europe'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-400401723308076126</id><published>2017-11-07T15:27:00.001-08:00</published><updated>2017-11-27T12:21:01.679-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>CodeRage XII session files – Directly Using The Android API</title><content type='html'>&lt;p&gt;My &lt;a href=&quot;http://thecoderage.com/&quot; target=&quot;_blank&quot;&gt;CodeRage XII&lt;/a&gt; session on &lt;a href=&quot;https://www.embarcaderoacademy.com/courses/236275/lectures/3690364&quot; target=&quot;_blank&quot;&gt;Directly Using the Android API&lt;/a&gt; has been aired on the Internet. If you saw it I hope it came across reasonably well (interruptions notwithstanding) and might prove useful to you in your endeavours with Android.&lt;/p&gt;&lt;p&gt;As promised, the slides and samples are now available &lt;a href=&quot;http://blong.com/Downloads/CodeRageXII-DirectlyUsingTheAndroidAPI.7z&quot; target=&quot;_blank&quot;&gt;at this link&lt;/a&gt;. Do enjoy, now ˚◡˚&amp;nbsp;&amp;nbsp; [ Update: the broken link has been fixed ]&lt;/p&gt;&lt;p&gt;Apologies for the interrupted video transmission during the conference. &lt;strike&gt;Rest assured that as soon as Jim can manage it, pretty much all the CodeRage videos will be made available for replay. As soon as mine is available I shall be updating this post with the link and also linking to it on &lt;/strike&gt;&lt;a href=&quot;http://blong.com/Conferences.htm&quot; target=&quot;_blank&quot;&gt;&lt;strike&gt;my Conference Talks web page&lt;/strike&gt;&lt;/a&gt;&lt;strike&gt;.&lt;/strike&gt; You can see it at your leisure now &lt;a href=&quot;https://www.embarcaderoacademy.com/courses/236275/lectures/3690364&quot; target=&quot;_blank&quot;&gt;here at Embarcadero Academy&lt;/a&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/400401723308076126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2017/11/coderage-xii-session-files-directly.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/400401723308076126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/400401723308076126'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2017/11/coderage-xii-session-files-directly.html' title='CodeRage XII session files – Directly Using The Android API'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-5714891882868730166</id><published>2017-11-07T01:05:00.001-08:00</published><updated>2017-11-07T03:05:36.862-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>CodeRage XII session</title><content type='html'>&lt;p&gt;A whole 5 years ago (!) I did &lt;a href=&quot;http://blong.com/Conferences.htm#CodeRage7&quot; target=&quot;_blank&quot;&gt;a session for CodeRage 7 on accessing the Android API&lt;/a&gt;. This was not long after RAD Studio XE5 introduced support for developing Android applications, and Delphi’s Android support was in its first stage.&lt;/p&gt;&lt;p&gt;5 years on and &lt;a href=&quot;http://thecoderage.com/&quot; target=&quot;_blank&quot;&gt;CodeRage XII&lt;/a&gt; is starting today. I’ll be doing an updated talk on the same subject covering all that’s new in RAD Studio 10.2 at &lt;a href=&quot;https://www.embarcaderoacademy.com/courses/coderage-xii/lectures/3690364&quot; target=&quot;_blank&quot;&gt;3pm CST today, Tuesday 7th November 2017&lt;/a&gt;. I hope you can join me!&lt;/p&gt;&lt;p&gt;A full timetable of sessions is available &lt;a href=&quot;https://community.embarcadero.com/uploads/12169/coderage_2017/CodeRageXII_Schedule_by_Day_and_TimeSlot.pdf&quot; target=&quot;_blank&quot;&gt;in this PDF download&lt;/a&gt; in case you’re having trouble working out which sessions to attend.&lt;/p&gt;&lt;p&gt;Sad for me (due to working on-site meaning I won’t be able to catch them – alas they won’t be made available as replays!) but hopefully fabulous for many of you (if you can attend the sessions) is the inclusion in the list of speakers of a couple of legends in their areas:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://community.embarcadero.com/blogs/entry/robert-uncle-bob-martin-is-speaking-at-coderage-xii&quot; target=&quot;_blank&quot;&gt;Robert Martin&lt;/a&gt; (aka Uncle Bob Martin), author of &lt;a href=&quot;http://www.amazon.com/dp/0132350882/&quot; target=&quot;_blank&quot;&gt;Clean Code&lt;/a&gt;, 7am-9am 7th November 2017.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://community.embarcadero.com/blogs/entry/steve-mcconnell-to-speak-on-managing-technical-debt-at-coderage-xii&quot; target=&quot;_blank&quot;&gt;Steve McConnell&lt;/a&gt;, author of the classic &lt;a href=&quot;http://www.amazon.com/dp/0735619670/&quot; target=&quot;_blank&quot;&gt;Code Complete&lt;/a&gt; (among others), 12pm-1pm 8th November 2017.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These are well respected industry luminaries and Malcolm Groves, among others, has &lt;a href=&quot;https://www.code-partners.com/two-of-my-favourite-authors-uncle-bob-martin-and-steve-mcconnell-at-coderage/&quot; target=&quot;_blank&quot;&gt;a lot to say about them&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Enjoy &lt;a href=&quot;http://thecoderage.com/&quot; target=&quot;_blank&quot;&gt;CodeRage XII&lt;/a&gt;!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/5714891882868730166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2017/11/coderage-xii-session.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/5714891882868730166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/5714891882868730166'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2017/11/coderage-xii-session.html' title='CodeRage XII session'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-3142256098968075263</id><published>2017-10-29T15:42:00.001-07:00</published><updated>2017-10-30T12:35:36.259-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>‘What if?’ scenario analysis in the CPU window</title><content type='html'>&lt;p&gt;Last Tuesday, 24th October I did some sessions at &lt;a href=&quot;http://blog.blong.com/2017/10/ekon-21.html&quot; target=&quot;_blank&quot;&gt;EKON 21&lt;/a&gt;, one of which was on Creative Debugging Techniques. During the session there was a section where I was trying to demonstrate an idea or technique that happened to fully involve the CPU window. Unfortunately a series of finger fumbles on my part meant I couldn’t show what I wanted to show, albeit I &lt;em&gt;think &lt;/em&gt;the point was made.&lt;/p&gt;&lt;p&gt;Anyway, I mentioned that maybe I’d write up that little snippet into a blog post, just to prove that it really does work as I suggested it does, and so here it is.&lt;/p&gt;
















&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;














&lt;p&gt;Oh, apologies up front for all the animated GIFs below-&amp;nbsp; it seemed the most expeditious way to make sure I could really convey some of the points.&lt;/p&gt;&lt;p&gt;So the context was ‘What if?’ situations and testing out such scenarios during a debug session.&lt;/p&gt;&lt;p&gt;Clearly the primary tool for testing out ‘What if?’ scenarios is the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Evaluate/Modify&quot; target=&quot;_blank&quot;&gt;Run, Evaluate/Modify…&lt;/a&gt; (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+F7&lt;/font&gt;) dialog. This dialog’s Modify button allows you to alter the value of the expression you have evaluated to find out how code behaves when the expression has a value other than what it actually had.&lt;/p&gt;&lt;p&gt;That’s a good and very valuable tool. But the case in point in the EKON 21 session was a bit different.&lt;/p&gt;&lt;p&gt;Consider a scenario where you are in the midst of a lengthy debug session, one that you’d really rather not reset and start again. Also consider that from some observations made in the debug session you have realised that a certain function &lt;font face=&quot;Courier New&quot;&gt;B&lt;/font&gt; that is called from function &lt;font face=&quot;Courier New&quot;&gt;A&lt;/font&gt; ought in fact not to be called. You want to test how well things pan out with &lt;font face=&quot;Courier New&quot;&gt;B&lt;/font&gt; not being called.&lt;/p&gt;&lt;p&gt;In an entirely fabricated ultra-academic example, let’s use this code here, where &lt;font face=&quot;Courier New&quot;&gt;A&lt;/font&gt; is &lt;font face=&quot;Courier New&quot;&gt;TMainForm.WhatIfButtonClick&lt;/font&gt; and &lt;font face=&quot;Courier New&quot;&gt;B&lt;/font&gt; is &lt;font face=&quot;Courier New&quot;&gt;CommonRoutine&lt;/font&gt;.&lt;/p&gt;&lt;code&gt;procedure TMainForm.WhatIfButtonClick(Sender: TObject);&lt;br&gt;
{$REGION &#39;&quot;What if?&quot; scenarios&#39;}&lt;br&gt;
var&lt;br&gt;&amp;nbsp;&amp;nbsp; S: string;&lt;br&gt;
begin&lt;br&gt;&amp;nbsp;&amp;nbsp; S := &#39;Hello world&#39;;&lt;br&gt;&amp;nbsp;&amp;nbsp; Caption := S;&lt;br&gt;&amp;nbsp;&amp;nbsp; CommonRoutine;&lt;br&gt;&amp;nbsp;&amp;nbsp; Color := Random($1000000);&lt;br&gt;{$ENDREGION}&lt;br&gt;
end;&lt;br&gt;&lt;/code&gt;
&lt;p&gt;One solution to this is to move the instruction pointer to skip the call to &lt;font face=&quot;Courier New&quot;&gt;B&lt;/font&gt; just as &lt;font face=&quot;Courier New&quot;&gt;B&lt;/font&gt; is about to be called. This can be done in a number of ways in Delphi. Set a breakpoint on the call to &lt;font face=&quot;Courier New&quot;&gt;B&lt;/font&gt; and when it hits do one of the following four options to achieve this:&lt;/p&gt;&lt;p&gt;&lt;u&gt;1) Set next statement menu item&lt;/u&gt;&lt;/p&gt;&lt;p&gt;Right-click on the statement that follows the call to &lt;font face=&quot;Courier New&quot;&gt;B&lt;/font&gt; and select &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Code_Editor_Context_Menu&quot; target=&quot;_blank&quot;&gt;Debug, Set Next Statement&lt;/a&gt;, a menu item added in Delphi 2006 and described by Chris Hesik in &lt;a href=&quot;https://web.archive.org/web/20080612014210/http://blogs.codegear.com:80/chrishesik/2007/04/30/34241&quot; target=&quot;_blank&quot;&gt;this old 2007 blog post (from the Internet Archive WayBack Machine)&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrnD6gd3-cZ2fQ_FtEPa0Ts2s-AfX4Skkxgef3WGG2GQD3luobSREayBmga1UCfj7wB4OKEGx1WlnCc0IkVzong-KcvAJbZzPqL4LV3Y__2GTJZTRk-igMS8J5U5sbGACuDAceB9LYOLM/s1600-h/SetNextStatement%255B2%255D&quot;&gt;&lt;img width=&quot;584&quot; height=&quot;590&quot; title=&quot;SetNextStatement&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;SetNextStatement&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjln2mFXyTwzBw_DCcUS-COATKe-Z2r8QQWZ2cvQIex-OGMpllgkDKSGTE3w5XF3qFTUKVC6XyetaVJIHmwNiJpAyBY0wNLaOFdHJMpBJjp8BgkzUcun3OPHeAavaoI7WNRt3rSz_NUPMg/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;u&gt;2) Drag the instruction pointer editor gutter icon&lt;/u&gt;&lt;/p&gt;&lt;p&gt;Drag the instruction pointer icon in the editor gutter to point at the following statement. This drag and drop support for the instruction pointer symbol was &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/2010/en/What%27s_New_in_Delphi_and_C%2B%2BBuilder_2010#Code_Editor_Changes&quot; target=&quot;_blank&quot;&gt;added in Delphi 2010&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiTcjFu29-ZE3DrKNVvYZxPPCHo5H-RZBHBK3ivQfCMYebsEziPZtoxY67RB-syRbQNb9OLsYN_HxbpCSTEW4FNg5Lp9WXMtzXzZmpSXLdmxzqaGAzYu-cw4msVOa_U4BkTAtN1ESDt_U/s1600-h/DragInstructionPointer%255B1%255D&quot;&gt;&lt;img width=&quot;524&quot; height=&quot;249&quot; title=&quot;DragInstructionPointer&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block;&quot; alt=&quot;DragInstructionPointer&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs7dDqlnJehumn3XT8OT8MYzL-qvh25ep1XKtccMX25YPXUkftDFgclvM_kmPYwwFlh6-RAOwfqlbHO_gMCBRYMXA1m7_L0AKQjjkpRWDqrJ1GqpWmdbZR_uPyDu6VV5Bvjsj8XgCUiJI/?imgmax=800&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;u&gt;3) Change the instruction pointer in the CPU window&lt;/u&gt;&lt;/p&gt;&lt;p&gt;Invoke the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/CPU_Windows_Index#Opening_the_Entire_CPU_View&quot; target=&quot;_blank&quot;&gt;CPU window&lt;/a&gt; (View, Debug Windows, CPU Windows, Entire CPU or &lt;font face=&quot;Courier New&quot;&gt;Ctrl+Alt+C&lt;/font&gt;), or at the very least the Disassembly pane (View, Debug Windows, CPU Windows, Disassembly or &lt;font face=&quot;Courier New&quot;&gt;Ctrl+Alt+D&lt;/font&gt;). Right click on the next statement and choose New EIP (or &lt;font face=&quot;Courier New&quot;&gt;Ctrl+N&lt;/font&gt;).&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjssZGGEZuTnweCQaroRJNji1v6j-HnsZ1YwKswNAWYc0FSCX5VRYA5uRfH4rlrA8sbWpqRVz1_qN0wN0LI4GftGdtWhSG55xJMQTlufPJVBBB-digo79zcinkBnM3ojWgX-uGV5PCwQoM/s1600-h/NewEIP%255B4%255D&quot;&gt;&lt;img width=&quot;580&quot; height=&quot;406&quot; title=&quot;NewEIP&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block;&quot; alt=&quot;NewEIP&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEharVXWBA176DdxQQMtHOI-wZ8f3DAiMWXQO5pUv_NE0XQJIrdY1JmH5w38Y1HL8uc0MNvo7bwo71stoA8xzx599lbDcR3U75q3MQEgr-mPlOQrcjUQ6WrQoIDLJbo7lGmdo2b0ithzrxs/?imgmax=800&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;u&gt;4) Update the EIP register in the CPU window&lt;/u&gt;&lt;/p&gt;&lt;p&gt;Invoke the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/CPU_Windows_Index#Opening_the_Entire_CPU_View&quot; target=&quot;_blank&quot;&gt;CPU window&lt;/a&gt; (View, Debug Windows, CPU Windows, Entire CPU or &lt;font face=&quot;Courier New&quot;&gt;Ctrl+Alt+C&lt;/font&gt;). Note the address of the instruction you want to execute next. Right-click the &lt;a href=&quot;http://www.c-jump.com/CIS77/ASM/Instructions/I77_0040_instruction_pointer.htm&quot; target=&quot;_blank&quot;&gt;EIP&lt;/a&gt; register in the Registers pane and choose Change Register… (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+H&lt;/font&gt;) and enter the new value as a hexadecimal number, i.e. with a $ prefix. An alternative to Change Register… is to choose Increment Register (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+I&lt;/font&gt;) a sufficient number of times to get the value to match the target address.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUZTZztjcMmylm5wT-Odso5xMFnWOyX6BhR_2sZSYYuMhFOvNOmhfEmg7bdDSuTq10SehUR1R2FZaoH-R7GHwgLHA5s7cASai2R74kxbqhN5LYXed7x67rQXOPcTzS_fBZ8sj5UQDWm0E/s1600-h/ChangeEIP%255B2%255D&quot;&gt;&lt;img width=&quot;583&quot; height=&quot;411&quot; title=&quot;ChangeEIP&quot; style=&quot;display: inline;&quot; alt=&quot;ChangeEIP&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSupFsCPjNY2RFbumAbUEZZmVOjnA0kmkl_J7dQbptfeMatMSadeqeS8LHqMOAeYb72wuS1yQjDyjHCGIAYvcwLc4G0LvkVXfjde13wMoGeXSTBgsCInldSxjBgEu5UZZU5hB8QdVSwNo/?imgmax=800&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;OK, so all of those achieve the goal on that single invocation of routine &lt;font face=&quot;Courier New&quot;&gt;A&lt;/font&gt;, but what about the case where &lt;font face=&quot;Courier New&quot;&gt;A&lt;/font&gt; is called lots of times – lots and lots of times? This idea falls down in that situation and so we might seek out an alternative option.&lt;/p&gt;&lt;p&gt;Maybe we can get rid of the call to &lt;font face=&quot;Courier New&quot;&gt;B&lt;/font&gt; entirely for this run of the executable. Yes, maybe we &lt;em&gt;can&lt;/em&gt; and indeed that was just the very technique I tried to show, but made a couple of silly mistakes by not paying attention to what exactly was on the screen. Mea culpa.&lt;/p&gt;&lt;p&gt;There are a couple of approaches to getting rid of the call to &lt;font face=&quot;Courier New&quot;&gt;B&lt;/font&gt; from the code present in &lt;font face=&quot;Courier New&quot;&gt;A&lt;/font&gt;. One is to replace the first few bytes of that statement with an instruction that jumps to the next statement. The other is to replace the entire statement with opcodes corresponding to ‘no operation’, i.e. the no-op opcode &lt;font face=&quot;Courier New&quot;&gt;NOP&lt;/font&gt;. Let’s look at both approaches.&lt;/p&gt;&lt;p&gt;Both these approaches involve changing existing machine instructions in memory. With that end goal comes a rule, and the rule is that you can’t successfully change a machine instruction that your program is currently stopped at in the debugger or that the debugger has a breakpoint on. In other words, if you want to change the call to &lt;font face=&quot;Courier New&quot;&gt;CommonRoutine&lt;/font&gt; to be something else this &lt;em&gt;must&lt;/em&gt; be done when the program is stopped at a different instruction in the debugger and there must be no breakpoint on that instruction.&lt;/p&gt;&lt;p&gt;This is simply a side effect of the way debuggers implement breakpoints and statement stepping - they replace the first byte of the instruction to break at with $CC, the byte value, or opcode, for the assembly instruction &lt;a href=&quot;https://en.wikipedia.org/wiki/INT_(x86_instruction)#INT_3&quot; target=&quot;_blank&quot;&gt;INT 3&lt;/a&gt;. When execution continues the $CC is swapped back for the original value.&lt;/p&gt;&lt;p&gt;So if you change the instruction at the current EIP when the execution has stopped in the debugger, when you ask it to move on your first byte will get replaced, just by the mechanics of your debugger doing its day job. This will most likely cause a very much unwanted opcode combination leading quickly to an application crash. [ One of my EKON fumbles was to instantly forget this previously well known (by me) fact and promptly get a crashed &lt;a href=&quot;https://en.wiktionary.org/wiki/debuggee&quot; target=&quot;_blank&quot;&gt;debuggee&lt;/a&gt;. ]&lt;/p&gt;&lt;p&gt;Your best bet is to put a breakpoint on the &lt;em&gt;preceding&lt;/em&gt; instruction, and then modify/replace your target instruction. Make sure there is no breakpoint on the target instruction.&lt;/p&gt;&lt;p&gt;When you look in the CPU window you can see the assembly instructions that correspond to the Pascal statement above it.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5rQFb9qsCTpCCVjtNjtxHaG43MM2KMhr1dZ4n0-P3fn_NpJgTZB8rQugOZE3Hb_v2rey-z6XzGxAd3kObzmrrtR7HbK_lqRDHV7i4blF39OsR6xd68WwgMxwIGmS2hU3hLeA-gO1pFbM/s1600-h/Disassembly15&quot;&gt;&lt;img width=&quot;532&quot; height=&quot;244&quot; title=&quot;Disassembly&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;Disassembly&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXfRPSmxWlyXuEhJUwqzZbuF3qiNrSoOHeT1k9TfSETqWQxXgzip7-z6-AQwxOejLtKx4May6-qkwx8ajszUqAq_M5l6wkc8kXOQ5IpvvW941PTjL3yalo1_EDk7UGMjuRWLj8jFzOUVw/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In the case of the call to &lt;font face=&quot;Courier New&quot;&gt;CommonRoutine&lt;/font&gt; the assembly code is:&lt;/p&gt;&lt;code&gt;mov eax,[ebp-$04]&lt;br&gt;call TMainForm.CommonRoutine&lt;/code&gt;&lt;p&gt;The machine code bytes (opcodes) that represent those 2 instructions are $8B, $45, $FC and $E8, $11, $F8, $FF, $FF respectively. The 3 bytes for the first instruction are stored at locations starting at $5D1287 and the 5 bytes for the second instruction start at $5D128A.&lt;/p&gt;&lt;p&gt;The statement following the call to &lt;font face=&quot;Courier New&quot;&gt;CommonRoutine&lt;/font&gt; starts at address $5D128F, 8 bytes on from $5D1287.&lt;/p&gt;&lt;p&gt;&lt;u&gt;1) Overwriting an instruction with a jump instruction&lt;/u&gt;&lt;/p&gt;&lt;p&gt;The goal is to write some opcodes into memory starting at address $5D1287 that represent an assembly instruction to jump 8 bytes forward. If we look at the &lt;a href=&quot;http://x86.renejeschke.de/html/file_module_x86_id_147.html&quot; target=&quot;_blank&quot;&gt;documentation for the x86 JMP instruction&lt;/a&gt;, a small jump is 2 bytes of instructions encoded as $EB coupled with the jump distance from the end of the jump instruction. So 8 bytes minus the 2 byte instruction is 6, so $EB $06. [ One of my fumbles in the EKON session was to misread the $EB as $E8, which is a &lt;font face=&quot;Courier New&quot;&gt;CALL&lt;/font&gt; opcode. ]&lt;/p&gt;&lt;p&gt;So, to change the current code for new instructions we have to move our attention away from the Disassembly pane to the Memory pane. You can either use the one embedded into the Entire CPU view or open up one of four standalone memory panes using an item from the submenu View, Debug Windows, CPU Windows:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Memory 1 (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+Alt+E&lt;/font&gt;)&lt;/li&gt;&lt;li&gt;Memory 2 (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+Alt+2&lt;/font&gt;)&lt;/li&gt;&lt;li&gt;Memory 3 (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+Alt+3&lt;/font&gt;)&lt;/li&gt;&lt;li&gt;Memory 4 (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+Alt+4&lt;/font&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;By default the memory pane will be settled on address $401000, the start of the application’s Code segment (according to first piece of information in &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Detailed-Segments_Map_File&quot; target=&quot;_blank&quot;&gt;a detailed .map file&lt;/a&gt;, as generated by the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Linking&quot; target=&quot;_blank&quot;&gt;linker&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbt1KMiuD4IoB8gcmSmCOhsJPOFgV0K0z8UnkzUW1zCv4oIQxVtRS9FYBsCOhyphenhyphen1MuNDn-xveMzWjQOI4i0A9SHTyeNjA5OOsVyHI2_F8pId5Wmo2uNZflpsp5Va880ToS-y3uHQ-_ES-M/s1600-h/Memory1%255B1%255D&quot;&gt;&lt;img width=&quot;463&quot; height=&quot;166&quot; title=&quot;Memory1&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;Memory1&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJdZZYB88F81FvRtpHWYu5D9BSnzn8_Pp2cpGLKGNMmkCgAYWEXiWWhnGlbpgjsWHHAGPxj5TdPrADQBiktjfzcFiKn0sxootqrf2XwbH8xF6X8lndKR03urkmdF9-OM_APzd7uV-RR9Y/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You should reposition to the target instruction by using Go to Address… (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+G&lt;/font&gt;) from the context menu and entering (in this examples case) $5D1287. You’ll see the ‘familiar’ 8 bytes we saw for the instructions right there on the first line: &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9bTOAZQgaC696_tHygHq3otIYJ0FiPTtrKJgVYu0fydFSfjz7ancujLguSX6hufY89H7IJKte7xYh_PcQ3QI98E6uVBOZ7cbXYe2eRSFH13PAU8TvNjzx_e6yMH-Y8Bj6BIKcMTos23w/s1600-h/Memory2%255B1%255D&quot;&gt;&lt;img width=&quot;466&quot; height=&quot;168&quot; title=&quot;Memory2&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;Memory2&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMX41SFc7jGEDyuw1qkWEEVoEd52rHBMcQTaiQBiDXRxK7gU3rXpmbP0hC8c19HaWYer9bRHLBXIkZA52gaXA7iA-zc6ySUH02r_wenK8u0ONpGMqRJnnFre8X7BRqxfSUVeHWMCuweSc/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;To change these 6 bytes to be bytes representing our jump instruction you can select Change (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+H&lt;/font&gt;) from the context menu and enter the values: $EB $06.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOoRdFWRVrq77iPhapHoj-hR8nZ0ZEcRxjyws4MexHWtYHq15YNKSVUgnIphwZ8h2X7vkSPeIwFd_A9fDRcnsuyRDwj7oS2a1BBqBXg50FHY71Xg4_tIDZHMwtqkueS9_nqkhbQV-1r_Q/s1600-h/NewValue1%255B9%255D&quot;&gt;&lt;img width=&quot;427&quot; height=&quot;173&quot; title=&quot;NewValue1&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;NewValue1&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7K-BHp06GwA74n4xsC9t-Da1owDIyS7Q5pRQeHWwwrJbASj1IGhxmQspl_VCTFD_5F8G-gJrpDzpUZQdtrjHMP3rKnsYC0KxOuKzG4DczwNsjowpGXNr7yQdlRvESCCKczkVL5e0ZV6A/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You can also simply start typing those values directly into the Memory pane and the Enter New Value dialog will pop up.&lt;/p&gt;&lt;p&gt;This changes the first 2 bytes of that instruction and the Disassembly pane echoes this by showing the JMP instruction.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4G8F1cdtOgfp5xq9wfs3p5-qlRXAGSrOXrESKqxsPDJ9UTWk8vJy9OGn4r3BBK77qtn9p8Dw54TdTRzQO3hRCBl4YEeq33NdKS0o0pXbCzRMPzEoXSfqW1c0V0nfWVrE-b4c8LQR6das/s1600-h/Disassembly2%255B6%255D&quot;&gt;&lt;img width=&quot;529&quot; height=&quot;258&quot; title=&quot;Disassembly2&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;Disassembly2&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL3XGDykxdsVqg0LRZtIta9pj2kw6Z900tbuRbxH2djvm9O0FHZPbjMDLMC7gfx0srFY6vyaiaxNtz9pVL4-MpQp6zm3SP68eJD0UUX94LGjFIw4UrgixklBJA1zl3NEf1wFb3UF0RqC4/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;As you’ll note, however, there is a bit of “noise” after this for the remaining 6 opcodes: some junk that is jumped over.&lt;/p&gt;&lt;p&gt;[ Update 30/10/2017 – thanks to The Arioch for welcome interjections. It should be noted that in this case after trampling over the first 2 opcodes the remainder of the previous set of opcodes still “make sense” to the disassembler. So much so that the very next Delphi statement is still shown and is still translated directly into its constituent opcodes.&lt;/p&gt;&lt;p&gt;It is, however, often the case that having bulldozed over a couple of essentially arbitrary opcodes, what’s left is a bit of a mess, and puts things “out of kilter”, leaving subsequent Delphi statements not showing in the disassembly pane thanks to what opcodes have come before.&lt;/p&gt;&lt;p&gt;As a simple example, not necessarily demonstrating the ultimate confusion that can be caused, here’s some code:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX7kBKvumEocdzTcE-u6nA3wmetyewxJB16a4orcj_8obZ0IzpAWd1gBdB_Td-377MF6UltQLZpY5RH_YFpPk3Irrzrzh96SgCA0BWW-Dwc466mW3FQGhIfyOa8iuMeIT7g8Gq-DQPjSY/s1600-h/Disassembly6%255B3%255D&quot;&gt;&lt;img width=&quot;501&quot; height=&quot;238&quot; title=&quot;Disassembly6&quot; style=&quot;display: inline; background-image: none;&quot; alt=&quot;Disassembly6&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9X9ijVP8W5HlI2dEX6XcBCnaTlGMlirCU-3kv8IjDF5ihMH0G6WYd88U8-FgcR1_OdZORIoMk7uiEugRzMo7vRy-UsQiMHa4qJtiIx6Y8gdxkmKgBWR294gfCtcVKJYWIvMpecJb25GA/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;If we wish to skip the &lt;font face=&quot;Courier New&quot;&gt;ShowMessage&lt;/font&gt; call we need to workout the &lt;font face=&quot;Courier New&quot;&gt;JMP&lt;/font&gt; opcodes.&lt;/p&gt;&lt;p&gt;Run a copy of Windows Calculator, go into programmer mode (&lt;font face=&quot;Courier New&quot;&gt;Alt+3&lt;/font&gt;), and calculate $5D1686 – $5D167C to get the gap from &lt;font face=&quot;Courier New&quot;&gt;ShowMessage&lt;/font&gt; to the following statement. Then subtract 2 to take off the size of the small &lt;font face=&quot;Courier New&quot;&gt;JMP&lt;/font&gt; instruction. This gives a final result of 8, so we enter new opcodes of $EB $08 and what’s then showing in the disassembly pane is this:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpINyGFGTHFVgZWz-ksFhsil40zxO4tT0E6rZOaDTVxpWr1K1tjZUxr7-NRG12tu2MbesCpKAi9KKJFhQRGTFJrX4-p34eKT-8ncEVnTkceiOv537FMMi9cxLTL-RazATOOyQoGKu3RM0/s1600-h/Disassembly7%255B4%255D&quot;&gt;&lt;img width=&quot;508&quot; height=&quot;363&quot; title=&quot;Disassembly7&quot; style=&quot;display: inline; background-image: none;&quot; alt=&quot;Disassembly7&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBIKTelH-V5FwNsC62LVeKJtSRE44qXZsy8q707IGhE8Dxt6YntCBkIX9rEFME39OWjva3XazhO0gy1__NOsFeLpg7RsK4ee0i2xJ5F60eojOr4eGBOT1Y6gxsclBqWGYWQ6RmqqesNG8/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The disassembly of the call to &lt;font face=&quot;Courier New&quot;&gt;CommonRoutine&lt;/font&gt; has gone rather up the spout, even though the opcodes for it are actually still quite intact.&lt;/p&gt;&lt;p&gt;End of update ]&lt;/p&gt;&lt;p&gt;To clean this up we could fill in the remaining 6 bytes with opcode $90, which corresponds to NOP, the assembly no-op instruction:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJn3F8dlw0BrnMwPRjb08KIHtjGNNPFTQjiGihCUSnkT5NjqSQ8k5C97guJFc0njntw2WlbUZ8GkRkQasdgQ-A_M5VWhlF8xHfriGINbRwl5r4zyV7FCXI4j0ypA6ikeUH1xjbl3whqeU/s1600-h/NewValue2%255B11%255D&quot;&gt;&lt;img width=&quot;429&quot; height=&quot;174&quot; title=&quot;NewValue2&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;NewValue2&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgg2mUwvokNrDtj8ae58hIfjZYzvBi_pmx-SetWojjG1hop2cHbtMIrsbb1YwNZiYmBNKRf8DGGLbjdAKYVqNoT3aGoNsmTY8aYNwom8W6h6DOQlga_PkzRp2mHlhsxf6rdMSvd80omEeU/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This shows as:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhThCiI5H0I81PvimRddiSAxOaekSn5uzNSGMLt1jVntKxzfRXAbdNaoxODQ78dAjaArUWRZtHfGOq1WzvcjQo0LlB0ajiShwRHmlEkjmrqA0fiPlP5r8Sg7pUbXod6PhpCtL4sFwI1h_w/s1600-h/Disassembly3%255B11%255D&quot;&gt;&lt;img width=&quot;528&quot; height=&quot;277&quot; title=&quot;Disassembly3&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;Disassembly3&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCH3zap3A3aQqJkPYsAp9dcB0cZh6eN3hZi2Fv9pRVenUNgAeaNslvESCzB49ErdYJjJCkRNpxajyVjzWimL5ce-wE1VHPCQeA9eiomeakmm1R0_0ccDDmAw3VblLt3WicFokvbNt9u-I/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;[ Another of my EKON fumbles was to enter too many $90 bytes having miscounted the required bytes, or perhaps forgetting that I need to subtracted the size of the jump instruction. This rather messed up the following instruction, which should have been left intact. This got another crash. ]&lt;/p&gt;&lt;p&gt;Or you could fill with data byte $FF – just data:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA2cf6lFkiQopEpshg_db-jQXwN2JeGAmjoMBYseXDB1XqBmVDIghPuEEijGhRGHfQuYBkxdSxI4E9cCE1rdEuioawEThEFsz6dYcxUh-ThZruo5OsHvNI3VnqnLXGqPOD3oBuc47kIFI/s1600-h/NewValue3%255B5%255D&quot;&gt;&lt;img width=&quot;413&quot; height=&quot;168&quot; title=&quot;NewValue3&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;NewValue3&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbIhqymSpuX7GHi11_iZ8yQi0_yHyn69_3c0lBPuQdx7IbEhYGkICxgJ0KOushfCLGj4JZSgyabITODsHPPJHsO0B7fGaEMKKqfbVhY2oPLGsAWBzxXLqvAK9H3joZA_Sr1UMh74kwDdQ/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ8VZ9gdyWq7TMexGMNYHI7yFlsu_m3bydBj-7Qw6k7K6aZvaafvzjVEYpazYj4cWlfST6n5Ha29Nm9arqZey8uKKuVbreceUKoIEPC6qzJi16H-cvBXh2b_RCN2WEsDdNxM49sNOIgew/s1600-h/Disassembly4%255B3%255D&quot;&gt;&lt;img width=&quot;527&quot; height=&quot;279&quot; title=&quot;Disassembly4&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;Disassembly4&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGVpXGUAQpki1kH8eHWL7hv5Qi-z4NFLy5AcjB4uKHq1bqr51XZ3n8tsSgzK0T2CDc38V_g8AXntzVpJPggmR3AlYBSo_2BKLpSz5ZB2ERlPyUIRNR5bm_uDaRUf9F1-PrahPzXkoSpGY/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;u&gt;2) Overwriting an instruction with &lt;font face=&quot;Courier New&quot;&gt;NOP&lt;/font&gt; opcodes&lt;/u&gt;&lt;/p&gt;&lt;p&gt;This is just an extension of the last points in the option above. In a memory pane that has been located on the start of the target instruction, just change all the bytes of the instruction to the &lt;font face=&quot;Courier New&quot;&gt;NOP&lt;/font&gt; opcode, $90. We have 8 bytes here, so use the Change submenu item (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+H&lt;/font&gt;):&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiEmPB0PKrIfnutZxa-wH3HOrMTPPZQOPCsIWSUZ-s-nV7VMhywfIqjwCX5yfynFiXvOnauUrQFI9RQoTsxsHczuR3ycZqo7RlZx8aDAlZp_nG8rohe0mu_JRBWltgHD45BMepFnB-7xU/s1600-h/NewValue4%255B6%255D&quot;&gt;&lt;img width=&quot;414&quot; height=&quot;168&quot; title=&quot;NewValue4&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;NewValue4&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhotPTxKycTwX8jwjz-pNFATYrCGn-bvLOL4HqjDg_ARjJrJAwLbfAQ36cirrGMIB3VCRUWbfzLQSByTGLf1xZ7d-xW1UQuf_pHxnoZtw7wWth95bf66VnIdxT8tg3kWhmH5l8PIRSqyio/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6yr_2q9rxAiq2ZSXqwGVDANXcAAkwcUBVtcr-qmKjBbIzUKg7VLCXyOZMoSPLGa3jTsNGQv0fOLP3L6h9SL_RETXkYDPL-PtD4ii85galN-ZvdEGwaxWjX6_XBGpHk3lounELJcGXFeo/s1600-h/Disassembly5%255B4%255D&quot;&gt;&lt;img width=&quot;524&quot; height=&quot;349&quot; title=&quot;Disassembly5&quot; style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; alt=&quot;Disassembly5&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicvNOTrFr3RnQZw0_hGF7W7PcyTaZkuGxMHyQu-tBg6LF2JtMmTIesa2QK4ULGURTLXOXMNvLdRHroE8mpTxFPPRcVy19dvMlwkjWdcxz2o0ro6wlckiTY4Ag7_zFV0ndNRQx7a5taemg/?imgmax=800&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;There we go, that’s what I meant to show in that 5 minute section of the session – apologies for the poor demonstration but hopefully this makes up for it ¯\_(ツ)_/¯ &lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/3142256098968075263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2017/10/what-if-scenario-analysis-in-cpu-window.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/3142256098968075263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/3142256098968075263'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2017/10/what-if-scenario-analysis-in-cpu-window.html' title='‘What if?’ scenario analysis in the CPU window'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjln2mFXyTwzBw_DCcUS-COATKe-Z2r8QQWZ2cvQIex-OGMpllgkDKSGTE3w5XF3qFTUKVC6XyetaVJIHmwNiJpAyBY0wNLaOFdHJMpBJjp8BgkzUcun3OPHeAavaoI7WNRt3rSz_NUPMg/s72-c?imgmax=800" height="72" width="72"/><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-931955932370626142</id><published>2017-10-17T12:07:00.001-07:00</published><updated>2017-10-19T03:35:14.995-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>Remote debugger recalcitrance</title><content type='html'>&lt;p&gt;My development machine in my main week day job does not have some custom hardware that a nearby test machine does. It doesn’t make sense to load up the development environment onto the test machine for various reasons, so I am a fairly irregular user of &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Remote_debugging&quot; target=&quot;_blank&quot;&gt;remote debugging&lt;/a&gt; against my Win32 application.&lt;/p&gt;&lt;p&gt;As it happens the client language is C++Builder (classic compiler), but I expect this issue to apply equally to Delphi (I’d be interested to know from anyone who can confirm one way or another).&lt;/p&gt;&lt;p&gt;Remote debugging works quite nicely via &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/PAServer,_the_Platform_Assistant_Server_Application&quot; target=&quot;_blank&quot;&gt;PAServer&lt;/a&gt;. It is certainly straightforward in comparison to the games we had to play some years back – PAServer seems to have simplified the setup quite nicely.&lt;/p&gt;&lt;p&gt;Granted, stepping is pretty slow, but then there’s quite a lot going on and a certain amount of information for PAServer retrieve from the remote debugger (rmtdbg250.exe) and then to send back to &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Paclient.exe,_the_Platform_Assistant_Client_Application&quot; target=&quot;_blank&quot;&gt;PAClient&lt;/a&gt; and to the IDE, so I can take that.&lt;/p&gt;&lt;p&gt;What gets my goat, though, is what happens when the program ends. Often I have to kill the application (&lt;font face=&quot;Courier New&quot;&gt;Ctrl+F2&lt;/font&gt;, or Run, Program Reset), but often the application exits quite naturally.&lt;/p&gt;&lt;p&gt;More often than not I can’t make a change in the code and have &lt;font face=&quot;Courier New&quot;&gt;F9&lt;/font&gt; successfully compile and run up the app remotely again. I get this:&lt;/p&gt;&lt;p&gt;&lt;font face=&quot;Courier New&quot;&gt;[PAClient Error] Error: E0009 Cannot create file &quot;\\?\C:\Program Files (x86)\Embarcadero\PAServer\19.0\scratch-dir\some_subfolder\project_name\project_name.tds&quot;. The process cannot access the file because it is being used by another process&lt;/font&gt;&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;p&gt;As it turns out this is indeed true. There are two copies of the remote debugger, rmtdbg250.exe (in the case of RAD Studio 10.2.x) running, at least one of which has a handle open on the TDS symbol file.&lt;/p&gt;&lt;p&gt;This is quite annoying, as I have to use Task Manager to show me the two remote debuggers and manually kill them. In the grand scale of things, there are worse things, of course. But over a number of deploy/debug cycles this does get annoying.&lt;/p&gt;&lt;p&gt;Maybe I need to revert to directly running the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Installing,_Starting,_and_Stopping_the_Remote_Debug_Server&quot; target=&quot;_blank&quot;&gt;Remote Debug Server&lt;/a&gt;?&lt;/p&gt;&lt;p&gt;Anyway, in lieu of a good reason for this and in the absence of good behaviour from the remote debuggers I’ve had to expedite the clean-up process by way of another command script (aka batch file). This gets the process IDs (PIDs) of the remote debuggers and has Windows kill them. It has to do this twice though, as the first time round one of the pesky debugger instances always survives the cull.&lt;/p&gt;&lt;p&gt;Anyway, on the off-chance it is of any use to others, here is the script, which I call KillDebuggers.bat. Apologies for its slightly prolix nature – I like to keep alternative approaches around just to remind myself of how I can do things.&lt;/p&gt;&lt;code&gt;@echo off
&lt;p&gt;rem When remote debugging, this batch file is useful to kill the &lt;br&gt;
rem remote debugger instances that refuse to die naturally&lt;/p&gt;
&lt;p&gt;setlocal&lt;/p&gt;
&lt;p&gt;rem First round&lt;/p&gt;
&lt;p&gt;echo.&amp;amp;echo First round of Wipe Out The Debuggers&amp;amp;echo.&lt;/p&gt;
&lt;p&gt;call :sic_em_boy&lt;/p&gt;
&lt;p&gt;rem Second round&lt;/p&gt;
&lt;p&gt;echo.&amp;amp;echo Second round of Wipe Out The Debuggers&amp;amp;echo.&lt;/p&gt;
&lt;p&gt;call :sic_em_boy&lt;/p&gt;
&lt;p&gt;endlocal&lt;/p&gt;
&lt;p&gt;goto :EOF&lt;/p&gt;
&lt;p&gt;:sic_em_boy&lt;/p&gt;
&lt;p&gt;set CMDLINE=tasklist /FO TABLE /NH /FI &quot;IMAGENAME eq rmtdbg250.exe&quot;&lt;br&gt;
rem This gives output lines like:&lt;/p&gt;
&lt;p&gt;rem rmtdbg250.exe 776 Console 2 6,456 K&lt;/p&gt;
&lt;p&gt;rem The PID is token 2, if we consider this as white space delimited&lt;br&gt;
rem However if no debuggers are running we get:&lt;/p&gt;
&lt;p&gt;rem INFO: No tasks are running which match the specified criteria.&lt;/p&gt;
&lt;p&gt;rem In that message token 2 is &quot;No&quot;&lt;/p&gt;
&lt;p&gt;for /f &quot;tokens=2 delims= &quot; %%A in (&#39;%CMDLINE%&#39;) do (&lt;br&gt;&amp;nbsp; if %%A == No (&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; echo No debugger found!&lt;br&gt;&amp;nbsp; ) else (&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; taskkill /PID %%A&lt;br&gt;&amp;nbsp; )&lt;br&gt;)&lt;/p&gt;
&lt;p&gt;rem Or we could simply say:&lt;/p&gt;
&lt;p&gt;rem taskkill /IM rmtdbg250.exe&lt;/p&gt;
&lt;/code&gt;&lt;p&gt;&lt;code&gt;exit /B&lt;/code&gt;&lt;p&gt;If anyone has any input on this issue, please get in touch via the comments.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/931955932370626142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2017/10/remote-debugger-recalcitrance.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/931955932370626142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/931955932370626142'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2017/10/remote-debugger-recalcitrance.html' title='Remote debugger recalcitrance'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-8263531342872991689</id><published>2017-10-16T12:26:00.001-07:00</published><updated>2017-10-17T12:48:39.494-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>Project corruption bug</title><content type='html'>&lt;p&gt;Long ago there was an issue with the RAD Studio IDE (Delphi and C++Builder both). It meant that when changing certain project options or switching build configurations, the (XML format) project file would get saved with an extra errant (empty) XML element in it, causing subsequent compilations to baulk, complaining about: &lt;em&gt;ProjectExtensions appears multiple time in project&lt;/em&gt;. If you build from the command line the error looks like: &lt;em&gt;[MSBuild Error] MSB4079 The &amp;lt;ProjectExtensions&amp;gt; element occurs more than once&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;The extra line in the file, were you to open it in a text editor and take a look, will be rather like this:&lt;/p&gt;&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ProjectExtensions /&amp;gt;&lt;/code&gt;&lt;p&gt;If you peruse some of the entries in Embarcadero’s Quality Central portal, such as &lt;a href=&quot;https://quality.embarcadero.com/browse/RSP-9774&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt;, &lt;a href=&quot;https://quality.embarcadero.com/browse/RSP-12577&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt; or even &lt;a href=&quot;https://quality.embarcadero.com/browse/RSP-10229&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt;, then you’ll see that Embarcadero made some changes in XE6 that improved matters (done against Quality Central bug 109016, no longer accessible since QC went offline some while back, but in &lt;a href=&quot;http://edn.embarcadero.com/article/43754&quot; target=&quot;_blank&quot;&gt;this list of XE6 fixes&lt;/a&gt;), but clearly has not dismissed the problem entirely. Various customers do continue to hit it, albeit not very reproducibly.&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;p&gt;This set of affected customers does include myself. I was hitting this issue very regularly in C++Builder XE3 and this then continued (perhaps less frequently, I’m not sure) in more recent versions of the product.&lt;/p&gt;&lt;p&gt;I think one of the reasons the issue doesn’t get more coverage is that the IDE appears &lt;em&gt;generally&lt;/em&gt; not to mind when the project file gets an extra &lt;font face=&quot;Courier New&quot;&gt;ProjectExtensions&lt;/font&gt; element inserted. Indeed it may well be the case that the internal IDE state&amp;nbsp; is more correct than what gets written to the file so generally it will be command-line builds that fail more than IDE builds, with the errant file element often getting removed during subsequent saves of the project.&lt;/p&gt;&lt;p&gt;Whatever the specifics, the IDE issue &lt;em&gt;is&lt;/em&gt; most definitely still present, but it is seems to be proving extremely tricky to get a reproducible test case to submit, as it seems to be subject to the whims of the weather, almost.&lt;/p&gt;&lt;p&gt;For me this is quite frustrating. I use an automated build system and it is a fairly regular occurrence that after checking in a changed project file (say after bumping the version number a bit) the build system will see the repository change, pull out the updates and set off a new build. Then shortly thereafter I’ll be notified of a build failure, and I’ll see it’s another occurrence of the broken project, which I then need to fix with a text editor and check in again.&lt;/p&gt;&lt;p&gt;In order to save my sanity I now use the &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/ReFind.exe,_the_Search_and_Replace_Utility_Using_Perl_RegEx_Expressions&quot; target=&quot;_blank&quot;&gt;reFind.exe&lt;/a&gt; command (the Regular Expression find and replace tool &lt;a href=&quot;http://blog.marcocantu.com/blog/refind_and_bde_migration.html&quot; target=&quot;_blank&quot;&gt;added in XE5&lt;/a&gt;) on the build server. The automated build system we use (&lt;a href=&quot;https://jenkins.io/&quot; target=&quot;_blank&quot;&gt;Jenkins&lt;/a&gt; in our case, which I personally think is absolutely fabulous!) pulls out changed files from the version control repository, runs reFind to fix any possibly broken projects and then builds from there on it.&lt;/p&gt;&lt;p&gt;Here’s an example of a call to reFind, which lives in RAD Studio’s bin directory:&lt;/p&gt;&lt;code&gt;refind project_name.dproj /L &quot;/P:^\s*&amp;lt;ProjectExtensions\s/&amp;gt;\s*$\r\n&quot; &quot;/R:&quot;&lt;/code&gt;&lt;p&gt;This does a multi-line search to locate any lines that contain only an empty &lt;font face=&quot;Courier New&quot;&gt;ProjectExtensions&lt;/font&gt; element (plus optional whitespace where that may be found) and replaces it with nothing, i.e. deletes it.&lt;/p&gt;&lt;p&gt;[ &lt;u&gt;Update&lt;/u&gt; – 17/10/2017&lt;/p&gt;&lt;p&gt;It should perhaps be explicitly noted that my suggested use of reFind works quite nicely on an automated build server, where command-line builds are the order of the day. However, if you try the same trick on your development machine and the project happens to open in the IDE, well you perhaps won;t be surprised to see the IDE spot the change to the project file and immediately pop up and invite you to let it reload. That might be a bit annoying every time you run a command-line build. So apply some thought and judgement to where you use the reFind trick.&lt;/p&gt;&lt;p&gt;End Update ]&lt;/p&gt;&lt;p&gt;[ &lt;u&gt;Update&lt;/u&gt; 2 – 17/10/2017&lt;/p&gt;&lt;p&gt;Just for completeness, if you just want to find out if your project has the ProjectExtensions issue you can use this grep call (&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/GREP.EXE,_the_text_search_utility&quot; target=&quot;_blank&quot;&gt;grep.exe&lt;/a&gt; is also supplied in the RAD Studio bin directory, but its implementation of regular expressions is not &lt;em&gt;quite&lt;/em&gt; the same as reFind’s):&lt;/p&gt;&lt;p&gt;&lt;font face=&quot;Courier New&quot;&gt;grep -e &quot;^[ \t]*&amp;lt;ProjectExtensions[ \t]*/&amp;gt;[ \t]*$&quot; project_name.dproj&lt;/font&gt;&lt;/p&gt;&lt;p&gt;End Update ]&lt;/p&gt;&lt;p&gt;Some of the jobs that I have set up in Jenkins send custom emails, in addition to the normal “build failure” emails. I wrote a little command line tool that uses &lt;a href=&quot;http://www.blat.net/&quot; target=&quot;_blank&quot;&gt;Blat&lt;/a&gt; to send emails under certain criteria, such as when a build completes with a new version number. Yes, I could have &lt;a href=&quot;http://www.indyproject.org/Sockets/Blogs/RLebeau/20080116.EN.aspx&quot; target=&quot;_blank&quot;&gt;used Indy quite straightforwardly&lt;/a&gt; to do the same, but I just rustled up a batch file to drive Blat instead.&lt;/p&gt;&lt;p&gt;Anyway, I mention this as I suspect I’ll try and use it also to send an email if reFind is seen to have found an errant &lt;font face=&quot;Courier New&quot;&gt;ProjectExtensions&lt;/font&gt; element in the project file. Being notified that there is an issue in the project file for me to fix as and when I decide to is preferable (IMHO) to the build breaking and forcing my hand there and then.&lt;/p&gt;&lt;p&gt;Of course all of this may be at odds to your own point of view. You may well consider a broken project file to warrant immediate repair, and welcome a build failure with open arms, but this is not the case in my setup. Horses for courses, and all that. I thought I’d just share the idea while I was in a sharing mood.&lt;/p&gt;&lt;p&gt;tl;dr – reFind is a nifty search and replace tool: check it out!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/8263531342872991689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2017/10/project-corruption-bug.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/8263531342872991689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/8263531342872991689'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2017/10/project-corruption-bug.html' title='Project corruption bug'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-4172627032829746198</id><published>2017-10-14T08:19:00.001-07:00</published><updated>2017-10-19T04:28:39.431-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>Delphi build/install/launch Android app from the command-line</title><content type='html'>&lt;p&gt;Quite some while back I &lt;a href=&quot;https://stackoverflow.com/a/39669011&quot; target=&quot;_blank&quot;&gt;answered a question on Stack Overflow&lt;/a&gt;, which explained how to build a Delphi project from the command line and also how to deploy it. The context of the question was Andriod development&lt;/p&gt;&lt;p&gt;In the case of an Android application deploying it has absolutely nothing to do with installing the resultant .apk file onto your Android device, despite what your personal interpretation of the word may be. Oh no, most definitely not.&lt;/p&gt;&lt;p&gt;Instead, deployment is about packaging up all your various files - your compiled Android library (a .so file), all the images, splash screens, icons, custom files, databases, application manifest file and so forth – all into an .apk file. In other words as far as the Delphi IDE is concerned, deploying a Delphi project means going from a .so native ARM library to an install&lt;em&gt;&lt;strong&gt;able&lt;/strong&gt;&lt;/em&gt; .apk file.&lt;/p&gt;&lt;p&gt;Clearly when you press &lt;font face=&quot;Courier New&quot;&gt;F9&lt;/font&gt; or &lt;font face=&quot;Courier New&quot;&gt;Ctrl+Shift+F9&lt;/font&gt; to run your application the IDE works out how to install your .apk on the currently connected and selected device, but that is subsequent to the IDE’s notion of the deployment step.&lt;/p&gt;&lt;p&gt;So, installation notwithstanding, &lt;a href=&quot;https://stackoverflow.com/a/39669011&quot; target=&quot;_blank&quot;&gt;that SO answer&lt;/a&gt; shows how to make/build and deploy a Delphi project, such as an Android project, from a RAD Studio command prompt:&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;p&gt;To recap on it this does a build:&lt;/p&gt;&lt;code&gt;msbuild Foo.dproj /p:Config=Debug /p:Platform=Android /t:Build&lt;/code&gt;&lt;p&gt;This does a make, which only compiles files that have changed:&lt;/p&gt;&lt;code&gt;msbuild Foo.dproj /p:Config=Debug /p:Platform=Android /t:Make&lt;/code&gt;&lt;p&gt;This step, assuming you have done a deployment at least once in the IDE and thereby have had a Foo.deployproj file generated, will do the deployment:&lt;/p&gt;&lt;code&gt;msbuild Foo.dproj /p:Config=Debug /p:Platform=Android /t:Deploy&lt;/code&gt;&lt;p&gt;If you have the .deployproj file you can combine the two steps in this one command (excuse any line wrapping this blog theme applies):&lt;/p&gt;&lt;code&gt;msbuild Foo.dproj /p:Config=Debug /p:Platform=Android /t:Make;Deploy&lt;/code&gt;&lt;p&gt;[&lt;u&gt;Update&lt;/u&gt; – 16/10/2-17:&lt;/p&gt;&lt;p&gt;I also &lt;a href=&quot;https://stackoverflow.com/a/46778286/2817399&quot; target=&quot;_blank&quot;&gt;bumped into&lt;/a&gt; the property that controls the Target Configuration, which can be Development or Application Store for Android. The &lt;font face=&quot;Courier New&quot;&gt;BT_BuildType&lt;/font&gt; can either be &lt;font face=&quot;Courier New&quot;&gt;Debug&lt;/font&gt; or &lt;font face=&quot;Courier New&quot;&gt;AppStore&lt;/font&gt; for Android (for iOS there is also &lt;font face=&quot;Courier New&quot;&gt;AdHoc&lt;/font&gt;. So if you want to build a signed app ready for upload to the Google Play store you could run:&lt;/p&gt;&lt;code&gt;msbuild Foo.dproj /p:Config=Release /p:Platform=Android /t:Make;Deploy /p:BT_BuildType=AppStore&lt;/code&gt;&lt;p&gt;&lt;u&gt;End Update&lt;/u&gt; ]&lt;/p&gt;&lt;p&gt;So anyway, history to one side, I was wondering if there was another MSBuild target that did the installation, or if this was some custom code in the IDE, not exposed through MSBuild. My investigation suggests the latter to be the case, but I wanted a convenient command-line way to make, deploy and install the Android application (and even possibly launch it!).&lt;/p&gt;&lt;p&gt;The best option I could rustle up at short notice was a batch file (or command script, if you prefer). Save the file below as BuildAndInstall.bat or BuildAndInstall.cmd, set up any of the paths etc. that need personalising to your system.&lt;/p&gt;&lt;p&gt;Again, please excuse unsolicited line wrapping…. There is probably a nifty way to get this code into a horizontally scrollable &lt;font face=&quot;Courier New&quot;&gt;div&lt;/font&gt; or similar, but I don’t have the time to do the research just now….&lt;/p&gt;&lt;pre&gt;@echo off&lt;/pre&gt;&lt;pre&gt;rem Syntax&lt;br&gt;rem&amp;nbsp; Arg 1 = project name&lt;br&gt;rem&amp;nbsp; Arg 2 (optional) = build configuration&lt;br&gt;rem&amp;nbsp; Arg 3 (optional) = package name&lt;/pre&gt;&lt;pre&gt;set ANDROID_SDK=%PUBLIC%\Documents\Embarcadero\Studio\19.0\PlatformSDKs\android-sdk-windows&lt;br&gt;set ADB=%ANDROID_SDK%\platform-tools\adb.exe&lt;br&gt;set FQ_PROJECT=%~f1&lt;br&gt;set PROJECT_DIR=%~p1&lt;br&gt;set PROJECT_NAME=%~n1&lt;br&gt;set PACKAGE_NAME=com.embarcadero.%PROJECT_NAME%&lt;br&gt;set CONFIG=Debug&lt;/pre&gt;&lt;pre&gt;if X%1 == X goto syntax&lt;/pre&gt;&lt;pre&gt;if not exist %1 (&lt;br&gt;&amp;nbsp; echo Cannot locate project %FQ_PROJECT%&lt;br&gt;&amp;nbsp; goto :EOF&lt;br&gt;)&lt;/pre&gt;&lt;pre&gt;if not X%2 == X (&lt;br&gt;&amp;nbsp; if &quot;%2&quot; == &quot;Release&quot; set CONFIG=Release&lt;br&gt;)&lt;/pre&gt;&lt;pre&gt;if not X%3 == X (&lt;br&gt;&amp;nbsp; set PACKAGE_NAME=%3&lt;br&gt;)&lt;/pre&gt;&lt;pre&gt;pushd %PROJECT_DIR%&lt;/pre&gt;&lt;pre&gt;echo.&amp;amp;echo Building %1&amp;amp;echo.&lt;/pre&gt;&lt;pre&gt;msbuild %PROJECT_NAME%.dproj /p:Config=%CONFIG% /p:Platform=Android /t:Make || goto build_error&lt;/pre&gt;&lt;pre&gt;echo.&amp;amp;echo Deploying %1&amp;amp;echo.&lt;/pre&gt;&lt;pre&gt;msbuild %PROJECT_NAME%.dproj /p:Config=%CONFIG% /p:Platform=Android /t:Deploy || goto deploy_error&lt;/pre&gt;&lt;pre&gt;echo.&amp;amp;echo Installing Android package&amp;amp;echo.&lt;/pre&gt;&lt;pre&gt;%ADB% install -r Android\%CONFIG%\%PROJECT_NAME%\bin\%PROJECT_NAME%.apk || goto install_error&lt;/pre&gt;&lt;pre&gt;echo.&amp;amp;echo Launching Android app&amp;amp;echo.&lt;/pre&gt;&lt;pre&gt;%ADB% -d shell am start -a android.intent.action.MAIN -n %PACKAGE_NAME%/com.embarcadero.firemonkey.FMXNativeActivity || goto launch_error&lt;/pre&gt;&lt;pre&gt;popd&lt;/pre&gt;&lt;pre&gt;echo.&amp;amp;echo Done!&lt;/pre&gt;&lt;pre&gt;goto :EOF&lt;/pre&gt;&lt;pre&gt;:syntax&lt;/pre&gt;&lt;pre&gt;echo BuildAndInstall syntax:&lt;br&gt;echo.&lt;br&gt;echo&amp;nbsp;&amp;nbsp; BuildAndInstall ^&amp;lt;DelphiProjectFile^&amp;gt; [^&amp;lt;Configuration^&amp;gt; [^&amp;lt;AndroidPackageName^&amp;gt;]]&lt;br&gt;echo.&lt;br&gt;echo where:&lt;br&gt;echo.&lt;br&gt;echo ^&amp;lt;DelphiprojectFile^&amp;gt; is a Delphi project.dproj file&lt;br&gt;echo ^&amp;lt;Configuration^&amp;gt; is the required build configuration, Release or Debug, which defaults to Debug&lt;br&gt;echo ^&amp;lt;AndroidPackageName^&amp;gt; is the Android package name for the project, in case it is different from com.embarcadero.project&lt;br&gt;goto :EOF&lt;/pre&gt;&lt;pre&gt;:build_error&lt;/pre&gt;&lt;pre&gt;echo Problem encountered while build the Android lib%PROJECT_NAME%.so native library&lt;br&gt;goto :EOF&lt;/pre&gt;&lt;pre&gt;:deploy_error&lt;/pre&gt;&lt;pre&gt;echo Problem encountered while creating the %PROJECT_NAME%.apk Android package&lt;br&gt;goto :EOF&lt;/pre&gt;&lt;pre&gt;:install_error&lt;/pre&gt;&lt;pre&gt;echo Problem encountered while installing %PROJECT_NAME%.apk&lt;br&gt;goto :EOF&lt;/pre&gt;&lt;pre&gt;:launch_error&lt;/pre&gt;&lt;pre&gt;echo Problem encountered while launching %PROJECT_NAME%.apk&lt;br&gt;goto :EOF&lt;delphiprojectfile   ^=&quot;&quot;&gt;&lt;configuration   ^=&quot;&quot;&gt;&lt;androidpackagename   ^=&quot;&quot;&gt;&lt;delphiprojectfile   ^=&quot;&quot;&gt;&lt;configuration   ^=&quot;&quot;&gt;&lt;androidpackagename   ^=&quot;&quot;&gt;
&lt;/androidpackagename&gt;&lt;/configuration&gt;&lt;/delphiprojectfile&gt;&lt;/androidpackagename&gt;&lt;/configuration&gt;&lt;/delphiprojectfile&gt;&lt;/pre&gt;&lt;p&gt;If you young pups reading this are all into relatively modern PowerShell scripting or traditional Windows scripting, then this throwback to the world of DOS may fall uneasily on the eye, but it works and there is a lot of power available in DOS scripting commands.&lt;/p&gt;&lt;p&gt;[ &lt;u&gt;Update&lt;/u&gt; – 16/10/2017: I initially forgot to mention that you’d be wise to run this from a RAD Studio Command Prompt for the version of RAD Studio that you want to build your project. This ensures that the Windows search path is set up to find the correct compilers etc. Alternatively, at the top of my batch file you can do the equivalent of running a RAD Studio Command Prompt by inserting:&lt;/p&gt;&lt;code&gt;CALL C:\Program Files (x86)\Embarcadero\Studio\19.0\bin\rsvars.bat&lt;/code&gt;&lt;p&gt;If you choose this latter option then you can use any old command prompt you like.&lt;/p&gt;&lt;p&gt;&lt;u&gt;End Update&lt;/u&gt; ]&lt;/p&gt;&lt;p&gt;Now you can install and run an Android project with a command-line of:&lt;/p&gt;&lt;code&gt;BuildAndInstall Foo.dproj&lt;/code&gt;&lt;p&gt;if you want the release build, use:&lt;/p&gt;&lt;code&gt;BuildAndInstall Foo.dproj Release&lt;/code&gt;&lt;p&gt;If you’ve changed the package name (specified as package in the project options Version Info page) from the default com.embarcadero.Foo then to launch the app you’ll need to pass the package name on the command line:&lt;/p&gt;&lt;code&gt;BuildAndInstall Foo.dproj Debug com.blong.Foo&lt;/code&gt;&lt;p&gt;Don’t forget that you will have to choose Project, Deploy libProjectname.so in the IDE menus once before this will work.&lt;/p&gt;&lt;p&gt;I hope this is of use to someone….&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/4172627032829746198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2017/10/delphi-buildinstall-to-android-from.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4172627032829746198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4172627032829746198'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2017/10/delphi-buildinstall-to-android-from.html' title='Delphi build/install/launch Android app from the command-line'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-2716105744895541108</id><published>2017-10-14T08:12:00.001-07:00</published><updated>2017-10-17T12:50:34.968-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>EKON 21</title><content type='html'>&lt;p&gt;I’m delighted to say that later this month I’ll be over in Cologne speaking at &lt;a href=&quot;https://entwickler-konferenz.de/&quot; target=&quot;_blank&quot;&gt;EKON 21&lt;/a&gt;, which runs from 23rd to 25th October, 2017 and is being held in Cologne in Germany.&amp;nbsp; I’m &lt;a href=&quot;https://entwickler-konferenz.de/speaker/brian-long/&quot; target=&quot;_blank&quot;&gt;doing three Delphi-related talks&lt;/a&gt; on some of my favourite subjects: creative debugging, Android API usage and IDE tips/techniques.&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;Unfortunately, though, being as all three talks are in the same day, Tuesday 24th October, I’m not sure I’ll get to see much of &lt;a href=&quot;https://entwickler-konferenz.de/program-en/&quot; target=&quot;_blank&quot;&gt;the other great talks on offer&lt;/a&gt;, which is a shame for me.&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;It’s great to be &lt;a href=&quot;http://blong.com/Conferences.htm#EKON21&quot; target=&quot;_blank&quot;&gt;heading back to EKON&lt;/a&gt; – I haven’t been over to Germany for a conference since long ago in 2004 at the joint &lt;a href=&quot;http://blong.com/Conferences.htm#BorConEurope2004&quot; target=&quot;_blank&quot;&gt;BorCon Europe 2004 / EKON 8 conference&lt;/a&gt; in Frankfurt.&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;p align=&quot;left&quot;&gt;In 2004 I was into interoperability between unmanaged code (&lt;a href=&quot;http://blong.com/Conferences/BorCon2004/Interop1/Win32AndDotNetInterop.htm&quot; target=&quot;_blank&quot;&gt;Win32&lt;/a&gt; and &lt;a href=&quot;http://blong.com/Conferences/BorCon2004/Interop2/COMNetInterop.htm&quot; target=&quot;_blank&quot;&gt;COM&lt;/a&gt;) and .NET code, as well as &lt;a href=&quot;http://blong.com/Conferences/DCon2003/Internals/Profiling.htm&quot; target=&quot;_blank&quot;&gt;building .NET profiling tools&lt;/a&gt;. This year my Android talk is not a million miles from those old interoperability talks, looking at how to reach out from unmanaged Delphi Android ARM code to managed Java code, for various purposes and reasons.&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;The debugging talk continues my efforts to help Delphi developers get better value for money from their debugger and debugging tools. This is a mission I’ve been on since the start of this century after having been inspired after watching Danny Thorpe do an excellent session at a BorCon in the late 90s, showing how to really utilise the CPU window and not see it simply as a source of horror.&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;The IDE tips talk is also an evolution of a session I’ve done on and off over the course of this century, trying to share knowledge of the IDE, code editor and so on that will help you do your job just that bit faster.&lt;/p&gt;&lt;p&gt;These talks are all based around Delphi although the concepts (and in some cases the specifics) are equally as applicable to C++Builder. I spend a lot of my working day working with C++Builder with a few regular clients and it is still a goal of mine to start getting more C++Builder information onto this blog.&lt;/p&gt;&lt;p&gt;If any readers are going to EKON 21, I hope to see you there and look forward to a great conference!&lt;/p&gt;&lt;p&gt;[ As seems to usually be the case, it’s been a much longer gap than I would like since I last put &lt;strike&gt;pen&lt;/strike&gt; finger to &lt;strike&gt;paper&lt;/strike&gt; keyboard for this blog. Mea culpa – I will endeavour to allot more time for this sort of thing, or more particularly for posts of general practical value ]&lt;/p&gt;&lt;p align=&quot;left&quot;&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/2716105744895541108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2017/10/ekon-21.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/2716105744895541108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/2716105744895541108'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2017/10/ekon-21.html' title='EKON 21'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-7447839059235690288</id><published>2016-11-22T03:15:00.001-08:00</published><updated>2017-10-17T12:51:23.842-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="iPhone"/><category scheme="http://www.blogger.com/atom/ns#" term="Mac"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>Debug logging in FireMonkey – CodeRage XI Lightning Talks</title><content type='html'>&lt;p&gt;During &lt;a href=&quot;https://community.embarcadero.com/article/technical-articles/16433-coderage-xi-productivity-platforms-and-performance&quot; target=&quot;_blank&quot;&gt;CodeRage XI&lt;/a&gt; I had a couple of Lightning Talks broadcast on a subject I’ve been intending to write up for quite a long time, but haven’t quite managed to achieve: how to emit debug log messages on the various FireMonkey platforms.&lt;/p&gt; &lt;p&gt;I made a 10 minute video for Delphi and one for C++ looking at all the target platforms, Win32/Win64, OS X/macOS, Android and iOS, showing the logging options and then looking at how to view log output.&lt;/p&gt; &lt;p&gt;Unfortunately I got a bit caught up in some work and didn’t publicise this ahead of the conference, so I think not many people were aware of them.&lt;/p&gt; &lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;p&gt;If you want to see the short videos after the fact, you can see them below or on YouTube:&lt;/p&gt; &lt;p&gt;&lt;u&gt;Debug Logging in Delphi FireMonkey Apps&lt;/u&gt; &lt;/p&gt; &lt;p&gt;&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/U3rHwL_Q7W8&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;&lt;u&gt;Debug Logging in C++ FireMonkey Apps&lt;/u&gt;&lt;/p&gt; &lt;p&gt;&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/F3beANOZYOc&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;You can look at the supporting (short) slideshows on SlideShare (ignore the funky bullet point symbols – something was awry in the slide template when I made the slides):&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.slideshare.net/BrianLong61/debug-logging-in-delphi-firemonkey-apps&quot; target=&quot;_blank&quot;&gt;Debug Logging in Delphi FireMonkey Apps&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;iframe width=&quot;595&quot; height=&quot;380&quot; src=&quot;http://www.slideshare.net/slideshow/embed_code/key/8yaRxRsOE18KqB&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;&quot; style=&quot;border: 1px solid rgb(204, 204, 204); margin-bottom: 5px; max-width: 100%;&quot;&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://www.slideshare.net/BrianLong61/debug-logging-in-c-firemonkey-apps&quot; target=&quot;_blank&quot;&gt;Debug Logging in C++ FireMonkey Apps&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;iframe width=&quot;595&quot; height=&quot;380&quot; src=&quot;http://www.slideshare.net/slideshow/embed_code/key/xx6ioTYZdZfNGe&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;&quot; style=&quot;border: 1px solid rgb(204, 204, 204); margin-bottom: 5px; max-width: 100%;&quot;&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;The simple sample projects are also available to download:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&quot;http://blong.com/Downloads/CodeRageXI-DebugLoggingInDelphi.7z&quot; target=&quot;_blank&quot;&gt;Debug Logging in Delphi FireMonkey Apps samples&lt;/a&gt;  &lt;li&gt;&lt;a href=&quot;http://blong.com/Downloads/CodeRageXI-DebugLoggingInCPlusPlus.7z&quot; target=&quot;_blank&quot;&gt;Debug Logging in C++ FireMonkey Apps samples&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/7447839059235690288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2016/11/debug-logging-in-firemonkey-coderage-xi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/7447839059235690288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/7447839059235690288'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2016/11/debug-logging-in-firemonkey-coderage-xi.html' title='Debug logging in FireMonkey – CodeRage XI Lightning Talks'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/U3rHwL_Q7W8/default.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-7445656030090300820</id><published>2016-09-09T16:13:00.001-07:00</published><updated>2017-10-17T12:52:11.563-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>Android callbacks wrapped by FireMonkey</title><content type='html'>&lt;p&gt;A couple of years ago (exactly!) I &lt;a href=&quot;http://blog.blong.com/2014/09/delphi-and-nfc-on-android.html&quot; target=&quot;_blank&quot;&gt;posted on this blog&lt;/a&gt; about &lt;a href=&quot;http://blong.com/Articles/DelphiXE7NFC/NFC.htm&quot; target=&quot;_blank&quot;&gt;an article&lt;/a&gt; I’d written on accessing NFC tags from Delphi Android applications. At the time this was quite an involved exercise, requiring custom Java code to be compiled and linked in to the application in order to respond to the pertinent Android callback, &lt;a href=&quot;https://developer.android.com/reference/android/app/Activity.html#onNewIntent(android.content.Intent)&quot; target=&quot;_blank&quot;&gt;&lt;font face=&quot;Courier New&quot;&gt;Activity.onNewIntent&lt;/font&gt;&lt;/a&gt;. Indeed, Delphi versions XE5, XE6 and XE7 all have slightly differing capabilities, with each new release making certain Android operations rather easier.&lt;/p&gt; &lt;p&gt;While catching up on what’s new in recent releases of Delphi I realised a change had been snuck into Delphi 10 Seattle that makes the whole NFC exercise much more straightforward now in Delphi.&lt;/p&gt;&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;p&gt;What this change means is:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;No more custom Java code required!  &lt;li&gt;No more linking in a custom Java library file  &lt;li&gt;No more activity custom subclassing!  &lt;li&gt;No more debugging obstacles!&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This change seems to have gone in completely under the radar*, escaping the attention of the documentation department, so I thought it best that I brought it out into the open.&lt;/p&gt; &lt;p&gt;It turns out that the key activity callback that NFC foreground dispatch relies upon (&lt;font face=&quot;Courier New&quot;&gt;&lt;a href=&quot;https://developer.android.com/reference/android/app/Activity.html#onNewIntent(android.content.Intent)&quot; target=&quot;_blank&quot;&gt;Activity.onNewIntent&lt;/a&gt;&lt;/font&gt;) is now hookable from Delphi code (with the right know-how) and so all the Java shenanigans can be put behind us (at least in the context of NFC access). This callback is used in Android in all sorts of other scenarios as well, so if you find a requirement for responding to &lt;font face=&quot;Courier New&quot;&gt;onNewIntent&lt;/font&gt; then Delphi 10 Seattle (and later) makes this something of a doddle.&lt;/p&gt; &lt;p&gt;I have updated the article to show the more direct means of &lt;a href=&quot;http://blong.com/Articles/Delphi10NFC/NFC.htm&quot; target=&quot;_blank&quot;&gt;accessing NFC from Delphi 10 Seattle and later&lt;/a&gt; and provided corresponding updated samples for &lt;a href=&quot;http://blong.com/Articles/Delphi10NFC/NFC_Samples_10_Seattle.7z&quot; target=&quot;_blank&quot;&gt;Delphi 10 Seattle&lt;/a&gt; and &lt;a href=&quot;http://blong.com/Articles/Delphi10NFC/NFC_Samples_10.1_Berlin.7z&quot; target=&quot;_blank&quot;&gt;Delphi 10.1 Berlin&lt;/a&gt;. You can find the full details and code there.&lt;/p&gt; &lt;p&gt;In short, though, new intents are picked up in the FireMonkey activity’s &lt;font face=&quot;Courier New&quot;&gt;onNewIntent&lt;/font&gt; method and sent into &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Using_the_RTL_Cross-Platform_Messaging_Solution&quot; target=&quot;_blank&quot;&gt;the RTL cross-platorm messaging system&lt;/a&gt;. You can write &lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/Sending_and_Receiving_Messages_Using_the_RTL&quot; target=&quot;_blank&quot;&gt;message-receiving code&lt;/a&gt; to pick up new intents and process them, This intent messaging is done via an additional (and seemingly undocumented) use of the Android-specific &lt;font face=&quot;Courier New&quot;&gt;&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/en/List_of_FireMonkey_Message_Types#Android_Message_Types&quot; target=&quot;_blank&quot;&gt;TMessageReceivedNotification&lt;/a&gt;&lt;/font&gt; message.&lt;/p&gt; &lt;p&gt;If you are playing with NFC cards in your apps you can simplify the setup very nicely in the most recent versions of Delphi.&lt;/p&gt; &lt;p&gt;Just to round this topic (given the blog subject) off I’ll also mention that another activity callback, &lt;font face=&quot;Courier New&quot;&gt;&lt;a href=&quot;http://d.android.com/reference/android/app/Activity.html#onActivityResult(int, int, android.content.Intent)&quot; target=&quot;_blank&quot;&gt;onActivityResult&lt;/a&gt;&lt;/font&gt;, is also covered by FireMonkey and has been since Delphi XE6. This is also wrapped up in the same messaging system, though this time with the &lt;font face=&quot;Courier New&quot;&gt;&lt;a href=&quot;http://docwiki.embarcadero.com/RADStudio/XE6/en/List_of_FireMonkey_Message_Types#Android_Message_Types&quot; target=&quot;_blank&quot;&gt;TMessageResultNotification&lt;/a&gt;&lt;/font&gt; message.&lt;/p&gt; &lt;p&gt;I showed an example of how to use this to pick up information about a scanned barcode (scanned by the popular and open Source ZXing, or Zebra Crossing, &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.google.zxing.client.android&quot; target=&quot;_blank&quot;&gt;barcode scanner app&lt;/a&gt;) in an article about launching various activity types back in April 2014: &lt;a href=&quot;http://blong.com/Articles/DelphiXE6AndroidActivityResult/ActivityResult.htm&quot; target=&quot;_blank&quot;&gt;Launching activities and handling results in Delphi XE6 Android apps&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;* Update [16/09/2016]: I have since discovered that both Delphi 10 Seattle and Delphi 10.1 Berlin ship with an Android intents demo that does in fact utilise this feature. The demo is located at:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Delphi 10 Seattle: %PUBLIC%\Documents\Embarcadero\Studio\17.0\Samples\Object Pascal\Mobile Snippets\AndroidIntents, &lt;a href=&quot;http://docwiki.embarcadero.com/CodeExamples/Seattle/en/FMX.Android_Intents_Sample&quot; target=&quot;_blank&quot;&gt;documented here&lt;/a&gt;  &lt;li&gt;Delphi 10.1 Berlin: %PUBLIC%\Documents\Embarcadero\Studio\18.0\Samples\Object Pascal\Mobile Snippets\AndroidIntents, &lt;a href=&quot;http://docwiki.embarcadero.com/CodeExamples/Berlin/en/FMX.Android_Intents_Sample&quot; target=&quot;_blank&quot;&gt;documented here&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The most up to date version of the demo can be found in the &lt;a href=&quot;https://sourceforge.net/p/radstudiodemos/code/HEAD/tree/branches/RADStudio_Seattle/Object%20Pascal/Mobile%20Snippets/AndroidIntents/&quot; target=&quot;_blank&quot;&gt;Delphi 10 Seattle Sourceforce repository&lt;/a&gt; or the &lt;a href=&quot;https://sourceforge.net/p/radstudiodemos/code/HEAD/tree/branches/RADStudio_Berlin/Object%20Pascal/Mobile%20Snippets/AndroidIntents/&quot; target=&quot;_blank&quot;&gt;Delphi 10.1 Berlin Sourceforge repository&lt;/a&gt;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/7445656030090300820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2016/09/android-callbacks-wrapped-by-firemonkey.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/7445656030090300820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/7445656030090300820'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2016/09/android-callbacks-wrapped-by-firemonkey.html' title='Android callbacks wrapped by FireMonkey'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-2797524453277598904</id><published>2016-09-01T02:10:00.001-07:00</published><updated>2016-09-01T02:25:59.474-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>Speaking at the SDN Event</title><content type='html'>&lt;p&gt;All the preparations are nigh on complete and this evening I shall be on a short aeroplane ride to Holland (or The Netherlands, if you prefer) to present a couple of Delphi talks at one of the &lt;a href=&quot;http://sdn.nl/&quot; target=&quot;_blank&quot;&gt;SDN&lt;/a&gt;’s big SDN Events – &lt;a href=&quot;http://sdn.nl/EVENTS/2-september-2016&quot; target=&quot;_blank&quot;&gt;full agenda here&lt;/a&gt;. I’ll be in good company as also speaking on the Delphi track will be &lt;a href=&quot;http://www.tmssoftware.com/&quot; target=&quot;_blank&quot;&gt;TMS Software&lt;/a&gt;’s &lt;a href=&quot;http://www.tmssoftware.com/site/brunofierens.asp&quot; target=&quot;_blank&quot;&gt;Bruno Fierens&lt;/a&gt; and also &lt;a href=&quot;http://drbob42.com/&quot; target=&quot;_blank&quot;&gt;Bob Swart&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;I’ve spoken at &lt;a href=&quot;http://blong.com/UserGroupTalks.htm&quot; target=&quot;_blank&quot;&gt;User Groups&lt;/a&gt; regularly but this is the first opportunity for me to talk to Delphi developers from further afield &lt;a href=&quot;http://blong.com/Conferences.htm&quot; target=&quot;_blank&quot;&gt;at a conference&lt;/a&gt; since April 2015 when I was at the &lt;a href=&quot;http://blong.com/Conferences.htm#ADUG15&quot; target=&quot;_blank&quot;&gt;ADUG Symposium&lt;/a&gt;, speaking in Canberra and Melbourne.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://sdn.nl/&quot; target=&quot;_blank&quot;&gt;SDN&lt;/a&gt; events are always friendly gatherings and I’ve spoken at a few of them over the years: 1997, 1999, 2002, 2005, 2006 and 2012.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blong.com/Conferences.htm#SDC2016&quot; target=&quot;_blank&quot;&gt;This time around&lt;/a&gt; I will be speaking on two of my favourite subjects: creative debugging techniques and accessing the Android OS API. Naturally I’ll be using the latest and greates version of Delphi as a vehicle for the talks, and I’ll be trying to squeeze in as many technical tips, tricks and techniques as I can into the 2 hour-long sessions.&lt;/p&gt; &lt;p&gt;For those attending the event tomorrow (2nd September, 2016) I’ll see you there!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/2797524453277598904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2016/09/speaking-at-sdn-event.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/2797524453277598904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/2797524453277598904'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2016/09/speaking-at-sdn-event.html' title='Speaking at the SDN Event'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1853768304794693097.post-4948610562984746725</id><published>2016-06-23T09:38:00.001-07:00</published><updated>2016-10-03T07:52:46.453-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CPlusPlus"/><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>Live Templates (née Code Templates)</title><content type='html'>&lt;p&gt;Over the years since Delphi 3 various people have written about aspects of Code Templates and Live Templates, but not particularly recently. I find Code Templates fabulously helpful and Live Templates add some real power into the mix.&lt;/p&gt; &lt;p&gt;About six or seven months ago (November 2015) I did a &lt;a href=&quot;http://blong.com/UserGroupTalks.htm&quot; target=&quot;_blank&quot;&gt;User Group talk&lt;/a&gt; on Live Templates and it seemed to provoke some reasonable interest. Since then I’ve been trying to find a suitable time window to sit down and write it all up. At last I have had a couple of days to gather my thoughts and get it all down on (metaphorical) paper.&lt;/p&gt; &lt;p&gt;For the benefit of those who haven’t considered creating Live Templates to help their productivity, or who have forgotten about the feature over time, please feel free to peruse &lt;a href=&quot;http://blong.com/Articles/CodeTemplates&quot; target=&quot;_blank&quot;&gt;Code Templates and Live Templates&lt;/a&gt; over on my web site.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.blong.com/feeds/4948610562984746725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.blong.com/2016/06/live-templates-nee-code-templates.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4948610562984746725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1853768304794693097/posts/default/4948610562984746725'/><link rel='alternate' type='text/html' href='http://blog.blong.com/2016/06/live-templates-nee-code-templates.html' title='Live Templates (née Code Templates)'/><author><name>blong</name><uri>http://www.blogger.com/profile/15865043713752235355</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>