<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8094471332664349731</id><updated>2011-12-14T02:53:34.918-08:00</updated><category term='alias'/><category term='clipper'/><category term='tricks'/><category term='dll'/><category term='dicas'/><category term='imagens'/><category term='Word'/><category term='bmp'/><category term='library'/><category term='form'/><category term='Arquivos Texto'/><category term='grid'/><category term='Paradox'/><category term='status bar'/><category term='mouse'/><category term='hint'/><category term='edit'/><category term='campo'/><category term='delete'/><category term='Fontes'/><category term='Source'/><category term='sql'/><category term='palavras reservadas'/><category term='tips'/><category term='cores'/><category term='icones'/><category term='tabelas'/><category term='numeros'/><category term='monitor'/><category term='listar'/><category term='Delphi'/><category term='Diretorio'/><category term='Componentes'/><category term='windows'/><category term='code'/><category term='numbers'/><category term='progress bar'/><category term='fast tips'/><category term='Pascal'/><category term='OFF-TOPIC'/><category term='zip'/><category term='datas'/><category term='Excel'/><title type='text'># Tips of Delphi #</title><subtitle type='html'>Dicas e exemplos de delphi. Base de funções úteis em delphi. Source codes and samples for delphi</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default?start-index=101&amp;max-results=100'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>454</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-2056609841612569672</id><published>2009-02-28T08:33:00.001-08:00</published><updated>2009-02-28T08:33:00.917-08:00</updated><title type='text'>Delphi HTML Preview</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;HI,&lt;br /&gt;&lt;br /&gt;Acabei de preparar um exemplo com uma &lt;a href="http://delphi.about.com/cs/adptips2004/a/bltip0104_4.htm"&gt;rotina&lt;/a&gt; que achei para visualizar um código HTML no componente WebBrowser sem precisar criar um arquivo.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_6HEffI4v80I/SaiUMrO1gZI/AAAAAAAAAGA/1E3lKicVsSI/s1600-h/delphi_html_preview.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 353px;" src="http://2.bp.blogspot.com/_6HEffI4v80I/SaiUMrO1gZI/AAAAAAAAAGA/1E3lKicVsSI/s400/delphi_html_preview.jpg" alt="" id="BLOGGER_PHOTO_ID_5307655106340422034" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Antes quando precisa exibir algo em HTML no programa, eu criava um arquivo .html com o código e caregava no componente. Mas recentemente precisei exibir um código HTML armazenado no banco de dados. Poderia ter feito no esquema que já sabia, mas decidi fazer algo mais decente, hehehe. Pegar o código e carregar diretamente no componente TWebBrowser.&lt;br /&gt;&lt;br /&gt;Download do exemplo &lt;a href="http://www.4shared.com/file/89894966/c94e9264/HtmlPreview.html"&gt;AQUI&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Até Mais.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://dprogrammer.blogspot.com/2009/02/delphi-html-preview.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-2056609841612569672?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/2056609841612569672/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=2056609841612569672' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2056609841612569672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2056609841612569672'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2009/02/delphi-html-preview.html' title='Delphi HTML Preview'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_6HEffI4v80I/SaiUMrO1gZI/AAAAAAAAAGA/1E3lKicVsSI/s72-c/delphi_html_preview.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1020924550290277526</id><published>2008-08-18T14:21:00.002-07:00</published><updated>2008-08-18T14:28:55.905-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>SmartInspect 3.0 Session Improvements</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;p&gt;&lt;img style="margin: 0px 0px 0px 15px" height="129" alt="sessions" src="http://blog.gurock.com/wp-content/uploads/2008/07/sessions.png" width="217" align="right" border="0" /&gt;This is the first part of a series showing some of the major new features and improvements of the upcoming &lt;a href="http://www.gurock.com/products/smartinspect/"&gt;SmartInspect&lt;/a&gt; 3.0 release. Yep, that&amp;#8217;s right; SmartInspect 3.0 is coming very soon now! As with the previous major release, it will contain quite a few new features that are directly based on customer feedback. We are really grateful for all the feature requests, bug reports and ideas for improvements that we received over the years. Without them, SmartInspect wouldn&amp;#8217;t be near as good or complete as it is today.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The first improvement I would like to write about is actually not a new feature. It&amp;#8217;s more like a set of several enhancements to the existing SmartInspect session concept. Back then in 2003 and 2004 when we first planned which features SmartInspect 1.0 should shave, we quickly agreed that we should provide users with a way to group and categorize related log messages. We have chosen the session concept because it&amp;#8217;s a) easy to understand and b) maps very well to existing related concepts such as user sessions in web applications.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In retrospect we are happy that we went with sessions for two reasons. First, sessions turned out to be one the key features of SmartInspect. Although sessions are a somewhat advanced feature that new users often ignore (which they easily can, because they don&amp;#8217;t have to care about it when they are learning SmartInspect). But once they are getting used to it and are using SmartInspect in more complex applications, they quickly see the advantages of sessions over other logging concepts.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The second point is a bit more technical. Since the entire library design relies on sessions, it would have been difficult to integrate sessions at a later point without breaking existing customer code. And because you should be very careful to not break existing customer code with a new version of a dev tool, we are glad that we got the basic library design mostly right in the first attempt.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Although we got most of the design right, there were a few missing features. The first new feature in SmartInspect 3.0 regarding sessions is the new log level support. This is probably the most often requested session related feature that we incorporated into the new version. Log level support for sessions means that you are now able to configure log levels on a per-session basis. This allows you, for example, to only log errors and warnings in your application, except for your database module where you want SmartInspect to generate a very detailed log (e.g., for debugging or auditing purposes).&lt;/p&gt;&lt;br /&gt;&lt;p style="text-align: center"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="213" alt="session-config" src="http://blog.gurock.com/wp-content/uploads/2008/07/session-config.png" width="327" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Another improvement in SmartInspect 3.0 is the new ability to configure sessions via SmartInspect configuration files. This allows you to enable, disable or configure specific sessions without recompiling your application. This can come in very handy if you have to dynamically enable or disable logging for certain application modules on production systems or at customer sites.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The last new session enhancement is the support for so-called session defaults. Session defaults let you specify default values for session attributes like the Active status or the background color of log entries in the Console. This is very useful in situations where you are working with many sessions and need a way to change the base settings of all instances.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We will introduce other new features and improvements of SmartInspect 3.0 in the next few days here on our blog.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&lt;tr&gt;&lt;td valign=top&gt;&lt;b&gt;Keyword&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Delphi&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://blog.gurock.com/postings/smartinspect-30-session-improvements/320/" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1020924550290277526?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1020924550290277526/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1020924550290277526' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1020924550290277526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1020924550290277526'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/smartinspect-30-session-improvements.html' title='SmartInspect 3.0 Session Improvements'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1899131108046903869</id><published>2008-08-18T14:21:00.001-07:00</published><updated>2008-08-18T14:21:06.868-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Anonymous Methods - When Should They Be Used?</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;p&gt;Anonymous methods are generating a lot of buzz in the Delphi community right now, being one of the bigger changes heading our way in the forthcoming Tiburon (Delphi 2009), along with Unicode and Generics.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Unlike Unicode and Generics however, the usefulness of anonymous methods is not nearly as clear.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span id="more-48"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;On Joel On Software&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://www.joelonsoftware.com/items/2006/08/01.html"&gt;Joel On Software&lt;/a&gt; has been invoked as an authority.  Unfortunately, as Joel himself has previously admitted, he does not actually use Delphi, and a great deal of the usefulness he sees in anonymous methods seems to stem from this fact, in that what he describes as the principal benefits of anonymous methods has always been achievable in Delphi.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To paraphrase his material on this point:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;    procedure Cook(const aIngredient1, aIngredient2: String;&lt;br /&gt;                   const aCookingMethod: TCookingMethod);&lt;br /&gt;    begin&lt;br /&gt;      Alert('get the ' + aIngredient);&lt;br /&gt;      aCookingMethod(aIngredient1);&lt;br /&gt;      aCookingMethod(aIngredient2);&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;Cook( 'lobster', 'water',   PutInPot );&lt;br /&gt;Cook( 'chicken', 'coconut', BoomBoom );&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Joel asks: &lt;/strong&gt;&lt;em&gt; Can your language do this?&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If the language is Delphi, yes.  We don&amp;#8217;t need anonymous methods for this.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;But that is not the only use for anonymous methods espoused by Joel.  He goes on to talk briefly about threading, before seeming to me to go off at something of a tangent to talk about &lt;a href="http://en.wikipedia.org/wiki/MapReduce"&gt;MapReduce&lt;/a&gt;, where the applicability of anonymous methods is a little hard to fathom (in the context of languages that &amp;#8220;&lt;em&gt;can&lt;/em&gt; do this&amp;#8221;) and I&amp;#8217;m certain that the &lt;a href="http://labs.google.com/papers/mapreduce.html"&gt;actual Google MapReduce implementation&lt;/a&gt; is a great deal more complex than Joel&amp;#8217;s summary, but I&amp;#8217;m not so sure that anonymous methods were critical to it&amp;#8217;s success, rather than just happening to be a part of it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;One wonders if they would have featured at all if Google had used Delphi.  &lt;img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt; &lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Anonymous Methods and Threading&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;In a different blog, &lt;a href="http://delphi.fosdal.com/2008/08/anonymous-methods-when-to-use-them.html"&gt;Lars Fosdal&lt;/a&gt; also mentions threading.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Coming at the subject with the Delphi perspective that Joel does not have, Lars aligns the benefits of anonymous methods against the failings of TThread.  Not unreasonable, given that TThread is the &amp;#8220;out of the box&amp;#8221; approach to threading in Delphi and it undeniably has a number of shortcomings.  But TThread is not the only game in town for Delphi developers.  I myself have needed a more lightweight approach to threading in the past.  So I made one.  I called it TMotile (&lt;a href="http://en.wikipedia.org/wiki/Commonwealth_Saga"&gt;a work by Peter F Hamilton&lt;/a&gt; brought the term &lt;a href="http://www.answers.com/topic/motility"&gt;motile&lt;/a&gt; to my attention, and the fit was obvious in my mind).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;My TMotile class can be used in two ways.  First to execute some procedure in a fire-and-forget background thread:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;    procedure SomeProcedure;&lt;br /&gt;    begin&lt;br /&gt;      // ...&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;TMotile.Execute( SomeProcedure );&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Or secondly in a way perhaps more familiar to those already used to TThread:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;    TMyMotile = class( TMotile )&lt;br /&gt;    protected&lt;br /&gt;      procedure Execute; override;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;    procedure TMyMotile.Execute;&lt;br /&gt;    begin&lt;br /&gt;      // ...&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;TMyMotile.Create;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;With anonymous methods that fire-and-forget usage could be made simpler:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;TMotile.Execute( procedure&lt;br /&gt;                 begin&lt;br /&gt;                   // ...&lt;br /&gt;                 end; );&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Of course, that &amp;#8220;simpler&amp;#8221; observation is, I think, debatable.  If it is &amp;#8220;simpler&amp;#8221; at all, then actually it isn&amp;#8217;t by very much, and arguably it introduces an unacceptable level of noise into the code.  This doesn&amp;#8217;t appear to be the case when viewed in isolation, but in the context of a longer sequence of code where only one statement is invoked to create a thread to handle background execution of some other code, seeing the body of that background code &lt;span style="text-decoration: underline;"&gt;is&lt;/span&gt; &amp;#8220;noise&amp;#8221;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;There is an even greater advantage when the body of the anonymous procedure captures state from the context in which it is created.  In those situations then this usage simply cannot work without anonymous methods, requiring a subclass of TMotile (or TThread) in order to explicitly capture that state from the context and make it available to the threaded procedure:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;    TMyMotile = class(TMotile)&lt;br /&gt;    private&lt;br /&gt;      fContextVar: ...;&lt;br /&gt;    protected&lt;br /&gt;      procedure Execute;&lt;br /&gt;    public&lt;br /&gt;      property ContextVar: .. write fContextVar;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;    procedure TMyMotile.Execute;&lt;br /&gt;    begin&lt;br /&gt;      ..  fContextVar  ..;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;mm := TMyMotile.Create;&lt;br /&gt;mm.ContextVar1 := SomeContextValue;&lt;br /&gt;mm.Execute;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Which can be replaced with:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;mm := TMotile.Execute( procedure;&lt;br /&gt;                       begin&lt;br /&gt;                         .. SomeContextValue ..;&lt;br /&gt;                       end; );&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Which is undeniably neat. Both in the sense that is it clever and a great deal more concise.  But I am still not convinced that this convenience is worth getting all that excited about - It has not enabled anything that was previously impossible, nor even especially difficult either to implement or to understand, and that noise is still there.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Indeed, anonymous methods do not even eradicate the infrastructure that is required to support it, they just hide it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If it&amp;#8217;s hidden, I can&amp;#8217;t fix it or improve it or adapt it to better suit a specific use.  If it&amp;#8217;s hidden I may never the less need to take it into account to understand what unfamiliar code does and how - hiding it just makes it that much harder to identify and requires me to bring that knowledge of the hidden details with me.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;For one thing of course, if this threaded code should later evolve and require some mechanism to pass information &lt;span style="text-decoration: underline;"&gt;back&lt;/span&gt; to the context that originated it - or some other context - having that threaded code represented by an identified and referencable object provides exactly the mechanism we need.  Without any such visible device, yet more wizardry is needed to provide that mechanism without resorting to simply exposing and extending the pretty basic infrastructure.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;With Great Anonymity Comes Great Responsibility&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;Having anonymous methods in the language does not compel us to use them, and unlike Generics or even Unicode to an extent, using them in your code will not compel &lt;span style="text-decoration: underline;"&gt;others&lt;/span&gt; to use them either, if they do not wish to.  So what&amp;#8217;s the harm?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Well, of course, the same could be said of &lt;strong&gt;with&lt;/strong&gt; - and indeed, the similarity is quite striking.  Both provide a means of hiding an implementation detail and avoiding the onerous task of encumbering that detail with an identity.  &lt;strong&gt;with&lt;/strong&gt; is, somewhat famously, regarded with disdain for the way that this hiding of details introduces problems.  Not least when debugging (and the prospect of debugging anonymous methods is similarly intriguing, to say the least).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So if we all only use anonymous methods responsibly, we&amp;#8217;ll be fine.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Which call to mind Eddie Izzard&amp;#8217;s response to the NRA&amp;#8217;s assertion that &amp;#8220;Guns don&amp;#8217;t kill people, people kill people&amp;#8221; &amp;#8230;..&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;em&gt;&amp;#8230;and monkeys do too (if they have a gun)&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Speaking of Eddie Izzard, if you haven&amp;#8217;t heard his Death Star Canteen sketch, then allow YouTube to introduce you to in &lt;a href="http://www.youtube.com/watch?v=Sv5iEK-IEzw"&gt;glorious LegoVision&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Any excuse.  &lt;img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt; &lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Other Parallels&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;No not a further examination of threading, but the use of one thing to draw a parallel, or a comparison, with something else.  In this case, let us imagine we are putting together a web site, and on some of our pages we have some content that isn&amp;#8217;t directly relevant to the page it is on.  Content that certainly doesn&amp;#8217;t have to be read at the time, but which perhaps isn&amp;#8217;t likely ever to be read alone.  It&amp;#8217;s not going to appear in our site navigation or even the table of contents necessarily.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It&amp;#8217;s content, but it doesn&amp;#8217;t have an absolute identity outside of some other context in which it is referenced.  On the printed page, it would be a footnote or an entry in the bibliography.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;These things to a written language are, essentially, what anonymous methods are to our code.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So why do we have footnotes?  Why do we use links in web pages, instead of just quoting, verbatim and inline, the content we would like the reader to perhaps come back to later, and just require them to skip over it in the meantime.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The question is of course rhetorical.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This is essentially what anonymous methods will bring to your source code.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I may never write code this way myself, but I am not looking forward to the first time I have to read someone else&amp;#8217;s code written that way.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;So, When Should They Be Used?&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;The title of this post posed a question, and it&amp;#8217;s only fair that I answer it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;As things stand, I would have to say that anonymous methods should be used &lt;em&gt;only&lt;/em&gt; when you absolutely have to, and so far I have not yet seen an example where anonymous methods are the only way to achieve anything.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I may yet change my mind, and more examples have been promised by CodeGear.  But CodeGear didn&amp;#8217;t invent these things, and they aren&amp;#8217;t new, as plenty of people point out - compelling and obvious examples should already be readily available, albeit not in Delphi.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Where are they?&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&lt;tr&gt;&lt;td valign=top&gt;&lt;b&gt;Keyword&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Delphi&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://www.deltics.co.nz/blog/?p=48" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1899131108046903869?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1899131108046903869/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1899131108046903869' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1899131108046903869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1899131108046903869'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/anonymous-methods-when-should-they-be.html' title='Anonymous Methods - When Should They Be Used?'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-4290479600263068067</id><published>2008-08-17T06:56:00.001-07:00</published><updated>2008-08-17T06:56:31.421-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Resizing a Non-Resizable Form</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;p&gt;One control that I have not seen in the line-up of new controls in the VCL for Tiburón is a size grip.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Most people may not even realise that this control exists, even though it is part of Windows itself and is really quite useful.  Fortunately, implementing it ourselves is truly trivial.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span id="more-193"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;What is a Size Grip?&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;A size grip is the small triangular control, usually in the lower right hand corner of a window that provides an indication that the window is resizable and is also a grab-point that the user can use to resize the window itself.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;You will see one if you place a status-bar control on a resizable form:&lt;/p&gt;&lt;br /&gt;&lt;div class="wp-caption alignnone" style="width: 322px"&gt;&lt;a href="http://www.deltics.co.nz/picture_library/sizegrip.gif"&gt;&lt;img title="Example of a Size Grip" src="http://www.deltics.co.nz/picture_library/sizegrip.gif" alt="Example of a Size Grip" width="312" height="140" /&gt;&lt;/a&gt;&lt;p class="wp-caption-text"&gt;Example of a Size Grip&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;If the form is not resizable, the grip does not appear in the status bar.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;But what if I have a form that I want to be sizable, but which does not have a status bar, doesn&amp;#8217;t &lt;span style="text-decoration: underline;"&gt;need&lt;/span&gt; a status bar, and which perhaps in all other respects doesn&amp;#8217;t even look resizable?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Imagine, for example, that I have &lt;a href="http://chrisbensen.blogspot.com/2008/07/tiburn-sneak-peek-project-options.html" target="_blank"&gt;redesigned a dialog box so that it now needs to be resizable&lt;/a&gt;&amp;#8230;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If you look at the dialog box shown in that link, you will see that it is resizable but offers no immediately obvious visual cue that this is in fact the case.  It clearly doesn&amp;#8217;t need a status bar.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;What would be useful in such cases is a way to add a size grip without having to use a status bar.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And this is exactly what a size grip control does for us.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;The Implementation&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;As I mentioned, the implementation of such a control is trivial.  So trivial that the entire implementation is provided below.  No need for a download in this case.&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;interface&lt;br /&gt;&lt;br /&gt;  uses&lt;br /&gt;    Classes,&lt;br /&gt;    Controls;&lt;br /&gt;&lt;br /&gt;  type&lt;br /&gt;    TSizeGrip = class(TWinControl)&lt;br /&gt;    protected&lt;br /&gt;      procedure CreateParams(var Params: TCreateParams); override;&lt;br /&gt;      procedure CreateWnd; override;&lt;br /&gt;    public&lt;br /&gt;      constructor Create(aOwner: TComponent); override;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;  uses&lt;br /&gt;    Windows;&lt;br /&gt;&lt;br /&gt;{ TSizeGrip }&lt;br /&gt;&lt;br /&gt;  constructor TSizeGrip.Create(aOwner: TComponent);&lt;br /&gt;  begin&lt;br /&gt;    inherited;&lt;br /&gt;&lt;br /&gt;    ControlStyle := [csOpaque, csFixedWidth, csFixedHeight];&lt;br /&gt;&lt;br /&gt;    Anchors := [akRight, akBottom];&lt;br /&gt;    Cursor  := crSizeNWSE;&lt;br /&gt;    Height  := 11;&lt;br /&gt;    Width   := 11;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  procedure TSizeGrip.CreateParams(var Params: TCreateParams);&lt;br /&gt;  begin&lt;br /&gt;    inherited;&lt;br /&gt;    CreateSubClass(Params, 'SCROLLBAR');&lt;br /&gt;    Params.Style := Params.Style or WS_CLIPSIBLINGS or SBS_SIZEGRIP;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  procedure TSizeGrip.CreateWnd;&lt;br /&gt;  begin&lt;br /&gt;    inherited;&lt;br /&gt;    Left := Parent.ClientWidth - Width - 1;&lt;br /&gt;    Top  := Parent.ClientHeight - Height - 1;&lt;br /&gt;    SendToBack;&lt;br /&gt;  end;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;As you can see, a size grip is in fact a special form of the built in SCROLLBAR Windows control class.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This code should work in any Win32 version of Delphi.  In my case since I use Delphi 7 I use dotted unit names and have it implemented in &lt;strong&gt;Deltics.Controls.SizeGrip&lt;/strong&gt;.  In earlier Delphi versions you will need to use a unit name with no dots.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And yes, we should probably use system metrics to size the control.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The implementation has the control place itself in the lower right hand corner of it&amp;#8217;s parent, and stay there.  But how do we ensure that we only show the control if the form is resizable?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Well, actually, we don&amp;#8217;t need to worry about that.  Simply placing the control on a form &lt;span style="text-decoration: underline;"&gt;makes&lt;/span&gt; the form resizable (via the size grip) even if that form would normally not be resizable.  That is, if the user moves their mouse over the size grip it will change to the resizing cursor and they can resize the form by grabbing the control and dragging.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So the user can see that the dialog is resizable &lt;span style="text-decoration: underline;"&gt;and&lt;/span&gt; is provided with the means to resize the form, even if the form has no border at all, such as this one, with border style &lt;strong&gt;bsNone&lt;/strong&gt;:&lt;/p&gt;&lt;br /&gt;&lt;div class="wp-caption alignnone" style="width: 217px"&gt;&lt;a href="http://www.deltics.co.nz/picture_library/sizegrip2.gif"&gt;&lt;img title="Resizable, Borderless Form" src="http://www.deltics.co.nz/picture_library/sizegrip2.gif" alt="Resizable, Borderless Form" width="207" height="111" /&gt;&lt;/a&gt;&lt;p class="wp-caption-text"&gt;Resizable, Borderless Form&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Getting this is as easy as adding:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;    with TSizeGrip.Create(self) do&lt;br /&gt;      Parent := self;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;To a form &lt;em&gt;constructor&lt;/em&gt; or &lt;em&gt;OnCreate&lt;/em&gt; event.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;In fact, in my applications I can simply write in any form &lt;em&gt;constructor&lt;/em&gt; or &lt;em&gt;OnCreate&lt;/em&gt; event:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;    HasSizeGrip := TRUE;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;em&gt;Any&lt;/em&gt;&lt;/span&gt; form.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;How is that possible?  &lt;strong&gt;HasSizeGrip&lt;/strong&gt; is not a property of &lt;strong&gt;TForm&lt;/strong&gt;, so where does it come from?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I&amp;#8217;m saving that for next time.  &lt;img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /&gt;&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&lt;tr&gt;&lt;td valign=top&gt;&lt;b&gt;Keyword&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Delphi&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://www.deltics.co.nz/blog/?p=193" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-4290479600263068067?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/4290479600263068067/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=4290479600263068067' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4290479600263068067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4290479600263068067'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/resizing-non-resizable-form.html' title='Resizing a Non-Resizable Form'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1141584826307413089</id><published>2008-08-16T16:54:00.001-07:00</published><updated>2008-08-16T16:54:30.827-07:00</updated><title type='text'>MapQuest and Delphi</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;A few weeks ago I started down the path of discovering how to GeoCode addresses for Delphi. This is related to a project we had where we wanted to show a map of a given point and then show facilities located near it on a map. I had originally started working with maps.live.com (which is a MS site). They have a decent little interface for JS that seemed to work for what I wanted AND I didn't have to store the annoying little GeoCoding addresses anywhere. This works great if all you want is a single address. For instance, the code below works for single addresses:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Address Lookup &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;meta&lt;/span&gt; &lt;span class="attr"&gt;http-equiv&lt;/span&gt;&lt;span class="kwrd"&gt;="Content-Type"&lt;/span&gt; &lt;span class="attr"&gt;content&lt;/span&gt;&lt;span class="kwrd"&gt;="text/html; charset=utf-8"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &amp;lt;script type=&lt;span class="str"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;var&lt;/span&gt; map = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br /&gt;      &lt;span class="kwrd"&gt;var&lt;/span&gt; findPlaceResults = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br /&gt;      &lt;span class="kwrd"&gt;function&lt;/span&gt; GetMap()&lt;br /&gt;      {&lt;br /&gt;         map = &lt;span class="kwrd"&gt;new&lt;/span&gt; VEMap(&lt;span class="str"&gt;'myMap:newmap'&lt;/span&gt;);&lt;br /&gt;         map.LoadMap();&lt;br /&gt;         map.Find(&lt;span class="kwrd"&gt;null&lt;/span&gt;,&lt;span class="str"&gt;'100 Enterprise Way, Scotts Valley, CA 95066'&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;, GetCoordinates);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;     &lt;span class="kwrd"&gt;function&lt;/span&gt; GetCoordinates(layer, resultsArray, places, hasMore, veErrorMessage)&lt;br /&gt;     {&lt;br /&gt;        findPlaceResults = places[0].LatLong;&lt;br /&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; myShape = &lt;span class="kwrd"&gt;new&lt;/span&gt; VEShape(VEShapeType.Pushpin, findPlaceResults);&lt;br /&gt;        myShape.SetTitle(&lt;span class="str"&gt;'CodeGear'&lt;/span&gt;);&lt;br /&gt;        myShape.SetDescription(&lt;span class="str"&gt;'100 Enterprise Way&amp;lt;br&amp;gt;Scotts Valley, CA 95066&amp;lt;br&amp;gt;'&lt;/span&gt;+findPlaceResults.toString());&lt;br /&gt;        map.AddShape(myShape);&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt; &lt;span class="attr"&gt;onload&lt;/span&gt;&lt;span class="kwrd"&gt;="GetMap();"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;='myMap:newmap'&lt;/span&gt; &lt;span class="attr"&gt;style&lt;/span&gt;&lt;span class="kwrd"&gt;="position:relative; width:800px; height:600px;"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The problem showed up when I went to add the facilities to the map. Thinking it would all work the same way, I added the same Map.Find code for each facility in the state of interest and voila. Except the voila was, "How come I only get one pushpin?" not "See how great this works!" It turns out that part of the answer is the MS VEMap object works asynchronously. I could live with that if the map moved around a little as it added pushpins... well, at the very least, I could just hide the map until it was done. &lt;br /&gt;&lt;br /&gt;Unfortunately, MS also made the calls non-reentrant. This is actually what they document the problem as. To me, the code IS non-reentrant in that it never calls itself. Apparently, our definitions of re-entrant differ significantly. To MS, non-reentrant means that you have to wait for the asynchronous call to complete before you can call it again. Of course, Javascript has little support for "waiting". I was able to create a work around using a do {} while (!completed); but it causes the browser to complain mightly, ties up a lot of CPU and is just generally ugly.&lt;br /&gt;&lt;br /&gt;Seeing that this wasn't going to work very well, I went back to the drawing board. If I actually could provide the Lat/Lng for each object, the problem would go away. It turns out that there are not very many services that want to let you do this for free using a desktop tool. If you are willing to do a web mashup you can get away with quite a bit, but the traditional languages are left out in the cold for the most part. &lt;br /&gt;&lt;br /&gt;This is where MapQuest comes in. They have a free service (you have to register, but that's it) that will let you have access to their mapping systems. Of course, they have no interface for Delphi, but they did publish their XML specifications so it's not too hard to write one. Keep in mind that you have to comply with the MapQuest TOS. The major one for me was that you can't use the Lat/Lng addresses with any other system than theirs. That means I can't use maps.live.com to produce my maps, I have to figure out how to use MapQuest. Considering my other choices was a complete web mashup rewrite or some commercial system that was going to cost a fortune, I think I'll live within those parameters.&lt;br /&gt;&lt;br /&gt;I've only implemented the single interface I needed so far (GeoCoding), but the other interfaces are equally easy. This code is virtually identical (in the HTTP POST) as my DHL code. I've reposted the whole thing here for those needing a complete unit but will likely factor it out for my personal use.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;1. This is how the classes are used. I assume you recognize that the txtXXX are just text box fields and the resolver form has a single control on it that is a list box (other than the Select / Cancel buttons).&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;uses&lt;/span&gt; mapquest_api, w_AddyResolver;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;procedure&lt;/span&gt; TForm1.btnGeoCodeClick(S&lt;span class="kwrd"&gt;end&lt;/span&gt;er: &lt;span class="kwrd"&gt;to&lt;/span&gt;bject);&lt;br /&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; geocode:TMapQuestGeoCoder;&lt;br /&gt;    index, ix:integer;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;geocode:=TMapQuestGeoCoder.Create;                                               &lt;span class="rem"&gt;//create the geocoder object&lt;/span&gt;&lt;br /&gt;geocode.Password:=&lt;span class="str"&gt;'YOUR PASS'&lt;/span&gt;;                                                   &lt;span class="rem"&gt;//assign the password and client id you got from mapquest&lt;/span&gt;&lt;br /&gt;geocode.ClientID:=&lt;span class="str"&gt;'YOUR ID'&lt;/span&gt;;                                                     &lt;span class="rem"&gt;//this will NOT work &lt;span class="kwrd"&gt;with&lt;/span&gt;out it!!!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;geocode.Address    := edtAddress.Text;                                           &lt;span class="rem"&gt;//assign the address info you want &lt;span class="kwrd"&gt;to&lt;/span&gt; code&lt;/span&gt;&lt;br /&gt;geocode.City       := edtCity.Text;&lt;br /&gt;geocode.State      := edtState.Text;&lt;br /&gt;geocode.PostalCode := edtPostalCode.Text;&lt;br /&gt;geocode.Country    := edtCountry.Text;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; geocode.getFromMapQuest(&lt;span class="kwrd"&gt;true&lt;/span&gt;) &lt;span class="kwrd"&gt;then&lt;/span&gt;                                            &lt;span class="rem"&gt;//this will s&lt;span class="kwrd"&gt;end&lt;/span&gt; the info &lt;span class="kwrd"&gt;to&lt;/span&gt; mapquest and return the results&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;if&lt;/span&gt; geocode.ReturnedAddresses.Count&amp;gt;0 &lt;span class="kwrd"&gt;then&lt;/span&gt;                                     &lt;span class="rem"&gt;//if we got a response&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; geoCode.ReturnedAddresses.Count=1 &lt;span class="kwrd"&gt;then&lt;/span&gt;                                  &lt;span class="rem"&gt;//if there's only 1, no need &lt;span class="kwrd"&gt;to&lt;/span&gt; show a resolver&lt;/span&gt;&lt;br /&gt;         index:=0&lt;br /&gt;      &lt;span class="kwrd"&gt;else&lt;/span&gt;                                                                       &lt;span class="rem"&gt;//we got multiple responses, the user will have &lt;span class="kwrd"&gt;to&lt;/span&gt; resolve which addy is correct&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;         index:=-1;                                                              &lt;span class="rem"&gt;//default &lt;span class="kwrd"&gt;to&lt;/span&gt; failure&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;for&lt;/span&gt; ix := 0 &lt;span class="kwrd"&gt;to&lt;/span&gt; geoCode.ReturnedAddresses.Count-1 &lt;span class="kwrd"&gt;do&lt;/span&gt;                     &lt;span class="rem"&gt;//for each addy&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;with&lt;/span&gt; geoCode.ReturnedAddresses.Address[ix] &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;br /&gt;               addyResolver.lb.Items.Add(Address+&lt;span class="str"&gt;' '&lt;/span&gt;+City+&lt;span class="str"&gt;' '&lt;/span&gt;+State+&lt;span class="str"&gt;' '&lt;/span&gt;+Country); &lt;span class="rem"&gt;//load the listbox&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;if&lt;/span&gt; addyResolver.ShowModal=mrOk &lt;span class="kwrd"&gt;then&lt;/span&gt;                                     &lt;span class="rem"&gt;//prompt the user, if they select one, mrOk will be set&lt;/span&gt;&lt;br /&gt;            index:=addyResolver.lb.ItemIndex;                                    &lt;span class="rem"&gt;//get the addy&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;if&lt;/span&gt; index&amp;lt;0 &lt;span class="kwrd"&gt;then&lt;/span&gt; exit;                                                   &lt;span class="rem"&gt;//if the user failed &lt;span class="kwrd"&gt;to&lt;/span&gt; pick, get out&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;      lblLat.Caption:=geoCode.ReturnedAddresses.Address[index].Lat;              &lt;span class="rem"&gt;//display the lat and long values&lt;/span&gt;&lt;br /&gt;      lblLong.Caption:=geoCode.ReturnedAddresses.Address[index].Long;&lt;br /&gt;      &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2. And this is the actual unit that does the work. BTW, the XML parser I'm using is OpenXML, a freely available, full source implementation that works for Delphi and Kylix. &lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;unit mapquest_api;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;interface&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;uses&lt;/span&gt; classes, contnrs;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;type&lt;/span&gt;&lt;br /&gt;   &lt;span class="rem"&gt;//base class, you must derive desc&lt;span class="kwrd"&gt;end&lt;/span&gt;ants &lt;span class="kwrd"&gt;to&lt;/span&gt; make use of this class&lt;/span&gt;&lt;br /&gt;   &lt;span class="rem"&gt;//in order &lt;span class="kwrd"&gt;to&lt;/span&gt; successfully communicate &lt;span class="kwrd"&gt;with&lt;/span&gt; mapquest, you must attach YOUR ClientID, Password and APIKey&lt;/span&gt;&lt;br /&gt;   &lt;span class="rem"&gt;//you can register for free at mapquest.com&lt;/span&gt;&lt;br /&gt;   TMapQuestAPI = &lt;span class="kwrd"&gt;class&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;private&lt;/span&gt;&lt;br /&gt;         fClientID : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;         fPassword : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;         fAPIKey   : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;         fURL      : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;      &lt;span class="kwrd"&gt;protected&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;function&lt;/span&gt; getXML:&lt;span class="kwrd"&gt;string&lt;/span&gt;; &lt;span class="kwrd"&gt;virtual&lt;/span&gt;; &lt;span class="kwrd"&gt;abstract&lt;/span&gt;;&lt;br /&gt;         &lt;span class="kwrd"&gt;procedure&lt;/span&gt; parseResponse(response:TStringList); &lt;span class="kwrd"&gt;virtual&lt;/span&gt;; &lt;span class="kwrd"&gt;abstract&lt;/span&gt;;&lt;br /&gt;      &lt;span class="kwrd"&gt;public&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;constructor&lt;/span&gt; Create;&lt;br /&gt;         &lt;span class="kwrd"&gt;function&lt;/span&gt; getFromMapQuest(enableLogging:boolean):boolean;&lt;br /&gt;&lt;br /&gt;         property ClientID : &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;read&lt;/span&gt; fClientID &lt;span class="kwrd"&gt;write&lt;/span&gt; fClientID;&lt;br /&gt;         property Password : &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;read&lt;/span&gt; fPassword &lt;span class="kwrd"&gt;write&lt;/span&gt; fPassword;&lt;br /&gt;         property APIKey   : &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;read&lt;/span&gt; fAPIKey   &lt;span class="kwrd"&gt;write&lt;/span&gt; fAPIKey;&lt;br /&gt;         property URL      : &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;read&lt;/span&gt; fURL;&lt;br /&gt;      &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   TReturnedAddyList=&lt;span class="kwrd"&gt;class&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class="rem"&gt;//this desc&lt;span class="kwrd"&gt;end&lt;/span&gt;ant will implement the GeoCoder &lt;span class="kwrd"&gt;function&lt;/span&gt;ality from mapquest&lt;/span&gt;&lt;br /&gt;   &lt;span class="rem"&gt;//you must comply &lt;span class="kwrd"&gt;with&lt;/span&gt; mapquests terms of service, check mapquest.com &lt;span class="kwrd"&gt;to&lt;/span&gt; make sure&lt;/span&gt;&lt;br /&gt;   &lt;span class="rem"&gt;//that works for you&lt;/span&gt;&lt;br /&gt;   TMapQuestGeoCoder = &lt;span class="kwrd"&gt;class&lt;/span&gt;(TMapQuestAPI)&lt;br /&gt;      &lt;span class="kwrd"&gt;private&lt;/span&gt;&lt;br /&gt;         fAddress   : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;         fState     : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;         fCity      : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;         fCountry   : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;         fPostalCode: &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;         fCounty    : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;         fReturnedAddresses : TReturnedAddyList;&lt;br /&gt;      &lt;span class="kwrd"&gt;protected&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;function&lt;/span&gt; getXML:&lt;span class="kwrd"&gt;string&lt;/span&gt;; &lt;span class="kwrd"&gt;override&lt;/span&gt;;&lt;br /&gt;         &lt;span class="kwrd"&gt;procedure&lt;/span&gt; parseResponse(response:TStringList); &lt;span class="kwrd"&gt;override&lt;/span&gt;;&lt;br /&gt;         &lt;span class="kwrd"&gt;procedure&lt;/span&gt; ClearReturnedAddys;&lt;br /&gt;      &lt;span class="kwrd"&gt;public&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;constructor&lt;/span&gt; Create;&lt;br /&gt;         destruc&lt;span class="kwrd"&gt;to&lt;/span&gt;r Done;&lt;br /&gt;&lt;br /&gt;         property Address:&lt;span class="kwrd"&gt;string&lt;/span&gt;    &lt;span class="kwrd"&gt;read&lt;/span&gt; fAddress    &lt;span class="kwrd"&gt;write&lt;/span&gt; fAddress;&lt;br /&gt;         property City:&lt;span class="kwrd"&gt;string&lt;/span&gt;       &lt;span class="kwrd"&gt;read&lt;/span&gt; fCity       &lt;span class="kwrd"&gt;write&lt;/span&gt; fCity;&lt;br /&gt;         property State:&lt;span class="kwrd"&gt;string&lt;/span&gt;      &lt;span class="kwrd"&gt;read&lt;/span&gt; fState      &lt;span class="kwrd"&gt;write&lt;/span&gt; fState;&lt;br /&gt;         property Country:&lt;span class="kwrd"&gt;string&lt;/span&gt;    &lt;span class="kwrd"&gt;read&lt;/span&gt; fCountry    &lt;span class="kwrd"&gt;write&lt;/span&gt; fCountry;&lt;br /&gt;         property PostalCode:&lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;read&lt;/span&gt; fPostalCode &lt;span class="kwrd"&gt;write&lt;/span&gt; fPostalCode;&lt;br /&gt;         property County:&lt;span class="kwrd"&gt;string&lt;/span&gt;     &lt;span class="kwrd"&gt;read&lt;/span&gt; fCounty     &lt;span class="kwrd"&gt;write&lt;/span&gt; fCounty;&lt;br /&gt;         property ReturnedAddresses:TReturnedAddyList &lt;span class="kwrd"&gt;read&lt;/span&gt; fReturnedAddresses;&lt;br /&gt;      &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class="rem"&gt;//container class for a returned address&lt;/span&gt;&lt;br /&gt;   TReturnedAddy = &lt;span class="kwrd"&gt;class&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;public&lt;/span&gt;&lt;br /&gt;         Address,&lt;br /&gt;         City,&lt;br /&gt;         State,&lt;br /&gt;         PostalCode,&lt;br /&gt;         Country,&lt;br /&gt;         County,&lt;br /&gt;         Lat,&lt;br /&gt;         Long      : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;constructor&lt;/span&gt; Create(aAddress, aCity, aState, aPostalCode, aCountry, aCounty, aLat, aLong:&lt;span class="kwrd"&gt;string&lt;/span&gt;);&lt;br /&gt;      &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class="rem"&gt;//you can get back MULTIPLE addresses if you s&lt;span class="kwrd"&gt;end&lt;/span&gt; in something that is generic enough&lt;/span&gt;&lt;br /&gt;   &lt;span class="rem"&gt;//in that case, the COUNT will be &amp;gt; 1. Make sure you implement a resolver screen &lt;span class="kwrd"&gt;to&lt;/span&gt; handle this&lt;/span&gt;&lt;br /&gt;   TReturnedAddyList = &lt;span class="kwrd"&gt;class&lt;/span&gt;(TList)&lt;br /&gt;      &lt;span class="kwrd"&gt;protected&lt;/span&gt;&lt;br /&gt;         property Items;&lt;br /&gt;         property List;&lt;br /&gt;      &lt;span class="kwrd"&gt;public&lt;/span&gt;&lt;br /&gt;         &lt;span class="kwrd"&gt;function&lt;/span&gt; getAddy(index:integer):TReturnedAddy;&lt;br /&gt;         property Address[Index:Integer]:TReturnedAddy &lt;span class="kwrd"&gt;read&lt;/span&gt; getAddy;&lt;br /&gt;      &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;implementation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;uses&lt;/span&gt; sysutils, dialogs, IdHttp, IdSSLOpenSSL, IdResourceStringsCore, IdLogFile, xdom_3_2;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;const&lt;/span&gt;&lt;br /&gt;   CR = #13;&lt;br /&gt;   LF = #10;&lt;br /&gt;   EOL = CR+LF;&lt;br /&gt;   xmlEOL = EOL;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;type&lt;/span&gt;&lt;br /&gt;  &lt;span class="rem"&gt;// this is a desc&lt;span class="kwrd"&gt;end&lt;/span&gt;ant of TidLogFile, it will create a plain text file &lt;span class="kwrd"&gt;with&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="rem"&gt;// information about the transfer session&lt;/span&gt;&lt;br /&gt;  TlogFile = &lt;span class="kwrd"&gt;class&lt;/span&gt;(TidLogFile)&lt;br /&gt;  &lt;span class="kwrd"&gt;protected&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;procedure&lt;/span&gt; LogReceivedData(&lt;span class="kwrd"&gt;const&lt;/span&gt; AText, AData: &lt;span class="kwrd"&gt;string&lt;/span&gt;); &lt;span class="kwrd"&gt;override&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kwrd"&gt;procedure&lt;/span&gt; LogSentData(&lt;span class="kwrd"&gt;const&lt;/span&gt; AText, AData: &lt;span class="kwrd"&gt;string&lt;/span&gt;); &lt;span class="kwrd"&gt;override&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kwrd"&gt;procedure&lt;/span&gt; LogStatus(&lt;span class="kwrd"&gt;const&lt;/span&gt; AText: &lt;span class="kwrd"&gt;string&lt;/span&gt;); &lt;span class="kwrd"&gt;override&lt;/span&gt;;&lt;br /&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;procedure&lt;/span&gt; Log&lt;span class="kwrd"&gt;write&lt;/span&gt;String(&lt;span class="kwrd"&gt;const&lt;/span&gt; AText: &lt;span class="kwrd"&gt;string&lt;/span&gt;); &lt;span class="kwrd"&gt;override&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; &lt;span class="kwrd"&gt;function&lt;/span&gt; buildLogLine(data, prefix: &lt;span class="kwrd"&gt;string&lt;/span&gt;) : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;  &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// this ensures the output of error and debug logs are in the same format, regardless of source&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; &lt;span class="kwrd"&gt;function&lt;/span&gt; TlogFile.buildLogLine(data, prefix: &lt;span class="kwrd"&gt;string&lt;/span&gt;) : &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  data := StringReplace(data, EOL, RSLogEOL, [rfReplaceAll]);&lt;br /&gt;  data := StringReplace(data, CR,  RSLogCR,  [rfReplaceAll]);&lt;br /&gt;  data := StringReplace(data, LF,  RSLogLF,  [rfReplaceAll]);&lt;br /&gt;&lt;br /&gt;  result := FormatDateTime(&lt;span class="str"&gt;'yy/mm/dd hh:nn:ss'&lt;/span&gt;, now) + &lt;span class="str"&gt;' '&lt;/span&gt;;&lt;br /&gt;  &lt;span class="kwrd"&gt;if&lt;/span&gt; (prefix &amp;lt;&amp;gt; &lt;span class="str"&gt;''&lt;/span&gt;) &lt;span class="kwrd"&gt;then&lt;/span&gt;&lt;br /&gt;    result := result + prefix + &lt;span class="str"&gt;' '&lt;/span&gt;;&lt;br /&gt;  result := result + data + EOL;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// ---------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;procedure&lt;/span&gt; TlogFile.LogReceivedData(&lt;span class="kwrd"&gt;const&lt;/span&gt; AText, AData: &lt;span class="kwrd"&gt;string&lt;/span&gt;);&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  &lt;span class="rem"&gt;// ignore AText as it contains the date/time&lt;/span&gt;&lt;br /&gt;  Log&lt;span class="kwrd"&gt;write&lt;/span&gt;String(buildLogLine(Adata, &lt;span class="str"&gt;'&amp;lt;&amp;lt;'&lt;/span&gt;));&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// ---------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;procedure&lt;/span&gt; TlogFile.LogSentData(&lt;span class="kwrd"&gt;const&lt;/span&gt; AText, AData: &lt;span class="kwrd"&gt;string&lt;/span&gt;);&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  &lt;span class="rem"&gt;// ignore AText as it contains the date/time&lt;/span&gt;&lt;br /&gt;  Log&lt;span class="kwrd"&gt;write&lt;/span&gt;String(buildLogLine(Adata, &lt;span class="str"&gt;'&amp;gt;&amp;gt;'&lt;/span&gt;));&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// ---------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;procedure&lt;/span&gt; TlogFile.LogStatus(&lt;span class="kwrd"&gt;const&lt;/span&gt; AText: &lt;span class="kwrd"&gt;string&lt;/span&gt;);&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  Log&lt;span class="kwrd"&gt;write&lt;/span&gt;String(buildLogLine(AText, &lt;span class="str"&gt;'**'&lt;/span&gt;));&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// ---------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;procedure&lt;/span&gt; TlogFile.Log&lt;span class="kwrd"&gt;write&lt;/span&gt;String(&lt;span class="kwrd"&gt;const&lt;/span&gt; AText: &lt;span class="kwrd"&gt;string&lt;/span&gt;);&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  &lt;span class="rem"&gt;// protected --&amp;gt; public&lt;/span&gt;&lt;br /&gt;  inherited;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// ---------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;{ TMapQuestAPI }&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;//create the class, default everything &lt;span class="kwrd"&gt;to&lt;/span&gt; blank&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;constructor&lt;/span&gt; TMapQuestAPI.Create;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;fURL:=&lt;span class="str"&gt;''&lt;/span&gt;;&lt;br /&gt;fClientID:=&lt;span class="str"&gt;''&lt;/span&gt;;&lt;br /&gt;fPassword:=&lt;span class="str"&gt;''&lt;/span&gt;;&lt;br /&gt;fAPIKey:=&lt;span class="str"&gt;''&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;// ---------------------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;//s&lt;span class="kwrd"&gt;end&lt;/span&gt; the http post &lt;span class="kwrd"&gt;to&lt;/span&gt; mapquest and return a stringlist &lt;span class="kwrd"&gt;with&lt;/span&gt; the results (or nil if error)&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; TMapQuestAPI.getFromMapQuest(enableLogging:boolean): boolean;&lt;br /&gt;&lt;span class="kwrd"&gt;const&lt;/span&gt; logFileName = &lt;span class="str"&gt;'http.log'&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt;&lt;br /&gt;  plainData : TStringList;&lt;br /&gt;  HTTP     : TidHTTP;&lt;br /&gt;  response : TStringList;&lt;br /&gt;  logFile  : TLogFile;&lt;br /&gt;&lt;br /&gt;  &lt;span class="rem"&gt;//as mentioned in my article on http post for DHL, indy converts CR/LF pairs &lt;span class="kwrd"&gt;to&lt;/span&gt; &amp;amp;.&lt;/span&gt;&lt;br /&gt;  &lt;span class="rem"&gt;//This ca&lt;span class="kwrd"&gt;uses&lt;/span&gt; a problem when s&lt;span class="kwrd"&gt;end&lt;/span&gt;ing xml data.&lt;/span&gt;&lt;br /&gt;  &lt;span class="rem"&gt;//This routine will remove CR/LF pairs and replace them &lt;span class="kwrd"&gt;with&lt;/span&gt; a space&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;procedure&lt;/span&gt; ConvertCRLF&lt;span class="kwrd"&gt;to&lt;/span&gt;Space;&lt;br /&gt;  &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; plainData.Count &amp;gt; 1 &lt;span class="kwrd"&gt;then&lt;/span&gt; &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;      &lt;span class="rem"&gt;// break trailing CR&amp;amp;LF&lt;/span&gt;&lt;br /&gt;      plainData.Text := StringReplace(Trim(plainData.Text), sLineBreak, &lt;span class="str"&gt;' '&lt;/span&gt;,[rfReplaceAll]);&lt;br /&gt;    &lt;span class="kwrd"&gt;end&lt;/span&gt; &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;      plainData.Text := Trim(plainData.Text);&lt;br /&gt;    &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;  &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  result:=&lt;span class="kwrd"&gt;false&lt;/span&gt;;                                                           &lt;span class="rem"&gt;//by default, we get failure response in error&lt;/span&gt;&lt;br /&gt;  plainData := TStringList.Create;                                         &lt;span class="rem"&gt;//init the container for xmiting the xml&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;     plainData.Text:=getXML;                                               &lt;span class="rem"&gt;//get the xml from the class and put it in the container&lt;/span&gt;&lt;br /&gt;     Http:=TidHTTP.Create(nil);                                            &lt;span class="rem"&gt;//create the http class&lt;/span&gt;&lt;br /&gt;     &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;        HTTP.&lt;span class="kwrd"&gt;read&lt;/span&gt;Timeout := 10000;                                         &lt;span class="rem"&gt;//setup the http timeouts and xmit &lt;span class="kwrd"&gt;type&lt;/span&gt;s&lt;/span&gt;&lt;br /&gt;        HTTP.ConnectTimeout := 10000;&lt;br /&gt;        HTTP.Request.Content&lt;span class="kwrd"&gt;type&lt;/span&gt; := &lt;span class="str"&gt;'text/xml'&lt;/span&gt;;&lt;br /&gt;        HTTP.HTTPOptions := [];&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; enableLogging &lt;span class="kwrd"&gt;then&lt;/span&gt;                                              &lt;span class="rem"&gt;//if we are going &lt;span class="kwrd"&gt;to&lt;/span&gt; log the events (useful if there's a problem)&lt;/span&gt;&lt;br /&gt;           &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;           logFile := TLogFile.Create(nil);                                &lt;span class="rem"&gt;//create the log file&lt;/span&gt;&lt;br /&gt;           logFile.FileName:=logFileName;                                  &lt;span class="rem"&gt;//set the default log file name - NOTE: you could get fancy &lt;span class="kwrd"&gt;with&lt;/span&gt; this, but I normally don't use it&lt;/span&gt;&lt;br /&gt;           logFile.Active:=&lt;span class="kwrd"&gt;true&lt;/span&gt;;                                           &lt;span class="rem"&gt;//activate the log file (creates the file and intializes everything)&lt;/span&gt;&lt;br /&gt;           HTTP.Intercept := logFile;                                      &lt;span class="rem"&gt;//set the logFile &lt;span class="kwrd"&gt;to&lt;/span&gt; the intercept of the HTTP &lt;span class="kwrd"&gt;to&lt;/span&gt; capture the events&lt;/span&gt;&lt;br /&gt;           &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;        response:=TStringList.Create;                                      &lt;span class="rem"&gt;//create the response container&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;           ConvertCRLF&lt;span class="kwrd"&gt;to&lt;/span&gt;Space;                                             &lt;span class="rem"&gt;//make sure you strip cr/lf pairs out or the xml will be malformed&lt;/span&gt;&lt;br /&gt;           response.Text := HTTP.Post(URL, plainData);                     &lt;span class="rem"&gt;//post the xml and receive the response xml&lt;/span&gt;&lt;br /&gt;           result:=&lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br /&gt;           parseResponse(response);&lt;br /&gt;        &lt;span class="kwrd"&gt;finally&lt;/span&gt;&lt;br /&gt;           response.Free;&lt;br /&gt;        &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;     &lt;span class="kwrd"&gt;finally&lt;/span&gt;&lt;br /&gt;        Http.free;                                                         &lt;span class="rem"&gt;//free the http class&lt;/span&gt;&lt;br /&gt;     &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;  &lt;span class="kwrd"&gt;finally&lt;/span&gt;&lt;br /&gt;     plainData.Free;                                                       &lt;span class="rem"&gt;//free the container class&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;{ TMapQuestGeoCoder }&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;procedure&lt;/span&gt; TMapQuestGeoCoder.ClearReturnedAddys;&lt;br /&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; ix:integer;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;for&lt;/span&gt; ix := 0 &lt;span class="kwrd"&gt;to&lt;/span&gt; fReturnedAddresses.Count-1 &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;br /&gt;   fReturnedAddresses.Address[ix].Free;&lt;br /&gt;fReturnedAddresses.Clear;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;constructor&lt;/span&gt; TMapQuestGeoCoder.Create;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;fURL:=&lt;span class="str"&gt;'http://geocode.free.mapquest.com/mq/mqserver.dll?e=5&amp;amp;'&lt;/span&gt;;            &lt;span class="rem"&gt;//this is the free server address. if you sign up for a different &lt;span class="kwrd"&gt;type&lt;/span&gt; of account, you'll want &lt;span class="kwrd"&gt;to&lt;/span&gt; set this &lt;span class="kwrd"&gt;to&lt;/span&gt; your account &lt;span class="kwrd"&gt;type&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;fReturnedAddresses:=TReturnedAddyList.Create;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;destruc&lt;span class="kwrd"&gt;to&lt;/span&gt;r TMapQuestGeoCoder.Done;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;ClearReturnedAddys;&lt;br /&gt;fReturnedAddresses.Free;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; TMapQuestGeoCoder.getXML: &lt;span class="kwrd"&gt;string&lt;/span&gt;;                                &lt;span class="rem"&gt;//returns the xml formated per the MapQuest API&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;const&lt;/span&gt; geocodeXML =&lt;br /&gt;   &lt;span class="str"&gt;'&amp;lt;?xml version="1.0" encoding="ISO-8859-1"?&amp;gt;'&lt;/span&gt;+&lt;br /&gt;   &lt;span class="str"&gt;'&amp;lt;Geocode version="1"&amp;gt;'&lt;/span&gt;+&lt;br /&gt;&lt;br /&gt;      &lt;span class="str"&gt;'&amp;lt;Address&amp;gt;'&lt;/span&gt;+&lt;br /&gt;        &lt;span class="str"&gt;'&amp;lt;AdminArea1&amp;gt;%s&amp;lt;/AdminArea1&amp;gt;'&lt;/span&gt;+&lt;br /&gt;        &lt;span class="str"&gt;'&amp;lt;AdminArea3&amp;gt;%s&amp;lt;/AdminArea3&amp;gt;'&lt;/span&gt;+&lt;br /&gt;        &lt;span class="str"&gt;'&amp;lt;AdminArea5&amp;gt;%s&amp;lt;/AdminArea5&amp;gt;'&lt;/span&gt;+&lt;br /&gt;        &lt;span class="str"&gt;'&amp;lt;PostalCode&amp;gt;%s&amp;lt;/PostalCode&amp;gt;'&lt;/span&gt;+&lt;br /&gt;        &lt;span class="str"&gt;'&amp;lt;Street&amp;gt;%s&amp;lt;/Street&amp;gt;'&lt;/span&gt;+&lt;br /&gt;      &lt;span class="str"&gt;'&amp;lt;/Address&amp;gt;'&lt;/span&gt;+&lt;br /&gt;&lt;br /&gt;      &lt;span class="str"&gt;'&amp;lt;GeocodeOptionsCollection Count="0"/&amp;gt;'&lt;/span&gt;+&lt;br /&gt;&lt;br /&gt;      &lt;span class="str"&gt;'&amp;lt;Au&lt;span class="kwrd"&gt;then&lt;/span&gt;tication Version="2"&amp;gt;'&lt;/span&gt;+&lt;br /&gt;        &lt;span class="str"&gt;'&amp;lt;Password&amp;gt;%s&amp;lt;/Password&amp;gt;'&lt;/span&gt;+&lt;br /&gt;        &lt;span class="str"&gt;'&amp;lt;ClientId&amp;gt;%s&amp;lt;/ClientId&amp;gt;'&lt;/span&gt;+&lt;br /&gt;      &lt;span class="str"&gt;'&amp;lt;/Au&lt;span class="kwrd"&gt;then&lt;/span&gt;tication&amp;gt;'&lt;/span&gt;+&lt;br /&gt;   &lt;span class="str"&gt;'&amp;lt;/Geocode&amp;gt;'&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;result := Format(geocodeXML, [Country,State,City,PostalCode,Address,Password,ClientID]);  &lt;span class="rem"&gt;//make the request xml for geocding an address&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;procedure&lt;/span&gt; TMapQuestGeoCoder.parseResponse(response: TStringList);&lt;br /&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt;&lt;br /&gt;    DOC:TXML&lt;span class="kwrd"&gt;to&lt;/span&gt;DomParser;&lt;br /&gt;    DOM:TDOMImplementation;&lt;br /&gt;    XML:TDOMDocument;&lt;br /&gt;    LocCollection:TDomNodeList;&lt;br /&gt;    Geo,&lt;br /&gt;    Node:TDomNode;&lt;br /&gt;&lt;br /&gt;    &lt;span class="rem"&gt;//you can't trust that the xml contains ALL element names so this wraps the testing conditions up&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;//&lt;span class="kwrd"&gt;to&lt;/span&gt; safely get the node values or a blank when not in the xml&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;function&lt;/span&gt; SafeGetNodeValue(node:TDomNode; name:&lt;span class="kwrd"&gt;string&lt;/span&gt;):&lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; DomElement:TDomElement;&lt;br /&gt;    &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;       result:=&lt;span class="str"&gt;''&lt;/span&gt;;&lt;br /&gt;       DomElement:=Node.GetFirstChildElement(name);&lt;br /&gt;       &lt;span class="kwrd"&gt;if&lt;/span&gt; DomElement=nil &lt;span class="kwrd"&gt;then&lt;/span&gt; exit;&lt;br /&gt;       &lt;span class="kwrd"&gt;if&lt;/span&gt; DomElement.ChildNodes=nil &lt;span class="kwrd"&gt;then&lt;/span&gt; exit;&lt;br /&gt;       &lt;span class="kwrd"&gt;if&lt;/span&gt; DomElement.ChildNodes.Length=0 &lt;span class="kwrd"&gt;then&lt;/span&gt; exit;&lt;br /&gt;       result:=DomElement.ChildNodes.Item(0).NodeValue;&lt;br /&gt;    &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span class="rem"&gt;//same as the previous but designed &lt;span class="kwrd"&gt;to&lt;/span&gt; get a subelement (LatLng/Lat or LatLng/Lng)&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;function&lt;/span&gt; SafeGetSubNodeValue(node:TDomNode; rootName, subName:&lt;span class="kwrd"&gt;string&lt;/span&gt;):&lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;br /&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; RootElement,&lt;br /&gt;        SubElement:TDomElement;&lt;br /&gt;    &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;       result:=&lt;span class="str"&gt;''&lt;/span&gt;;&lt;br /&gt;       RootElement:=Node.GetFirstChildElement(rootName);&lt;br /&gt;       &lt;span class="kwrd"&gt;if&lt;/span&gt; RootElement=nil &lt;span class="kwrd"&gt;then&lt;/span&gt; exit;&lt;br /&gt;       SubElement:=RootElement.GetFirstChildElement(subName);&lt;br /&gt;       &lt;span class="kwrd"&gt;if&lt;/span&gt; subElement=nil &lt;span class="kwrd"&gt;then&lt;/span&gt; exit;&lt;br /&gt;       &lt;span class="kwrd"&gt;if&lt;/span&gt; subElement.ChildNodes=nil &lt;span class="kwrd"&gt;then&lt;/span&gt; exit;&lt;br /&gt;       &lt;span class="kwrd"&gt;if&lt;/span&gt; subElement.ChildNodes.Length=0 &lt;span class="kwrd"&gt;then&lt;/span&gt; exit;&lt;br /&gt;       result:=subElement.ChildNodes.Item(0).NodeValue;&lt;br /&gt;    &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;   ClearReturnedAddys;                                                                             &lt;span class="rem"&gt;//make sure there are no saved addys&lt;/span&gt;&lt;br /&gt;   DOC:=TXML&lt;span class="kwrd"&gt;to&lt;/span&gt;DomParser.Create(nil);                                                               &lt;span class="rem"&gt;//create the xml parser&lt;/span&gt;&lt;br /&gt;   DOM:=TDOMImplementation.Create(nil);                                                            &lt;span class="rem"&gt;//create the dom&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;     DOC.DOMImpl:=DOM;                                                                             &lt;span class="rem"&gt;//assign the dom &lt;span class="kwrd"&gt;to&lt;/span&gt; the xml parser&lt;/span&gt;&lt;br /&gt;     XML := DOC.String&lt;span class="kwrd"&gt;to&lt;/span&gt;Dom(response.Text,&lt;span class="str"&gt;'mapquest.xml'&lt;/span&gt;,nil,&lt;span class="kwrd"&gt;true&lt;/span&gt;);                                &lt;span class="rem"&gt;//convert the response text &lt;span class="kwrd"&gt;to&lt;/span&gt; and xml document. NOTE: 'mapquest.xml' forces the correct creation of the node structures. If you pass blank, you get NO NODES&lt;/span&gt;&lt;br /&gt;     &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;br /&gt;        LocCollection := XML.GetElementsByTagName(&lt;span class="str"&gt;'LocationCollection'&lt;/span&gt;);                           &lt;span class="rem"&gt;//get the location collection (group of geoaddresses 1..n)&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; LocCollection=nil &lt;span class="kwrd"&gt;then&lt;/span&gt; exit;&lt;br /&gt;&lt;br /&gt;        Node:=LocCollection.Item(0);                                                               &lt;span class="rem"&gt;//get the &lt;span class="kwrd"&gt;to&lt;/span&gt;p level node&lt;/span&gt;&lt;br /&gt;        Geo:=Node.GetFirstChildElement(&lt;span class="str"&gt;'GeoAddress'&lt;/span&gt;);                                              &lt;span class="rem"&gt;//get the first GeoAddress&lt;/span&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;while&lt;/span&gt; Geo&amp;lt;&amp;gt;nil &lt;span class="kwrd"&gt;do&lt;/span&gt;                                                                          &lt;span class="rem"&gt;//while we have a GeoAddress&lt;/span&gt;&lt;br /&gt;           &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;           fReturnedAddresses.Add(TReturnedAddy.Create(SafeGetNodeValue(Geo, &lt;span class="str"&gt;'Street'&lt;/span&gt;),            &lt;span class="rem"&gt;//addy&lt;/span&gt;&lt;br /&gt;                                                       SafeGetNodeValue(Geo, &lt;span class="str"&gt;'AdminArea5'&lt;/span&gt;),        &lt;span class="rem"&gt;//city&lt;/span&gt;&lt;br /&gt;                                                       SafeGetNodeValue(Geo, &lt;span class="str"&gt;'AdminArea3'&lt;/span&gt;),        &lt;span class="rem"&gt;//state&lt;/span&gt;&lt;br /&gt;                                                       SafeGetNodeValue(Geo, &lt;span class="str"&gt;'PostalCode'&lt;/span&gt;),        &lt;span class="rem"&gt;//zip&lt;/span&gt;&lt;br /&gt;                                                       SafeGetNodeValue(Geo, &lt;span class="str"&gt;'AdminArea1'&lt;/span&gt;),        &lt;span class="rem"&gt;//country&lt;/span&gt;&lt;br /&gt;                                                       SafeGetNodeValue(Geo, &lt;span class="str"&gt;'AdminArea4'&lt;/span&gt;),        &lt;span class="rem"&gt;//county&lt;/span&gt;&lt;br /&gt;                                                       SafeGetSubNodeValue(Geo, &lt;span class="str"&gt;'LatLng'&lt;/span&gt;, &lt;span class="str"&gt;'Lat'&lt;/span&gt;),  &lt;span class="rem"&gt;//Latitude&lt;/span&gt;&lt;br /&gt;                                                       SafeGetSubNodeValue(Geo, &lt;span class="str"&gt;'LatLng'&lt;/span&gt;, &lt;span class="str"&gt;'Lng'&lt;/span&gt;)   &lt;span class="rem"&gt;//Longitude&lt;/span&gt;&lt;br /&gt;                                                       ));&lt;br /&gt;           Geo:=Geo.NextSibling;                                                                   &lt;span class="rem"&gt;//get the next GeoAddress&lt;/span&gt;&lt;br /&gt;           &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;     &lt;span class="kwrd"&gt;finally&lt;/span&gt;&lt;br /&gt;        XML.Free;                                                                                  &lt;span class="rem"&gt;//free the XML document&lt;/span&gt;&lt;br /&gt;     &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;   &lt;span class="kwrd"&gt;finally&lt;/span&gt;&lt;br /&gt;      DOM.Free;                                                                                    &lt;span class="rem"&gt;//free the dom&lt;/span&gt;&lt;br /&gt;      DOC.Free;                                                                                    &lt;span class="rem"&gt;//free the xml parser&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;{ TReturnedAddy }&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;//create the object and initialize the data&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;constructor&lt;/span&gt; TReturnedAddy.Create(aAddress, aCity, aState, aPostalCode, aCountry, aCounty, aLat, aLong: &lt;span class="kwrd"&gt;string&lt;/span&gt;);&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;Address:=aAddress;&lt;br /&gt;City:=aCity;&lt;br /&gt;State:=aState;&lt;br /&gt;PostalCode:=aPostalCode;&lt;br /&gt;Country:=aCountry;&lt;br /&gt;County:=aCounty;&lt;br /&gt;Lat:=aLat;&lt;br /&gt;Long:=aLong;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;{ TReturnedAddyList }&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;//easy way &lt;span class="kwrd"&gt;to&lt;/span&gt; get access &lt;span class="kwrd"&gt;to&lt;/span&gt; the accumulated returned addresses&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; TReturnedAddyList.getAddy(index: integer): TReturnedAddy;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;result:=TReturnedAddy(Items[index]);&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;.&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://ruminatedrumblings.blogspot.com/2008/08/mapquest-and-delphi.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1141584826307413089?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1141584826307413089/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1141584826307413089' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1141584826307413089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1141584826307413089'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/mapquest-and-delphi.html' title='MapQuest and Delphi'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-5613085330589343300</id><published>2008-08-15T13:18:00.003-07:00</published><updated>2008-08-15T13:18:21.840-07:00</updated><title type='text'>Writing reusable code - part 2</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;There are a few practices that will help you write solid, maintainable, reusable code.  A lot of software practitioners of greater fame than mine have written about these before, but it doesn't hurt to repeat good advice.&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#eeeeee"&gt;&lt;em&gt;Note that I in no way claim this to be the one and only true way to software development nirvana, but just some practices that work for me.  Your own opinions and experiences on the topic will be greatly appreciated, so feel free to comment.&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;strong&gt;Keep It Simple, Stupid&lt;/strong&gt; &lt;br /&gt;Reusable code should be kept low-feature.  It can be a challenge to avoid feature creep and dependency bloat, so make an effort to follow the KISS rule. The more sophisticated stuff you add, the more you will need to "fix" and not to forget: Test! - when inheriting from the class.  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Design for extendability&lt;/strong&gt;&lt;br /&gt;When you design a reusable class, you really have to define the scope of what you want to achieve.  Decide on the basic feature set, then evaluate the possible offspring to this class and conceivable additional features, but to adhere to the KISS rule - you should not add the features until you need them.  Instead, spend a little time on evaluating the impact of the features and put in any necessary hooks and leave enough comments to allow you to rediscover why you put them in in the first place. &lt;br /&gt;&lt;br /&gt;Later, if you absolutely have to add a feature and cannot add it in an inherited class - make sure you don't break existing behavior in class instancing.  A common mistake is to change a default property value in the base class constructor, which some derived class assumed had a specific state or value. &lt;br /&gt;&lt;br /&gt;...and on the point of assumptions...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Never Assume, Always Assert&lt;/strong&gt;&lt;br /&gt;I bet you never heard that one before!  :)  Use Asserts to check your assumptions.  It will save you from a number of embarrassing moments of broken code. The purists probably want this done in unit testing, but it can help add clarity to your code if it is done in the actual library code. Think of it as &lt;a href="http://en.wikipedia.org/wiki/Design_by_contract"&gt;design by contract&lt;/a&gt;.&lt;br /&gt;&lt;pre name="code" class="delphi"&gt;procedure TSimpleClass.ActOn(aParameter:TSomeClass; aValue:Integer);&lt;br /&gt;begin&lt;br /&gt;  // Ensure aParameter is assigned and of correct type &lt;br /&gt;  Assert(Assigned(aParameter) and (aParameter is TSomeClass));&lt;br /&gt;  // and that aValue is in legal range&lt;br /&gt;  Assert(aValue &gt;= 0);&lt;br /&gt;  ...&lt;/pre&gt;Using asserts like these will help you catch runtime problems faster.  They also will remind you of what conditioning you need to do before you call the method, and what assumptions you can make within the routine itself.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Avoid Dependencies&lt;/strong&gt;&lt;br /&gt;When you start pulling in code from other libraries or classes, you should consider the level of dependency that you introduce.  A simple extra nice-to-have attribute may come with a payload of extra code that hardly ever will be called.  If possible, put the extra attribute in a separate descendant class in a separate unit.  The less code you have to compile in, the better.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Embrace Polymorphism&lt;/strong&gt;&lt;br /&gt;When you create classes that are intended as foundation for descendant classes, you should consider how to best support polymorphic instancing.  &lt;br /&gt;&lt;br /&gt;For example - if you are writing a container class that will hold a polymorph collection of elements - you may want to have a virtual class function that return the default class type used to instance new elements in the container, instead of just instancing the base element class.  Doing so will allow descendant classes make reliable assumptions about the safety of typecasting within the extended methods in the descendant container class.&lt;br /&gt;&lt;pre name="code" class="delphi"&gt;unit BasicClass;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TElementClass = class of TBaseElement;&lt;br /&gt;&lt;br /&gt;  TBaseElement = class(TObject)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TBaseContainer = class(TObject)&lt;br /&gt;    class function ElementClass:TElementClass; virtual;&lt;br /&gt;    function ValidElement(anElement:TBaseElement):Boolean;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TBaseContainer }&lt;br /&gt;&lt;br /&gt;class function TBaseContainer.ElementClass: TElementClass;&lt;br /&gt;begin&lt;br /&gt;  Result := TBaseElement;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TBaseContainer.ValidElement(anElement: TBaseElement): Boolean;&lt;br /&gt;begin&lt;br /&gt;  Result := anElement is ElementClass;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;/pre&gt;&lt;em&gt;"But..."&lt;/em&gt; - you will say; &lt;em&gt;"you can just override methods in the descendant class for the same effect?".&lt;/em&gt;  Yes, you can and it works well when you add new functionality, but what about functionality that already has been implemented in class higher in your inheritance tree?  &lt;br /&gt;&lt;pre name="code" class="delphi"&gt;unit AdvancedClass;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;uses&lt;br /&gt;  BasicClass;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TAdvancedElement = class (TBaseElement)&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TAdvancedContainer = class(TBaseContainer)&lt;br /&gt;    class function ElementClass:TElementClass; override;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TAdvancedContainer }&lt;br /&gt;&lt;br /&gt;class function TAdvancedContainer.ElementClass: TElementClass;&lt;br /&gt;begin&lt;br /&gt;  Result := TAdvancedElement;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;/pre&gt;The base class won't have an understanding of it's descendants, so if you want it to be able to work with content from descendant classes, you would either have to override/redo the functionality or - do as above - allow the base class to work with their own child classes as well.&lt;br /&gt;&lt;pre name="code" class="delphi"&gt;program ExtendableClasses;&lt;br /&gt;{$APPTYPE CONSOLE}&lt;br /&gt;uses&lt;br /&gt;  SysUtils,&lt;br /&gt;  BasicClass in 'BasicClass.pas',&lt;br /&gt;  AdvancedClass in 'AdvancedClass.pas';&lt;br /&gt;&lt;br /&gt;procedure Main;&lt;br /&gt;var&lt;br /&gt;  Element1, Element2     : TBaseElement;&lt;br /&gt;  Container1, Container2 : TBaseContainer;&lt;br /&gt;begin&lt;br /&gt;  Container1 := TBaseContainer.Create;&lt;br /&gt;  Container2 := TAdvancedContainer.Create;&lt;br /&gt;&lt;br /&gt;  Element1 := Container1.ElementClass.Create;&lt;br /&gt;  Element2 := Container2.ElementClass.Create;&lt;br /&gt;&lt;br /&gt;  Writeln('E1: ', Element1.ClassName);&lt;br /&gt;  Writeln('E2: ', Element2.ClassName);&lt;br /&gt;&lt;br /&gt;  Writeln('E1 valid in C1: ', Container1.ValidElement(Element1));&lt;br /&gt;  Writeln('E2 valid in C1: ', Container1.ValidElement(Element2));&lt;br /&gt;&lt;br /&gt;  Writeln('E1 valid in C2: ', Container2.ValidElement(Element1));&lt;br /&gt;  Writeln('E2 valid in C2: ', Container2.ValidElement(Element2));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  try&lt;br /&gt;    try&lt;br /&gt;      Main;&lt;br /&gt;    except&lt;br /&gt;      on E:Exception do&lt;br /&gt;        Writeln(E.Classname, ': ', E.Message);&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    Write('Press Enter: ');&lt;br /&gt;    Readln;&lt;br /&gt;  end;&lt;br /&gt;end.&lt;/pre&gt;&lt;img src="http://public.fosdal.com/ExtendableClasses.png" border="0" alt="Result" /&gt;&lt;br /&gt;&lt;br /&gt;This particularly goes for dialogs and forms that use a polymorph class - make a virtual class function to enable overriding the class instancing.  Avoid the rigidly defined TSomeInheritableClass.Create constructs and call the virtual class type function instead. &lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;br /&gt;&lt;td bgcolor="#eeeeee"&gt;&lt;strong&gt;Note on constructors&lt;/strong&gt;&lt;br /&gt;When I finally "got" OOP as opposed to structured programming, it was hard to drop the structured way of thinking when it came to instancing.  Most of my classes would only have a constructor that took a ton of parameters to save a few lines at the point of instancing that class.  &lt;br /&gt;&lt;br /&gt;While this might work well for monomorphic classes, it really will not be good for a class hierarchy, and it took me some time to get to the habit of having a parameterless Create.  Today, I almost wish for a compiler hint if I should happen to write constructors that require parameters.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Hide detail with Layers&lt;/strong&gt;&lt;br /&gt;Think in APIs and layers and try to propagate only content between the layers, and not details that are specific to connectivity, storage, etc.  A good layered design will allow you to rip out and replace parts of the architecture without massive rewrites.   &lt;br /&gt;&lt;br /&gt;When you design your APIs or layers, you should consider leaving space or hooks for piggybacking in more content in yet-to-be defined formats where appropriate.  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Isolate Data from the GUI&lt;/strong&gt;&lt;br /&gt;The less your GUI know about your data, the better.  Vise versa, the less your data knows about the GUI, the better.  Use a mediating class that does the job of knowing both and how to tie them together.  This will ease the job of making the data structures as well as the GUI reusable.&lt;br /&gt;&lt;br /&gt;It can be particularly useful to tie your business logic to your data and avoid implementing biz.logic in the GUI presentation.  Your data will be easier to move to a different presentation form when the rules are not hard-coded in some draw routine.  You don't want to have duplication of biz.logic code between the display routines, the report routines, the export routines, etc.&lt;br /&gt;&lt;br /&gt;-&lt;br /&gt;&lt;br /&gt;Thats it for now. More on the topic of Layers and GUI abstraction to follow.  &lt;br /&gt;Also, part 3 of the reusable grid.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphi.fosdal.com/2008/07/writing-reusable-code-part-2.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-5613085330589343300?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/5613085330589343300/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=5613085330589343300' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5613085330589343300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5613085330589343300'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/writing-reusable-code-part-2.html' title='Writing reusable code - part 2'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-5500780647384161662</id><published>2008-08-15T13:18:00.001-07:00</published><updated>2008-08-15T13:18:05.553-07:00</updated><title type='text'>Reusable Grid View - part 3</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Let's take a closer look at how to hijack a pristine TStringGrid and make it our playground without inheriting the grid directly.  The VCL class is well designed for reuse and expose properties and event handlers that we easily can grab hold of.  The OnDrawCell event is of particular interest to us.  That's a good spot to redefine how the grid retrieve and render it's content.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;You will be assimilated&lt;/strong&gt;&lt;br /&gt;This is pretty self explanatory, but what we basically do is hook the draw routine and set up the appropriate number of rows and columns, and their respective default widths. &lt;br /&gt;&lt;pre name="code" class="delphi"&gt;procedure TGridViewController.Refresh;&lt;br /&gt;var&lt;br /&gt;  ix : Integer;&lt;br /&gt;begin&lt;br /&gt;  if not Assigned(Grid)&lt;br /&gt;   then Exit;&lt;br /&gt;&lt;br /&gt;  if not IsEmpty&lt;br /&gt;  then begin // Set Visitor's drawing handler, row and column count&lt;br /&gt;    Grid.Enabled := True;&lt;br /&gt;    Grid.OnDrawCell := DrawCell;&lt;br /&gt;    Grid.RowCount := RowCount + FixedRows;&lt;br /&gt;    Grid.ColCount := Count;&lt;br /&gt;    for ix := 0 to Count - 1  // Set column widths&lt;br /&gt;     do begin&lt;br /&gt;       Grid.ColWidths[ix] := (Objects[ix] as TGridViewColumn).Width;&lt;br /&gt;     end;&lt;br /&gt;  end&lt;br /&gt;  else begin // disable drawing handler, set rows/cols to 1 and fill in 1 "blank"&lt;br /&gt;    Grid.Enabled := False;&lt;br /&gt;    Grid.OnDrawCell := nil;&lt;br /&gt;    Grid.RowCount := 1;&lt;br /&gt;    Grid.ColCount := 1;&lt;br /&gt;    Grid.ColWidths[0] := 0;&lt;br /&gt;    Grid.Cells[0,0] := defaultEmptyCell;&lt;br /&gt;  end;&lt;br /&gt;  if Grid.RowCount &gt; 1&lt;br /&gt;  then begin // Reset header and Row positions in case empty grid overrode them.&lt;br /&gt;    Grid.FixedRows := FixedRows;&lt;br /&gt;    Grid.Row := FixedRows;&lt;br /&gt;  end;&lt;br /&gt;  Grid.Invalidate; // ensure that the grid is refreshed&lt;br /&gt;end;&lt;/pre&gt;&lt;strong&gt;OnDrawCell&lt;/strong&gt;&lt;br /&gt;So this is where all the action is... err... actually, not much happens here.  Instead we delegate the actual rendering to the column instance.&lt;pre name="code" class="delphi"&gt;procedure TGridViewController.DrawCell(Sender: TObject; ACol, ARow: Integer;&lt;br /&gt;  Rect: TRect; State: TGridDrawState);&lt;br /&gt;begin&lt;br /&gt;  (Objects[aCol] as TGridViewColumn).DrawCell(Grid.Canvas, aRow, Rect, State);&lt;br /&gt;end;&lt;/pre&gt;The column instance then again divide the draw into two sections.  The outer &lt;em&gt;DrawCell&lt;/em&gt; does basic housekeeping of canvas color settings and a little color trickery (a feature that snuck in while I was having fun - my bad). &lt;pre name="code" class="delphi"&gt;procedure TGridViewColumn.DrawCell(Canvas: TCanvas; aRow: Integer; Rect: TRect;&lt;br /&gt;  State: TGridDrawState);&lt;br /&gt;var&lt;br /&gt;  FG, ofg,&lt;br /&gt;  BG, obg : TColor;&lt;br /&gt;begin&lt;br /&gt;  with Canvas&lt;br /&gt;  do begin&lt;br /&gt;    ofg:=Font.Color;&lt;br /&gt;    obg:=Brush.Color;&lt;br /&gt;&lt;br /&gt;    if (State = []) // Not focused/selected/etc&lt;br /&gt;    then begin&lt;br /&gt;      FG := ofg;&lt;br /&gt;      BG := obg;&lt;br /&gt;&lt;br /&gt;      if aRow &gt; 0 // Not a title line&lt;br /&gt;      then begin&lt;br /&gt;        ForeColor(aRow, FG);&lt;br /&gt;        BackColor(aRow, BG);&lt;br /&gt;      end;&lt;br /&gt;&lt;br /&gt;      if ofg &lt;&gt; FG then Font.Color:=FG;&lt;br /&gt;      if obg &lt;&gt; BG then Brush.Color:=BG;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;    DrawCellInner(Canvas, aRow - Controller.FixedRows, Rect, State); // The business happens here&lt;br /&gt;&lt;br /&gt;    if (State = [])&lt;br /&gt;    then begin&lt;br /&gt;      if ofg &lt;&gt; FG then Font.Color:=ofg;&lt;br /&gt;      if obg &lt;&gt; BG then Brush.Color:=obg;&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;/pre&gt;The actual content rendering happens in &lt;em&gt;DrawCellInner&lt;/em&gt;. Note that we do an adjustment related to grid layout here.  If you look at the line where &lt;em&gt;DrawCellInner&lt;/em&gt; is called, we subtract &lt;em&gt;FixedRows&lt;/em&gt; from &lt;em&gt;aRow&lt;/em&gt;, ensuring that our data is zero offset based.&lt;pre name="code" class="delphi"&gt;procedure TGridViewColumn.DrawCellInner(Canvas: TCanvas; aRow: Integer;&lt;br /&gt;  Rect: TRect; State: TGridDrawState);&lt;br /&gt;var&lt;br /&gt;  CellText : String;&lt;br /&gt;  w      : Integer; // String width&lt;br /&gt;  txtAdj : Integer; // old adjust mode&lt;br /&gt;begin&lt;br /&gt;  if aRow &lt; 0&lt;br /&gt;  then CellText := Title&lt;br /&gt;  else CellText := FormattedText(aRow);&lt;br /&gt;  with Canvas&lt;br /&gt;  do begin&lt;br /&gt;    case FAlign of&lt;br /&gt;      taCenter       : begin&lt;br /&gt;                         w:=TextWidth(CellText);&lt;br /&gt;                         if (w&gt;(Rect.Right-Rect.Left))&lt;br /&gt;                         then w := 2&lt;br /&gt;                         else w := Round(((Rect.Right - Rect.Left) - w) / 2);&lt;br /&gt;                         TextRect(Rect, Rect.Left + w,Rect.Top + 1, CellText);&lt;br /&gt;                       end;&lt;br /&gt;      taRightJustify : begin&lt;br /&gt;                         txtAdj:=SetTextAlign(Handle, ta_Top or ta_Right);&lt;br /&gt;                         TextRect(Rect, Rect.Right - 3,Rect.Top + 1, CellText);&lt;br /&gt;                         SetTextAlign(Handle, txtAdj);&lt;br /&gt;                       end;&lt;br /&gt;               else // taLeftJustify&lt;br /&gt;                       TextRect(Rect, Rect.Left+2,Rect.Top+1, CellText);&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;/pre&gt;In the inner draw routine we first figure out if we are drawing the title row or a data row.  If it is a data row, we call the &lt;em&gt;TGridViewColumn.FormattedText&lt;/em&gt; method.&lt;pre name="code" class="delphi"&gt;function TGridViewTextColumn.FormattedText(aRow: Integer): String;&lt;br /&gt;begin&lt;br /&gt;  Result := GetTextMethod(aRow);&lt;br /&gt;end;&lt;/pre&gt;Does &lt;em&gt;GetTextMethod&lt;/em&gt; look familiar?  It is the procedure variable which holds the method we implement in our descendant viewcontroller class and pass on when we set up the column.  That is the method which actually retrieve the data from the underlying data structure as described in &lt;a href="http://delphi.fosdal.com/2008/07/reusable-grid-view-part-2.html"&gt;part 2&lt;/a&gt; (&lt;em&gt;GetNumber&lt;/em&gt;, &lt;em&gt;GetNumberSquared&lt;/em&gt;). &lt;br /&gt;&lt;br /&gt;The rest of &lt;em&gt;DrawCellInner&lt;/em&gt; measures the retrieved text and ensure it is adjusted as desired and rendered within the cell region.  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Magic Colors&lt;/strong&gt;&lt;br /&gt;Back to &lt;em&gt;ForeColor&lt;/em&gt; and &lt;em&gt;BackColor&lt;/em&gt; in the outer draw.  This is the closest we come to bells and whistles.  To make the grid look more sophisticated, I added support for overriding the colors as well as a very simple default rowshading algorithm. &lt;pre name="code" class="delphi"&gt;procedure TGridViewColumn.ForeColor(aRow: Integer; var Color: TColor);&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FGetForeColorMethod)&lt;br /&gt;   then GetForeColorMethod(aRow, Color)&lt;br /&gt;  else if DefaultForeColor &lt;&gt; clNone&lt;br /&gt;   then Color := DefaultForeColor;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TGridViewColumn.BackColor(aRow: Integer; var Color: TColor);&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FGetBackColorMethod)&lt;br /&gt;   then GetBackColorMethod(aRow, Color)&lt;br /&gt;  else if DefaultBackColor &lt;&gt; clNone&lt;br /&gt;   then Color := DefaultBackColor;&lt;br /&gt;&lt;br /&gt;  if Assigned(FGetShadeColorMethod)&lt;br /&gt;  then GetShadeColorMethod(aRow, Color);&lt;br /&gt;end;&lt;/pre&gt;Both these methods start in the same way.  The default color have been retrieved from the grid itself in the outer draw.  First we check if a color method have been plugged in, if not - we check if a column color override has been set.&lt;br /&gt;&lt;br /&gt;For the background color routine, there is another feature - a pluggable shading method.  The default row shader looks like this...&lt;pre name="code" class="delphi"&gt;procedure TGridViewController.DefaultRowShader(const aRow:Integer; var Color:TColor);&lt;br /&gt;begin&lt;br /&gt;  if ShadeRows and (not Odd(aRow))&lt;br /&gt;  then begin&lt;br /&gt;    Color := Graphics.ColorToRGB(Color); // Translate theme/system colors to RGB&lt;br /&gt;    if  ((Color and $FFFFFF) &gt; $888888)  // Lazy man's luminosity adjustment&lt;br /&gt;     then Color := Color - $080808&lt;br /&gt;     else Color := Color + $080808;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;/pre&gt;Too much flexibility?  Well, maybe I broke the KISS rule, but no rule without exceptions :) Now I can have static or procedural color adjustments per row as well as per column.&lt;br /&gt;&lt;br /&gt;Next: Reusable Grid goes code complete and come with examples.&lt;br /&gt;&lt;br /&gt;Stay tuned.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphi.fosdal.com/2008/07/reusable-grid-view-part-3.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-5500780647384161662?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/5500780647384161662/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=5500780647384161662' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5500780647384161662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5500780647384161662'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/reusable-grid-view-part-3.html' title='Reusable Grid View - part 3'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-965032181996173645</id><published>2008-08-15T06:31:00.004-07:00</published><updated>2008-08-15T06:32:57.979-07:00</updated><title type='text'>Reusable Grid View - part 2</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;strong&gt;The Controller&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Our basic TGridViewController will hold a list of TGridViewColumns. I could make a simple array, or I could use TStringList. TStringList is probably one of the best and one of the worst classes in Delphi. So easy to use and so easy to abuse. In this case, I will only need to manage a handful of columns, instead of thousands of lines of text - so it will be ok.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;On the abuse side: before you start filling TStringList - consider adjusting the capacity. Resizing the list is EXPENSIVE. Also - fill first, sort later.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Ok, lets take a look at the initial skeleton of the controller class:&lt;br /&gt;&lt;pre class="delphi" name="code"&gt;&lt;br /&gt;  TGridViewController = class (TStringList)&lt;br /&gt;  private&lt;br /&gt;    FGrid : TStringGrid;&lt;br /&gt;    function GetIsEmpty:Boolean;&lt;br /&gt;    function GetCurrentSelectionIndex: Integer;&lt;br /&gt;  protected&lt;br /&gt;    procedure DefineAttributes; virtual; abstract;&lt;br /&gt;    function GetRowCount: Integer; virtual; abstract;&lt;br /&gt;    procedure SetGrid(const Value: TStringGrid); virtual;&lt;br /&gt;    procedure DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);&lt;br /&gt;    function MakeColumn(ColType : TGridViewColumnType; aTitle:String; aWidth:Integer; anAlign:TAlignment):TGridViewColumn;&lt;br /&gt;  public&lt;br /&gt;    constructor Create; virtual;&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;    procedure Refresh;&lt;br /&gt;    function CreateTextColumn(aTitle:String; aGetText:TGetTextMethod; aWidth:Integer = 64; anAlign:TAlignment = taLeftJustify):TGridViewTextColumn;&lt;br /&gt;    property CurrentSelectionIndex:Integer read GetCurrentSelectionIndex;&lt;br /&gt;    property Grid: TStringGrid read FGrid write SetGrid;&lt;br /&gt;    property IsEmpty: Boolean read GetIsEmpty;&lt;br /&gt;    property RowCount:Integer read GetRowCount;&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I won't go into the details on the TGridViewColumn yet, but note the two abstract methods in the controller: DefineAttributes and GetRowCount. To make a working grid, these are what we need to override. &lt;br /&gt;&lt;br /&gt;The &lt;em&gt;Grid&lt;/em&gt; property identifies the grid that we will control and &lt;em&gt;DrawCell&lt;/em&gt; is the method we plug into the grid onDrawCell event. &lt;em&gt;MakeColumn&lt;/em&gt; is called by the &lt;em&gt;CreateTextColumn&lt;/em&gt; with the appropriate TGridColumnView descendant - hiding the interaction with our parent string list. I guess you already have figured out that &lt;em&gt;IsEmpty&lt;/em&gt; simply check the number of rows.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;A simple Example&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Lets consider the simplest possible example: a grid showing rows with the numbers 1 to 5, and their values squared. Note that the unit is pretty ignorant about what a grid is.&lt;br /&gt;&lt;br /&gt;&lt;pre class="delphi" name="code"&gt;&lt;br /&gt;unit DemoNumbersClass;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  Classes, SysUtils, FDCGridViewController;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TViewNumbers = class(TGridViewController)&lt;br /&gt;  private&lt;br /&gt;    function GetNumber(const Row: Integer): String;&lt;br /&gt;    function GetNumberSquared(const Row: Integer): String;&lt;br /&gt;  protected&lt;br /&gt;    procedure DefineAttributes; override;&lt;br /&gt;    function GetRowCount: Integer; override;&lt;br /&gt;  end;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We define two columns, and refer each column to a data retrival method.&lt;br /&gt;&lt;pre class="delphi" name="code"&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TViewNumbers }&lt;br /&gt;&lt;br /&gt;procedure TViewNumbers.DefineAttributes;&lt;br /&gt;begin&lt;br /&gt;  CreateTextColumn('Number', GetNumber);&lt;br /&gt;  CreateTextColumn('Squared', GetNumberSquared, 64, taRightJustify);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TViewNumbers.GetNumber(const Row: Integer): String;&lt;br /&gt;begin&lt;br /&gt;  Result := IntToStr(Row);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TViewNumbers.GetNumberSquared(const Row: Integer): String;&lt;br /&gt;begin&lt;br /&gt;  Result := IntToStr(SQR(Row));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TViewNumbers.GetRowCount: Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := 5;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then we create a Form, drop a string grid on it, tweak some row size settings etc., and add the controller.&lt;br /&gt;&lt;br /&gt;&lt;pre class="delphi" name="code"&gt;&lt;br /&gt;unit DemoFDCGridViewController;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  Windows, Messages, SysUtils, Classes, Controls, Forms,&lt;br /&gt;  StdCtrls, Grids, FDCGridViewController, DemoNumbersClass;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TGridViewForm = class(TForm)&lt;br /&gt;    StringGrid1: TStringGrid;&lt;br /&gt;    procedure FormCreate(Sender: TObject);&lt;br /&gt;  private&lt;br /&gt;    Numbers : TViewNumbers;&lt;br /&gt;  public&lt;br /&gt;    { Public declarations }&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  GridViewForm: TGridViewForm;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{$R *.dfm}&lt;br /&gt;&lt;br /&gt;{ TGridViewForm }&lt;br /&gt;&lt;br /&gt;procedure TGridViewForm.FormCreate(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;  // Create our controller&lt;br /&gt;  Numbers := TViewNumbers.Create;&lt;br /&gt;  // and introduce the controller to the host grid&lt;br /&gt;  Numbers.Grid := StringGrid1;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And the result: &lt;img style="cursor:pointer; cursor:hand;" src="http://public.fosdal.com/GridNumbersDemo.png" border="0" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;As you can see, there are a few tweaks that I haven't described yet.  Also, I still haven't revealed the simple steps done to invade our host grid.&lt;br /&gt;&lt;br /&gt;Stay tuned :)&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphi.fosdal.com/2008/07/reusable-grid-view-part-2.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-965032181996173645?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/965032181996173645/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=965032181996173645' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/965032181996173645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/965032181996173645'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/reusable-grid-view-part-2.html' title='Reusable Grid View - part 2'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1689523148369341835</id><published>2008-08-15T06:31:00.003-07:00</published><updated>2008-08-15T06:32:15.639-07:00</updated><title type='text'>Writing Readable Code - Formatting and Comments</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;I guess there are at least as many coding styles as there are programmers times programming languages.  Many of us are conformists, and some of us have our highly personal style, but most of us probably fail at being 100% consistant.  Code formatting can probably be considered a slightly religious area, so please feel free to disagree with me :)&lt;br /&gt;&lt;br /&gt;So - why bother to put any effort into the formatting anyways? It is not like the compiler care?  I mean, apart from the obvious requirement that things should be reasonable readable and not just a jumble of code?  &lt;br /&gt;&lt;br /&gt;Layout matters.  It is significantly easier to pick up code that is consistant in style than wading through spaghetti (or gnocchi) code where the indentation has not been considered much.&lt;br /&gt;&lt;br /&gt;I have noticed that my personal style with regards to block formatting definitively is non-conformist. Whenever there is a do, if/then/else, with or without related begin/end, I will probably annoy the heck out of the conformists. &lt;br /&gt;&lt;br /&gt;My formatting goals:&lt;br /&gt;&amp;bull; I want clear indication of flow&lt;br /&gt;&amp;bull; I want to separate conditions from actions &lt;br /&gt;&amp;bull; I want room to comment &lt;br /&gt;&lt;br /&gt;In the examples below, I will place comments in the individualist examples to give an indication of why I choose to wrap/indent in this way rather than the "global standard"&lt;br /&gt;&lt;br /&gt;Let's start with the &lt;em&gt;do&lt;/em&gt; in &lt;em&gt;with&lt;/em&gt; and the &lt;em&gt;for&lt;/em&gt;-loop  (I do at times, albeit rarely, confess to the occasional use of &lt;em&gt;with&lt;/em&gt;).&lt;pre name="code" class="delphi"&gt;&lt;br /&gt;// Conformist&lt;br /&gt;  for i := 1 to 5 do Something;&lt;br /&gt;&lt;br /&gt;  for i := 1 to 5 do begin&lt;br /&gt;    Something;&lt;br /&gt;    SomethingMore;&lt;br /&gt;  end;&lt;br /&gt;  &lt;br /&gt;  with SomeObject do begin&lt;br /&gt;    Something;&lt;br /&gt;    SomethingMore;&lt;br /&gt;  end;&lt;br /&gt;  &lt;br /&gt;// Individualist&lt;br /&gt;  for i := 1 to 5     // For selected range&lt;br /&gt;   do Something(i);   // get stuff done&lt;br /&gt;&lt;br /&gt;  for i := 0 to (count - 1) // For every item&lt;br /&gt;  do begin              &lt;br /&gt;    Something(i);       // Step 1&lt;br /&gt;    SomethingMore(i);   // Step 2&lt;br /&gt;  end;&lt;br /&gt;  &lt;br /&gt;  with SomeObject  // Focusing on this specific item,  &lt;br /&gt;  do begin         // I can add this comment for clarity&lt;br /&gt;    Something;&lt;br /&gt;    SomethingMore;&lt;br /&gt;  end;&lt;/pre&gt;&lt;br /&gt;The if/then/else statement have too many combinations to even get close to cover them all, so I am only going to do a handful.&lt;pre name="code" class="delphi"&gt;&lt;br /&gt;// Conformist&lt;br /&gt;  if (SomeVariable = Condition) and (SomeOtherExpression) then&lt;br /&gt;    PerformSomeRoutine;&lt;br /&gt;    &lt;br /&gt;  if (SomeVariable = Condition) and (SomeOtherExpression) then begin&lt;br /&gt;    Code;&lt;br /&gt;    MoreCode;&lt;br /&gt;    LotsOfCode;&lt;br /&gt;  end else OtherCode;&lt;br /&gt;&lt;br /&gt;  if Condition then DoFirstAlternative else DoSecondAlternative;&lt;br /&gt;  &lt;br /&gt;  if FirstCondition then DoFirstAlternative &lt;br /&gt;  else if SecondCondition then DoSecondAlternative&lt;br /&gt;  else DoThirdAlternative;&lt;br /&gt;    &lt;br /&gt;// Individualist&lt;br /&gt;  if (SomeVariable = Condition)    // I always put the condition alone&lt;br /&gt;   then PerformSomeRoutine;&lt;br /&gt;&lt;br /&gt;  if   (SomeVariable = Condition)  // Condition X found&lt;br /&gt;   and (SomeOtherExpression)       // Requirement Y fulfulled&lt;br /&gt;  then begin  // we can do our stuff&lt;br /&gt;    Code;&lt;br /&gt;    MoreCode;&lt;br /&gt;    LotsOfCode;&lt;br /&gt;  end&lt;br /&gt;   else OtherCode; // or we ended up with the alternative&lt;br /&gt;&lt;br /&gt;  if Condition &lt;br /&gt;   then DoFirstAlternative   // The Condition compelled us to do this&lt;br /&gt;   else DoSecondAlternative; // Optionally, we explain the alternative &lt;br /&gt;  &lt;br /&gt;  // Here I find myself doing many different approaches, &lt;br /&gt;  // depending on the complexity of the logic, and the number&lt;br /&gt;  // of alternatives, but with multiple nested if's, I tend to indent&lt;br /&gt;  if FirstCondition            &lt;br /&gt;   then DoFirstAlternative     // We are doing 1 because ...&lt;br /&gt;   else if SecondCondition &lt;br /&gt;    then DoSecondAlternative   // We are doing 2 because ...&lt;br /&gt;    else DoThirdAlternative;   // Otherwise, We are doing 3&lt;br /&gt;&lt;br /&gt;  // I might chose this approach if it is a long chain&lt;br /&gt;  if FirstCondition            &lt;br /&gt;   then DoFirstAlternative   // We are doing 1 because ...&lt;br /&gt;  else if SecondCondition &lt;br /&gt;   then DoSecondAlternative  // We are doing 2 because ...&lt;br /&gt;  else DoThirdAlternative;   // Otherwise, We are doing 3&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;C++/C# and Java people likes to rant about how ugly and verbose our &lt;em&gt;begin / end&lt;/em&gt;'s are, and I am sure I could rile myself up over their curly brace enclosures and some of the religion connected to those too - but I am not going to go there.  However, there are a few things about our enclosures that may be worth thinking over. &lt;br /&gt;&lt;br /&gt;Some like to dangle their &lt;em&gt;end&lt;/em&gt;'s at various indentation levels.  I prefer to align it with the matching start of the block (&lt;em&gt;do begin, then begin&lt;/em&gt;).  Why?  It makes it is easier to identify the code path in relation to the condition.&lt;br /&gt;&lt;br /&gt;More enclosures doesn't always mean better readability.  Here is an example from Indy9(IdTunnelCommon.pas). Kudzu, I love you - but I disagree with your code style in this file :) &lt;br /&gt;(I know I am going to get flamed for this...^^)&lt;pre name="code" class="delphi"&gt;procedure TReceiver.SetData(const Value: string);&lt;br /&gt;var&lt;br /&gt;  CRC16: Word;&lt;br /&gt;begin&lt;br /&gt;  Locker.Enter;&lt;br /&gt;  try&lt;br /&gt;    try&lt;br /&gt;      fsData := Value;&lt;br /&gt;      fiMsgLen := Length(fsData);&lt;br /&gt;      if fiMsgLen &gt; 0 then begin&lt;br /&gt;        Move(fsData[1], (pBuffer + fiPrenosLen)^, fiMsgLen);&lt;br /&gt;        fiPrenosLen := fiPrenosLen + fiMsgLen;&lt;br /&gt;        if (fiPrenosLen &gt;= HeaderLen) then begin&lt;br /&gt;          // copy the header&lt;br /&gt;          Move(pBuffer^, Header, HeaderLen);&lt;br /&gt;          TypeDetected := True;&lt;br /&gt;          // do we have enough data for the entire message&lt;br /&gt;          if Header.MsgLen &lt;= fiPrenosLen then begin&lt;br /&gt;            MsgLen := Header.MsgLen - HeaderLen;&lt;br /&gt;            Move((pBuffer+HeaderLen)^, Msg^, MsgLen);&lt;br /&gt;            // Calculate the crc code&lt;br /&gt;            CRC16 := CRC16Calculator.HashValue(Msg^);&lt;br /&gt;            if CRC16 &lt;&gt; Header.CRC16 then begin&lt;br /&gt;              fCRCFailed := True;&lt;br /&gt;            end&lt;br /&gt;            else begin&lt;br /&gt;              fCRCFailed := False;&lt;br /&gt;            end;&lt;br /&gt;            fbNewMessage := True;&lt;br /&gt;          end&lt;br /&gt;          else begin&lt;br /&gt;            fbNewMessage := False;&lt;br /&gt;          end;&lt;br /&gt;        end&lt;br /&gt;        else begin&lt;br /&gt;          TypeDetected := False;&lt;br /&gt;        end;&lt;br /&gt;      end&lt;br /&gt;      else begin&lt;br /&gt;        fbNewMessage := False;&lt;br /&gt;        TypeDetected := False;&lt;br /&gt;      end;&lt;br /&gt;    except&lt;br /&gt;      raise;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;  finally&lt;br /&gt;    Locker.Leave;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;/pre&gt;This little nugget very much bear the signs of being written for debugging, so I am not going to hold it to Kudzu for style (much). It includes a few nice examples of code that can be simplified, so it is all good.  &lt;br /&gt;&lt;br /&gt;So what do I do? &amp;bull; I assume the except block was for debugging, but I'm taking it out.  &amp;bull; I might be changing the behaviour by setting two default values up top, but at least there is no doubt about their default value. &amp;bull; But what is with the conditional assignments?  Please!  BooleanVariable := Expression; !! Don't go "then true else false" on me!  &amp;bull; Reworked the comments.&lt;br /&gt;&lt;br /&gt;Personally, I think it is more readable like this.&lt;pre name="code" class="delphi"&gt;procedure TReceiver.SetData(const Value: string);&lt;br /&gt;var&lt;br /&gt;  CRC16: Word;&lt;br /&gt;begin&lt;br /&gt;  fbNewMessage := False;&lt;br /&gt;  TypeDetected := False;&lt;br /&gt;  Locker.Enter;&lt;br /&gt;  try&lt;br /&gt;    fsData := Value;&lt;br /&gt;    fiMsgLen := Length(fsData);&lt;br /&gt;    if fiMsgLen &gt; 0&lt;br /&gt;    then begin // Data found, Check for Type&lt;br /&gt;      Move(fsData[1], (pBuffer + fiPrenosLen)^, fiMsgLen);&lt;br /&gt;      fiPrenosLen := fiPrenosLen + fiMsgLen;&lt;br /&gt;      TypeDetected := (fiPrenosLen &gt;= HeaderLen);&lt;br /&gt;      if TypeDetected&lt;br /&gt;      then begin // We have a type, check header for content&lt;br /&gt;        Move(pBuffer^, Header, HeaderLen);&lt;br /&gt;        fbNewMessage := Header.MsgLen &lt;= fiPrenosLen;&lt;br /&gt;        if fbNewMessage&lt;br /&gt;        then begin  // we have enough data for the entire message&lt;br /&gt;          MsgLen := Header.MsgLen - HeaderLen;&lt;br /&gt;          Move((pBuffer+HeaderLen)^, Msg^, MsgLen);&lt;br /&gt;          CRC16 := CRC16Calculator.HashValue(Msg^);  // Calculate the crc code&lt;br /&gt;          fCRCFailed := CRC16 &lt;&gt; Header.CRC16;       // and check if it was correct&lt;br /&gt;        end;&lt;br /&gt;      end;&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    Locker.Leave;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;/pre&gt;Now, where is that flameproof tin foil dress...&lt;br /&gt;&lt;br /&gt;Next: I'll be rambling a little more on effective comments, naming and structure.&lt;br /&gt;&lt;br /&gt;Edit - added after Paul's Snippet Rewritten: Delphifreak likes to exit early. He also likes to initialize up top, and I totally agree - that is a good practice. Exit works well in this example where all the conditions are dependant on the previous one.  IMO, things get a lot more hairy if there are multiple conditions with alternatives (if/then/else if).  For this example, Exits are not bad.&lt;pre name="code" class="delphi"&gt;procedure TReceiver.SetData(const Value: string);&lt;br /&gt;var&lt;br /&gt;  CRC16: Word;&lt;br /&gt;begin&lt;br /&gt;  fbNewMessage := False;&lt;br /&gt;  TypeDetected := False;&lt;br /&gt;  Locker.Enter;&lt;br /&gt;  try&lt;br /&gt;    fsData := Value;&lt;br /&gt;    fiMsgLen := Length(fsData);&lt;br /&gt;    if fiMsgLen = 0&lt;br /&gt;     then Exit;&lt;br /&gt;&lt;br /&gt;    // Data found, Check for Type&lt;br /&gt;    Move(fsData[1], (pBuffer + fiPrenosLen)^, fiMsgLen);&lt;br /&gt;    fiPrenosLen := fiPrenosLen + fiMsgLen;&lt;br /&gt;    TypeDetected := (fiPrenosLen &gt;= HeaderLen);&lt;br /&gt;    if not TypeDetected&lt;br /&gt;     then Exit;&lt;br /&gt;&lt;br /&gt;    // We have a type, check header for content&lt;br /&gt;    Move(pBuffer^, Header, HeaderLen);&lt;br /&gt;    fbNewMessage := Header.MsgLen &lt;= fiPrenosLen;&lt;br /&gt;    if not fbNewMessage&lt;br /&gt;     then Exit;&lt;br /&gt;&lt;br /&gt;    // we have enough data for the entire message&lt;br /&gt;    MsgLen := Header.MsgLen - HeaderLen;&lt;br /&gt;    Move((pBuffer+HeaderLen)^, Msg^, MsgLen);&lt;br /&gt;    CRC16 := CRC16Calculator.HashValue(Msg^);  // Calculate the crc code&lt;br /&gt;    fCRCFailed := CRC16 &lt;&gt; Header.CRC16;       // and check if it was correct&lt;br /&gt;&lt;br /&gt;  finally&lt;br /&gt;    Locker.Leave;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphi.fosdal.com/2008/08/writing-readble-code-formatting-and.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1689523148369341835?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1689523148369341835/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1689523148369341835' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1689523148369341835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1689523148369341835'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/writing-readable-code-formatting-and.html' title='Writing Readable Code - Formatting and Comments'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-3011273059520091440</id><published>2008-08-15T06:31:00.002-07:00</published><updated>2008-08-15T06:32:11.046-07:00</updated><title type='text'>Writing Readable Code - Paul's Snippet - Show your formatting!</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Paul made an &lt;a href="http://delphi.fosdal.com/2008/08/writing-readble-code-formatting-and.html"&gt;comment in my previous post&lt;/a&gt;, but unfortunately the Blogger comment system ate all the whitespace.  Paul, if you read this - please reformat the code below and &lt;a href="mailto:lars@fosdal.com"&gt;email it to me&lt;/a&gt; as a zipped attachment!  I would also love to receive everybody else's reformatted version as well!&lt;br /&gt;Your anonymity is guaranteed (Unless you explicitly permit me to name you and/or link to a site or something).&lt;br /&gt;&lt;br /&gt;Please note that there was a syntax problem in the original snippet, and I have indicated that below.  I suggest that unless Paul instruct us otherwise, we take out the semi-colon after the end on that line.&lt;pre name="code" class="delphi"&gt;&lt;br /&gt;try&lt;br /&gt;if ConditionA then&lt;br /&gt;Code(1)&lt;br /&gt;else if ConditionB then&lt;br /&gt;if ConditionC then begin&lt;br /&gt;if ConditionD then&lt;br /&gt;code(2);&lt;br /&gt;code(3);&lt;br /&gt;end; // I assume this semi-colon has to go&lt;br /&gt;else if ConditionE then begin&lt;br /&gt;code(4);&lt;br /&gt;morecode('X');&lt;br /&gt;if ConditionF then&lt;br /&gt;code(5)&lt;br /&gt;else if ConditionG then&lt;br /&gt;code(6);&lt;br /&gt;end else begin&lt;br /&gt;code(7);&lt;br /&gt;morecode('Y');&lt;br /&gt;end;&lt;br /&gt;finally&lt;br /&gt;code(8);&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphi.fosdal.com/2008/08/writing-readable-code-pauls-snippet.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-3011273059520091440?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/3011273059520091440/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=3011273059520091440' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3011273059520091440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3011273059520091440'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/writing-readable-code-pauls-snippet_15.html' title='Writing Readable Code - Paul&apos;s Snippet - Show your formatting!'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-4027303616856454975</id><published>2008-08-15T06:31:00.001-07:00</published><updated>2008-08-15T06:32:07.258-07:00</updated><title type='text'>Writing readable code - Comment for Context</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;While waiting for more suggestions to Paul's snippet, and while weaving and dodging through the virtual fireballs from the previous posts on code formatting and comments, I fearlessly continue my Don Quixote Crusade for readable code.  I am not quite done with comments yet.&lt;br /&gt;&lt;br /&gt;It is said that &lt;em&gt;"Real programmers don't write comments - It was hard to write - it should be hard to read"&lt;/em&gt;. That doctrine is way overdue for deletion.&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;h3&gt;&lt;em&gt;&lt;strong&gt;Comments are the context frame of our code.&lt;/strong&gt;&lt;/em&gt;&lt;/h3&gt;&lt;/div&gt;&lt;strong&gt;Comments are like garlic.&lt;/strong&gt;  &lt;br /&gt;Too little and the result is bland and unpalatable, too much and it stinks things up. Comments should only in rare occasions assume that the reader is too dumb to read the code properly, so as a general rule - we should not rewrite our code in plain english, line for line.  Such an approach tend to fog up [sic] the source, and it becomes a drag to maintain (Yeah, I know... garlic metaphors stink...).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Comments are like news headlines.&lt;/strong&gt;&lt;br /&gt;// File ready for saving! &lt;br /&gt;// No more filehandles, says OS &lt;br /&gt;// Raises exception for World+dog &lt;br /&gt;They should be short, concise and to the point.  In good tabloid tradition, they should also only touch on the very general points, and oversimplifying what really is going on.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Comments are like foreplay.&lt;/strong&gt;&lt;br /&gt;They serve to get us readers in the mood to appreciate the sleek lines, the richness of it's properties, and possibly arouse our interest to the point where we are ready to ravage the code.  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Comments are like, bi-se... uh directional.&lt;/strong&gt;&lt;br /&gt;Err, well ... what I am trying to say is that sometimes we can write them before we do stuff, while at other times - it can be just as effective to write them after something has been done in the code.  The first would probably indicate how we are going to do something, while the latter would focus on the result of what we just did. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Pick up the garbage!&lt;/strong&gt;&lt;br /&gt;Do you leave your workshop tools lying about in case you need them quickly, or do you store them safely away?  Once you finalize your code, clean it up.  Put "I deleted this, moved that, added that" comments in your version control commit/check-in comments, and don't litter the source code with it.  Once the code has been created or removed, the reason is uninteresting.  What the code is supposed to do, is so much more valuable information.  Remove unnecessary comments.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Don't spread &lt;a href="http://en.wikipedia.org/wiki/Fear,_uncertainty_and_doubt"&gt;FUD&lt;/a&gt;.&lt;/strong&gt;&lt;br /&gt;Your commentary should embellish the correctness and function of your code, not underline how insecure, unexpectedly behaving, mysterious, or potentially unreliable code it is.  If there is remaining work to be done, that should be written as a To-Do point, containing sufficient information to guide you to a starting point for that work.  &lt;br /&gt;&lt;br /&gt;It takes practice to write good commentary (life-long practice, some would say), but unless your code is totally clear and unambiguous to the point of self-explaining to your grandmother, you should probably add some comments.&lt;br /&gt;&lt;br /&gt;To round it off, here are a couple of disturbing - but funny - comments I have come across in production code:&lt;pre name="code" class="delphi"&gt;&lt;br /&gt;// ---- Better let sleeping dogs lie? Note the date. ----&lt;br /&gt;&lt;br /&gt;  try&lt;br /&gt;    if ValidParentForm(self) &lt;&gt; nil then&lt;br /&gt;    begin&lt;br /&gt;      ValidParentForm(Self).ActiveControl:=NIL;&lt;br /&gt;      //Turn this back on when I return from my holiday and have time to test it &lt;br /&gt;      //N.N. 20.07.2001&lt;br /&gt;      {if ValidParentForm(Self).ActiveControl=lFocusedControl then&lt;br /&gt;        //Control doesn't let go of focus, most likely because of some error message&lt;br /&gt;        exit; //Aborting the routine}&lt;br /&gt;    end;&lt;br /&gt;    if DataSet is TExtendedDataSet then&lt;br /&gt;      TExtendedDataSet(DataSet).Save&lt;br /&gt;    else&lt;br /&gt;      DataSet.Post;&lt;br /&gt;  finally&lt;br /&gt;    . . .&lt;br /&gt;&lt;br /&gt;// ---- Unusual if/then/else construct ----&lt;br /&gt;&lt;br /&gt;   if  (EditSomeProp.Text &lt;&gt; '')&lt;br /&gt;   and ((RequestTable[i].NUMREF+1) &gt; StrToInt(EditSomeProp.Text)) then&lt;br /&gt;   // Watch out for Elsie here&lt;br /&gt;   else&lt;br /&gt;   begin&lt;br /&gt;     . . .&lt;/pre&gt;Should I or should I not uncomment the first comment?  Well, it has been inactive for 7 years, so I think I'll leave it as is, or remove it.  &lt;br /&gt;The second one is history, due to a rewrite.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphi.fosdal.com/2008/08/writing-readable-code-comment-for.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-4027303616856454975?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/4027303616856454975/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=4027303616856454975' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4027303616856454975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4027303616856454975'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/writing-readable-code-comment-for.html' title='Writing readable code - Comment for Context'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-6504313117363787830</id><published>2008-08-15T06:31:00.000-07:00</published><updated>2008-08-15T06:32:01.201-07:00</updated><title type='text'>Writing Readable Code - Paul's Snippet Rewritten</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Five brave people have contributed rewritten versions of Paul's code.  Let's take a look at their approach.&lt;br /&gt;&lt;br /&gt;I reformatted Paul's example using two spaces for every indent level (after then, begin, else, etc. ), hoping that this is the way he originally wrote it.&lt;br /&gt;&lt;br /&gt;IMO, Paul's formatting (or my assumptions about his formatting) does not reflect the true code path, and trying to decipher the code paths become unnecessarily hard.&lt;pre name="code" class="delphi"&gt;  try&lt;br /&gt;    if ConditionA then&lt;br /&gt;      Code(1)&lt;br /&gt;    else if ConditionB then&lt;br /&gt;      if ConditionC then begin&lt;br /&gt;        if ConditionD then&lt;br /&gt;          code(2);&lt;br /&gt;        code(3);&lt;br /&gt;      end&lt;br /&gt;    else if ConditionE then begin&lt;br /&gt;      code(4);&lt;br /&gt;      morecode('X');&lt;br /&gt;      if ConditionF then&lt;br /&gt;        code(5)&lt;br /&gt;      else if ConditionG then&lt;br /&gt;        code(6);&lt;br /&gt;    end else begin&lt;br /&gt;      code(7);&lt;br /&gt;      morecode('Y');&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    code(8);&lt;br /&gt;  end;&lt;/pre&gt;Here is a small exercize. If we say that the string "ABCDEFG" are all conditions TRUE, and the string "abcdefg" are all conditions false: &lt;br /&gt; &amp;bull; What codes are run by "ABCDEFG"?&lt;br /&gt; &amp;bull; What codes are run by "aBcdefg"?&lt;br /&gt; &amp;bull; What string(s) would make code(6) run?&lt;br /&gt;&lt;br /&gt;TS contributed a very nicely formatted version, which is effective in guiding us through the potential code paths. I like his style. &lt;pre name="code" class="delphi"&gt;  try&lt;br /&gt;    if ConditionA then&lt;br /&gt;      Code(1)&lt;br /&gt;    else if ConditionB then&lt;br /&gt;      if ConditionC then&lt;br /&gt;      begin&lt;br /&gt;        if ConditionD then&lt;br /&gt;          code(2);&lt;br /&gt;        code(3);&lt;br /&gt;      end // without the semi-colon&lt;br /&gt;      else if ConditionE then&lt;br /&gt;      begin&lt;br /&gt;        code(4);&lt;br /&gt;        morecode('X');&lt;br /&gt;        if ConditionF then&lt;br /&gt;          code(5)&lt;br /&gt;        else if ConditionG then&lt;br /&gt;          code(6);&lt;br /&gt;      end&lt;br /&gt;      else&lt;br /&gt;      begin&lt;br /&gt;        code(7);&lt;br /&gt;        morecode('Y');&lt;br /&gt;      end;&lt;br /&gt;  finally&lt;br /&gt;    code(8);&lt;br /&gt;  end;&lt;/pre&gt;&lt;br /&gt;SS didn't quite manage to reflect the flow in the code and his formatting is similar to Paul's code.&lt;pre name="code" class="delphi"&gt;  try&lt;br /&gt;    if ConditionA then&lt;br /&gt;      Code(1)&lt;br /&gt;    else if ConditionB then&lt;br /&gt;      if ConditionC then&lt;br /&gt;      begin&lt;br /&gt;        if ConditionD then&lt;br /&gt;          code(2);&lt;br /&gt;        code(3);&lt;br /&gt;      end //; I assume this semi-colon has to go&lt;br /&gt;    else if ConditionE then&lt;br /&gt;    begin&lt;br /&gt;      code(4);&lt;br /&gt;      morecode('X');&lt;br /&gt;      if ConditionF then&lt;br /&gt;        code(5)&lt;br /&gt;      else if ConditionG then&lt;br /&gt;        code(6);&lt;br /&gt;      end&lt;br /&gt;    else&lt;br /&gt;    begin&lt;br /&gt;      code(7);&lt;br /&gt;      morecode('Y');&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    code(8);&lt;br /&gt;  end;&lt;/pre&gt;&lt;br /&gt;Jolyon scores high on restructuring and simplifying, but he made one mistake in his change. Under which condition will his code behave differently form the original?&lt;pre name="code" class="delphi"&gt;  procedure WhenC;&lt;br /&gt;  begin&lt;br /&gt;    if ConditionD then&lt;br /&gt;      code(2);&lt;br /&gt;    code(3);&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  procedure WhenE;&lt;br /&gt;  begin&lt;br /&gt;    code(4);&lt;br /&gt;    morecode('X');&lt;br /&gt;    if ConditionF then&lt;br /&gt;      code(5)&lt;br /&gt;    else if ConditionG then&lt;br /&gt;      code(6);&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;  try&lt;br /&gt;    if ConditionA then&lt;br /&gt;      Code(1)&lt;br /&gt;    else if NOT ConditionB then&lt;br /&gt;      EXIT;&lt;br /&gt;&lt;br /&gt;    if ConditionC then&lt;br /&gt;      WhenC&lt;br /&gt;    else if ConditionE then&lt;br /&gt;      WhenE&lt;br /&gt;    else&lt;br /&gt;    begin&lt;br /&gt;      code(7);&lt;br /&gt;      morecode('Y');&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    code(8);&lt;br /&gt;  end;&lt;/pre&gt;&lt;br /&gt;AO goes even further than Jolyon in reformatting and comments: &lt;em&gt;As I believe that proper formatting is not the only way to increase readability of code, I also refactored it a bit to reduce nesting where possible. If this were an actual code, I would have probably gone even further and introduced separate routines for the individual blocks, depending on their complexity.&lt;/em&gt;&lt;br /&gt;&lt;pre name="code" class="delphi"&gt;  try&lt;br /&gt;    { This comment explains why ConditionA is handled first. }&lt;br /&gt;    if ConditionA then begin&lt;br /&gt;      Code(1);&lt;br /&gt;      Exit;&lt;br /&gt;    end;&lt;br /&gt;  &lt;br /&gt;    { This comment explains why the aggregate of ConditionB and ConditionC is handled next. }&lt;br /&gt;    if ConditionB and ConditionC then begin&lt;br /&gt;      { This comment explains why ConditionD is relevant only in this block. }&lt;br /&gt;      if ConditionD then&lt;br /&gt;        code(2);&lt;br /&gt;  &lt;br /&gt;      code(3);&lt;br /&gt;      Exit;&lt;br /&gt;    end;&lt;br /&gt;  &lt;br /&gt;    { This comment explains why ConditionE is handled next. }&lt;br /&gt;    if ConditionE then begin&lt;br /&gt;      code(4);&lt;br /&gt;      morecode('X');&lt;br /&gt;  &lt;br /&gt;      { This comment explains why ConditionF and ConditionG are relevant only in this block. }&lt;br /&gt;      if ConditionF then&lt;br /&gt;        code(5)&lt;br /&gt;      else if ConditionG then&lt;br /&gt;        code(6);&lt;br /&gt;  &lt;br /&gt;      Exit;&lt;br /&gt;    end;&lt;br /&gt;  &lt;br /&gt;    { This comment explains the default handling. }&lt;br /&gt;    code(7);&lt;br /&gt;    morecode('Y');&lt;br /&gt;  finally&lt;br /&gt;    { This comment explains why the following code must execute no matter what. }&lt;br /&gt;    code(8);&lt;br /&gt;  end;&lt;/pre&gt;&lt;br /&gt;This is readable, but personally I think AO went a bit too far.  Like Jolyon, he also missed a structural detail in the refactoring and broke the code. Which condition state(s) will cause the code to misbehave? &lt;br /&gt;&lt;br /&gt;I am divided on the use of Exit.  It can add clarity, but it can also be a big problem as you leave a lot of code "dangling".  If you decide to move the exit - you have to be really careful to ensure that any states that suddenly move in or out of scope behave correctly.  If there is a nesting church and a chunking church, I'm probably a "Nestorian".&lt;br /&gt;&lt;br /&gt;I do agree that refactoring is a valuable tool to clarify and simplify, and we should make an effort to break down our code into manageable blocks, but in this particular case it probably isn't necessary.&lt;br /&gt;&lt;br /&gt;Another thing: I avoid using {curly braces} for in-code commentary and use // instead.  Why?  Because if you need to comment out code containing &lt;em&gt;select count(*) from table&lt;/em&gt;, those curlies will work where the (* comment *) fail. Should CodeGear add support for comment nesting?  I don't know...&lt;br /&gt;&lt;br /&gt;Anyways...&lt;br /&gt;Here's how I would format the example.  This is very similar to TS's example, except that I showel all the reserved words to the left side to leave the logic more visible and commentable, but I also add indentation to the innermost conditional code.&lt;pre name="code" class="delphi"&gt;  try&lt;br /&gt;    if ConditionA&lt;br /&gt;     then Code(1)&lt;br /&gt;     else if ConditionB&lt;br /&gt;      then if ConditionC&lt;br /&gt;       then begin&lt;br /&gt;         if ConditionD&lt;br /&gt;          then code(2);&lt;br /&gt;         code(3);&lt;br /&gt;       end&lt;br /&gt;       else if ConditionE&lt;br /&gt;        then begin&lt;br /&gt;          code(4);&lt;br /&gt;          morecode('X');&lt;br /&gt;          if ConditionF&lt;br /&gt;           then code(5)&lt;br /&gt;           else if ConditionG&lt;br /&gt;            then code(6);&lt;br /&gt;        end&lt;br /&gt;        else begin&lt;br /&gt;          code(7);&lt;br /&gt;          morecode('Y');&lt;br /&gt;        end;&lt;br /&gt;  finally&lt;br /&gt;    code(8);&lt;br /&gt;  end;&lt;/pre&gt;&lt;br /&gt;MJ adds a contribution with the following comment: &lt;em&gt;"To be sure not to create any future bugs you should consider adding a begin end section after every if statement even if it is not required, but that will make the code more unreadable."&lt;/em&gt;&lt;pre name="code" class="delphi"&gt;  try&lt;br /&gt;    if ConditionA then&lt;br /&gt;      Code(1)&lt;br /&gt;    else if ConditionB then&lt;br /&gt;    begin&lt;br /&gt;      if ConditionC then&lt;br /&gt;      begin&lt;br /&gt;        if ConditionD then&lt;br /&gt;          code(2);&lt;br /&gt;        code(3);&lt;br /&gt;      end&lt;br /&gt;      else if ConditionE then&lt;br /&gt;      begin&lt;br /&gt;        code(4);&lt;br /&gt;        morecode('X');&lt;br /&gt;        if ConditionF then&lt;br /&gt;          code(5)&lt;br /&gt;        else if ConditionG then&lt;br /&gt;          code(6);&lt;br /&gt;      end&lt;br /&gt;      else&lt;br /&gt;      begin&lt;br /&gt;        code(7);&lt;br /&gt;        morecode('Y');&lt;br /&gt;      end;&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    code(8);&lt;br /&gt;  end;&lt;/pre&gt;&lt;br /&gt;Good Points! In all honesty, I also screwed up the code blocks on first try.  Conditional code will bite you if you are not very very careful.  You should indeed think about what may happen if you need to add more code and/or conditions.  Personally, I don't think a few more enclosures makes the code less readable.  Here is how I would be more explicit in the use of enclosures to make the code less ambiguous.&lt;pre name="code" class="delphi"&gt;  try&lt;br /&gt;    if ConditionA&lt;br /&gt;     then Code(1)&lt;br /&gt;    else begin&lt;br /&gt;      if ConditionB&lt;br /&gt;      then begin&lt;br /&gt;        if ConditionC&lt;br /&gt;        then begin&lt;br /&gt;          if ConditionD&lt;br /&gt;           then code(2);&lt;br /&gt;          code(3);&lt;br /&gt;        end&lt;br /&gt;        else begin&lt;br /&gt;          if ConditionE&lt;br /&gt;          then begin&lt;br /&gt;            code(4);&lt;br /&gt;            morecode('X');&lt;br /&gt;            if ConditionF&lt;br /&gt;             then code(5)&lt;br /&gt;             else if ConditionG&lt;br /&gt;              then code(6);&lt;br /&gt;          end&lt;br /&gt;          else begin&lt;br /&gt;            code(7);&lt;br /&gt;            morecode('Y');&lt;br /&gt;          end;&lt;br /&gt;        end;&lt;br /&gt;      end;&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    code(8);&lt;br /&gt;  end;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;There is no one true correct way of formatting.&lt;/strong&gt;  &lt;br /&gt;The point I am trying to make is that code structure matter for understanding the code at first glance, and we should be mindful about how we lay it out.  We should strive for consistency, but always keep clarity and unambiguity as priority one.  Bend your rules, if you need to.&lt;br /&gt;&lt;br /&gt;Paul, Thank you for creating such a devious code snippet!&lt;br /&gt;&lt;br /&gt;P.S. If you haven't figured out the answers yet, load up your Delphi and &lt;a href="http://public.fosdal.com/StructureDemo.dpr"&gt;run all the examples in StructureDemo.dpr&lt;/a&gt;.&lt;br /&gt;&lt;strong&gt;No peeking until you have some suggestions!&lt;/strong&gt; :)&lt;br /&gt;(Hint: else starts a new block)&lt;br /&gt;&lt;br /&gt;Edit: Added an example of using Exits instead of nesting to the &lt;a href="http://delphi.fosdal.com/2008/08/writing-readble-code-formatting-and.html"&gt;initial post on formatting&lt;/a&gt;. It would be interesting to see DelphiFreak have a go at Paul's snippet.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphi.fosdal.com/2008/08/writing-readable-code-pauls-snippet_07.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-6504313117363787830?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/6504313117363787830/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=6504313117363787830' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6504313117363787830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6504313117363787830'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/writing-readable-code-pauls-snippet.html' title='Writing Readable Code - Paul&apos;s Snippet Rewritten'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-5008144399598251862</id><published>2008-08-13T18:31:00.008-07:00</published><updated>2008-08-13T19:57:17.835-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Latest Tiburón Preview</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;p&gt;I was a little disappointed that the preview webinar this morning was little more than a re-run of the same content from a little over a week ago, albeit with some downloadable PowerPoint slides this time.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It was at least an opportunity for some more Q&amp;amp;A and a couple of interesting Q&amp;#8217;s got A&amp;#8217;d.&lt;br /&gt;&lt;br /&gt;&lt;span id="more-180"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;1. Generics Support For Event Types&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;In my series of &lt;a href="http://www.deltics.co.nz/blog/?tag=multicast-events" target="_blank"&gt;posts on multicast events&lt;/a&gt; I speculated that if generics support included using event types as parameters then things could be made a little easier. &lt;a href="http://blogs.codegear.com/davidi/2008/08/12/38921/" target="_blank"&gt; David I&lt;/a&gt; demonstrated that it does appear to be possible:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;  TEventList = TList&amp;lt;TNotifyEvent&amp;gt;;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;So it appears that in a future D2009 revision of my multicast events implementation we should be able to write:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;  TMultiCastNotify = TMultiCast&amp;lt;TNotifyEvent&amp;gt;;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;It won&amp;#8217;t, as far as I can tell, eliminate &lt;span style="text-decoration: underline;"&gt;all&lt;/span&gt; the work in deriving a new multicast event class, but it will remove the drudgery of implementing &lt;em&gt;Add()&lt;/em&gt; and &lt;em&gt;Remove()&lt;/em&gt; methods, at the very least.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;2. Release Timeframe&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;In response to the inevitable questions about when it (Delphi 2009) will be released, the stock response is still &amp;#8220;&lt;em&gt;When it&amp;#8217;s ready&lt;/em&gt;&amp;#8220;.  The supplemental question &amp;#8220;&lt;em&gt;When will it be ready?&lt;/em&gt;&amp;#8221; triggered a stack overflow exception:&lt;em&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Q. When will it be ready?&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;A. When it&amp;#8217;s ready.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Q. Cool, so when will it be ready?&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;A. When it&amp;#8217;s ready.&lt;br /&gt;&lt;br /&gt;etc&lt;/p&gt;&lt;br /&gt;&lt;p&gt; &lt;img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;However, it was mentioned that these preview webinars will continue on a weekly basis through to the end of September.  So I think it&amp;#8217;s not unreasonable that we might optimistically hope for an October timeframe for an actual release.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;3. Ribbon is &lt;span style="text-decoration: line-through;"&gt;Not&lt;/span&gt; Entirely VCL Code&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;At the previous preview I got the distinct impression that the ribbon control support was entirely CodeGear VCL code.  This time around it was mentioned that it is a VCL wrapper around Microsoft code.  I&amp;#8217;m not sure that this is particularly important one way or the other, but some people might find it interesting.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href="http://blogs.codegear.com/nickhodges/" target="_blank"&gt;Nick Hodges&lt;/a&gt; (Delphi Product Manager, so he should know) has clarified that there is in fact no wrapper or Microsoft code involved, only VCL code.&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;What was certainly interesting was the indication that if you use the ribbon control in an application then you will need to obtain &lt;a href="http://msdn.microsoft.com/en-us/office/aa973809.aspx" target="_blank"&gt;a ribbon UI license&lt;/a&gt; from Microsoft to then deploy that application.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This in itself is already controversial and &lt;a href="http://weblogs.asp.net/fbouma/archive/2008/07/20/the-evil-of-the-office-ui-ribbon-license.aspx" target="_blank"&gt;one school of thought&lt;/a&gt; has it that the license is not only undesirable, but quite possibly unenforceable.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;4. No Generics Enrichments in the VCL&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;Apart from the Generics.Collections support, the VCL itself has not been enriched with generics support.  I find this surprising.  It strikes me that it should have been quite straightforward to enable us to write:&lt;/p&gt;&lt;br /&gt;&lt;pre class="delphi"&gt;TCustomerComboBox = TComboBox&amp;lt;TCustomer&amp;gt;;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;To create type-safe access to the data associated with the items in a combobox, for example.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It should be relatively easy to create these extensions ourselves, but it would have been nice to have that support built in to the VCL.  Having said that, design-time support would have been a bit difficult I suppose.  i.e. dropping a regular combo-box on a form and then specifying the type of the items data via the property inspector.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;5. Insight Into the Interested Customer Base&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;Aside from the information on Tiburon itself, the QA provided an interesting insight into the parts of the community that are actively interested in Delphi 2009.  Some of the questions appeared to demonstrate a lack of familiarity with more recent changes in the language, such as support for dotted unit names (&lt;em&gt;Delphi 7&lt;/em&gt;) and strict private visibility (&lt;em&gt;Delphi 2006&lt;/em&gt;, I think).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I am not ridiculing the people that asked those questions.  Far from it.  I think it is positively encouraging that users who - it would appear - were perhaps previously &amp;#8220;left behind&amp;#8221; are once again interested in this new version of Delphi.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It reinforces a general impression that I am increasingly forming, that a new spark of life has appeared in the Delphi community.&lt;/p&gt;&lt;br /&gt;&lt;p&gt; &lt;img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /&gt; &lt;/p&gt;&lt;br /&gt;&lt;h3&gt;More To Come&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;As mentioned, it appears there will be &lt;a href="http://blogs.codegear.com/davidi/2008/08/12/38921/" target="_blank"&gt;more previews to come&lt;/a&gt;, on a weekly basis.  The schedule currently only runs to the end of August, not September, but whether David I misspoke or the full schedule simply isn&amp;#8217;t finalised yet, I don&amp;#8217;t know.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;For local visitors, the 11am PDT time slot is 6am the following day in &amp;#8220;Auckland Time&amp;#8221;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The future is bright.  The future is Delphi.&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&lt;tr&gt;&lt;td valign=top&gt;&lt;b&gt;Keyword&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Delphi&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://www.deltics.co.nz/blog/?p=180" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-5008144399598251862?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/5008144399598251862/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=5008144399598251862' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5008144399598251862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5008144399598251862'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/latest-tiburn-preview.html' title='Latest Tiburón Preview'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-3219002569510417916</id><published>2008-08-13T18:31:00.007-07:00</published><updated>2008-08-13T18:35:01.756-07:00</updated><title type='text'>Vonage  calling from ObjectPascal</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Last week, a customer asked if he could call using his &lt;a href="http://www.vonage.com"&gt;Vonage&lt;/a&gt; phone to call from an application I developed some time ago. After searching for a way to do this, I stumbled upon this &lt;a href="https://secure.click2callu.com/"&gt;tutorial&lt;/a&gt;, then adapted the examples to ObjectPascal. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The results&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The first problem I found was how to connect to an HTTPS site. Of course the answer was &lt;a href="http://synapse.ararat.cz"&gt;Synapse&lt;/a&gt; with the help of &lt;a href="www.openssl.org"&gt;OpenSSL&lt;/a&gt; libraries.&lt;br /&gt;&lt;br /&gt;I created couple of small functions that first log in to a Vonage account, then place the call. The functions are contained in this unit:&lt;br /&gt;&lt;br /&gt;&lt;pre class="pas-source"&gt;&lt;span class="pas-kwd"&gt;unit&lt;/span&gt; vonagecall;&lt;br /&gt;&lt;br /&gt;&lt;span class="pas-kwd"&gt;interface&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="pas-comment"&gt;(* Calls to Vonage phone *)&lt;/span&gt;&lt;br /&gt;&lt;span class="pas-kwd"&gt;function&lt;/span&gt; CallToVonage(AUserName, APassword, AFromNumber, AToNumber: &lt;span class="pas-kwd"&gt;string&lt;/span&gt;): &lt;span class="pas-kwd"&gt;string&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="pas-kwd"&gt;implementation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="pas-kwd"&gt;uses&lt;/span&gt;&lt;br /&gt;  Classes,&lt;br /&gt;  ssl_openssl,&lt;br /&gt;  httpsend;&lt;br /&gt;&lt;br /&gt;&lt;span class="pas-kwd"&gt;function&lt;/span&gt; GetVonageNumbers(AUserName, APassword: &lt;span class="pas-kwd"&gt;string&lt;/span&gt;): &lt;span class="pas-kwd"&gt;string&lt;/span&gt;;&lt;br /&gt;&lt;span class="pas-comment"&gt;(* This function must be allways called from CallToVonage *)&lt;/span&gt;&lt;br /&gt;&lt;span class="pas-kwd"&gt;var&lt;/span&gt;&lt;br /&gt;  lHttp: THTTPSend;&lt;br /&gt;  lParams: &lt;span class="pas-kwd"&gt;string&lt;/span&gt;;&lt;br /&gt;  lResponse: TStringStream;&lt;br /&gt;&lt;span class="pas-kwd"&gt;begin&lt;/span&gt;&lt;br /&gt;  Result := &lt;span class="pas-str"&gt;''&lt;/span&gt;;&lt;br /&gt;  lHttp := THTTPSend.Create;&lt;br /&gt;  lResponse := TStringStream.Create(&lt;span class="pas-str"&gt;''&lt;/span&gt;);&lt;br /&gt;  &lt;span class="pas-kwd"&gt;try&lt;/span&gt;&lt;br /&gt;    lParams := &lt;span class="pas-str"&gt;'username='&lt;/span&gt; + AUserName;&lt;br /&gt;    lParams := lParams + &lt;span class="pas-str"&gt;'&amp;amp;password='&lt;/span&gt; + APassword;&lt;br /&gt;    &lt;span class="pas-comment"&gt;(* Get Phone numbers *)&lt;/span&gt;&lt;br /&gt;    lHttp.HTTPMethod(&lt;span class="pas-str"&gt;'GET'&lt;/span&gt;, &lt;span class="pas-str"&gt;'https://secure.click2callu.com/tpcc/getnumbers?'&lt;/span&gt; + lParams);&lt;br /&gt;    lHttp.Document.SaveToStream(lResponse);&lt;br /&gt;    Result := lResponse.DataString;&lt;br /&gt;    &lt;span class="pas-kwd"&gt;if&lt;/span&gt; Pos(&lt;span class="pas-str"&gt;':'&lt;/span&gt;, Result) &amp;gt; &lt;span class="pas-num"&gt;0&lt;/span&gt; &lt;span class="pas-kwd"&gt;then&lt;/span&gt;&lt;br /&gt;      Result := &lt;span class="pas-str"&gt;'Failed to retrieve Vonage phone numbers. Check your username and password.'&lt;/span&gt;;&lt;br /&gt;  &lt;span class="pas-kwd"&gt;finally&lt;/span&gt;&lt;br /&gt;    lResponse.Free;&lt;br /&gt;    lHttp.Free;&lt;br /&gt;  &lt;span class="pas-kwd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;span class="pas-kwd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="pas-kwd"&gt;function&lt;/span&gt; CallToVonage(AUserName, APassword, AFromNumber, AToNumber: &lt;span class="pas-kwd"&gt;string&lt;/span&gt;): &lt;span class="pas-kwd"&gt;string&lt;/span&gt;;&lt;br /&gt;&lt;span class="pas-comment"&gt;(* This makes the real call *)&lt;/span&gt;&lt;br /&gt;&lt;span class="pas-kwd"&gt;var&lt;/span&gt;&lt;br /&gt;  lHttp: THTTPSend;&lt;br /&gt;  lParams: &lt;span class="pas-kwd"&gt;string&lt;/span&gt;;&lt;br /&gt;  lResponse: TStringStream;&lt;br /&gt;&lt;span class="pas-kwd"&gt;begin&lt;/span&gt;&lt;br /&gt;  Result := &lt;span class="pas-str"&gt;''&lt;/span&gt;;&lt;br /&gt;  lHttp := THTTPSend.Create;&lt;br /&gt;  lResponse := TStringStream.Create(&lt;span class="pas-str"&gt;''&lt;/span&gt;);&lt;br /&gt;  &lt;span class="pas-kwd"&gt;try&lt;/span&gt;&lt;br /&gt;    lParams := &lt;span class="pas-str"&gt;'username='&lt;/span&gt; + AUserName;&lt;br /&gt;    lParams := lParams + &lt;span class="pas-str"&gt;'&amp;amp;password='&lt;/span&gt; + APassword;&lt;br /&gt;    lParams := lParams + &lt;span class="pas-str"&gt;'&amp;amp;fromnumber='&lt;/span&gt; + AFromNumber;&lt;br /&gt;    lParams := lParams + &lt;span class="pas-str"&gt;'&amp;amp;tonumber='&lt;/span&gt; + AToNumber;&lt;br /&gt;    GetVonageNumbers(AUserName, APassword);&lt;br /&gt;    lHttp.HTTPMethod(&lt;span class="pas-str"&gt;'GET'&lt;/span&gt;, &lt;span class="pas-str"&gt;'https://secure.click2callu.com/tpcc/makecall?'&lt;/span&gt; + lParams);&lt;br /&gt;    lHttp.Document.SaveToStream(lResponse);&lt;br /&gt;    Result := lResponse.DataString;&lt;br /&gt;  &lt;span class="pas-kwd"&gt;finally&lt;/span&gt;&lt;br /&gt;    lResponse.Free;&lt;br /&gt;    lHttp.Free;&lt;br /&gt;  &lt;span class="pas-kwd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;span class="pas-kwd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;span class="pas-kwd"&gt;end&lt;/span&gt;.&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The unit requires you to deploy libeay32.dll and ssleay32.dll, you can download these files from OpenSSL.org project. There are Windows and Linux versions.&lt;br /&gt;&lt;br /&gt;To use it, just include the &lt;span style="font-weight:bold;"&gt;vonagecall&lt;/span&gt; unit in the &lt;span style="font-weight:bold;"&gt;uses&lt;/span&gt; of your program and call the function CallToVonage passing UserName, Password, FromNumber and ToNumber parameters.&lt;br /&gt;&lt;br /&gt;In this &lt;a href="http://www.geocities.com/martinrame/vonage.zip"&gt;zip file&lt;/a&gt;, I packaged everything you need to test the function.&lt;br /&gt;&lt;br /&gt;Hasta la próxima!&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://leonardorame.blogspot.com/2008/03/vonage-calling-from-objectpascal.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-3219002569510417916?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/3219002569510417916/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=3219002569510417916' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3219002569510417916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3219002569510417916'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/vonage-calling-from-objectpascal.html' title='Vonage  calling from ObjectPascal'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7233263441499625568</id><published>2008-08-13T18:31:00.006-07:00</published><updated>2008-08-13T18:34:59.541-07:00</updated><title type='text'>Developing Office Add-ins the Easy Way - Part 2 of 2 (AKA: The tutorial stuff...)</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;p&gt;If you haven't read &lt;a title="Blah, Blah, Blah" href="http://memyselfanddelphi.blogspot.com/2007/06/developing-office-add-ins-easy-way-part.html"&gt;Part 1&lt;/a&gt;, I'd advise you to do so. In it you'll find some more information on these components and, more importantly, your &lt;strong&gt;20% discount coupon&lt;/strong&gt; redeemable until the end of June 2007...&lt;/p&gt; &lt;h4&gt;Step 1: Running the new Add-In Wizard&lt;/h4&gt; &lt;ol&gt; &lt;li&gt;Fire up Delphi and choose File-&amp;gt;New-&amp;gt;Other, Delphi Projects-&amp;gt;Add-In Express VCL-&amp;gt;ADX Outlook Add-in.  &lt;/li&gt;&lt;li&gt;Click Next and, for the project name, I'm using &lt;strong&gt;Insider&lt;/strong&gt; and &lt;strong&gt;coInsider&lt;/strong&gt; for the coClass Name. The first is used, guess what?, for the Project's name and the 2nd is used in Outlook's COM Addins dialog (Tools-&amp;gt;Options-&amp;gt;Other-&amp;gt;Advanced Options) &lt;/li&gt;&lt;li&gt;Clicking next will show you the "Option Pages" step which is optional.  &lt;ul&gt; &lt;li&gt;For this addin we'll just hit next again. For a more complex add-in, this would be where you'd create your own option pages. You can have option pages displayed as another tab on the Options dialog or by right-clicking all or some folders in outlook, say one for Inbox, other for Outbox: they are different types of dialogs serving different purposes and you can add as many as you like.&lt;/li&gt;&lt;/ul&gt; &lt;/li&gt;&lt;li&gt;Hit next again and we'll be in the "Outlook 2007 Task Panes"; again, not of interest to us here so move along.  &lt;/li&gt;&lt;li&gt;Click Next, Finish and we're done here.&lt;/li&gt;&lt;/ol&gt; &lt;h4&gt;Step 1.5: More blah, blah, blah...&lt;/h4&gt; &lt;p&gt;We now have a basic project that we'll add some meat to in order for it to do what we set out to. We could easily add an explorer or inspector command bar, but we don't need them for this project. An explorer command bar is one that is displayed on Outlook; an inspector command bar is displayed when you double-click some outlook item and "inspect" it in it's own window. Say, when you double click an e-mail message and another window pops up. You can have the inspector command bars only display for certain types of folders by simply setting a property, say, create an e-mail inspector bar that is displayed only when inspecting a mail message but not when viewing an appointment. And, of course, you can add as many as you want and add buttons, menus and other controls to them at will.&lt;/p&gt; &lt;p&gt;Among other cool objects you can use (not needed for this add-in), are the TADX&amp;lt;AppNameHere&amp;gt;AppEvents, such as TADXOutlookAppEvents from where you can add your own handlers. Here's the list of OutlookAppEvents (these are global events: other components have their own events as well, but these are events that don't relate to a particular button being pressed or hotkey being used):&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_H01pb6FTsXo/RnF4R7Lu8KI/AAAAAAAAAE8/BTgIvJBiZSY/s1600-h/Bugger.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_H01pb6FTsXo/RnF4R7Lu8KI/AAAAAAAAAE8/BTgIvJBiZSY/s320/Bugger.png" alt="" id="BLOGGER_PHOTO_ID_5075970504363274402" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;OnItemSend&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;OnNewMail&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;OnNewMailEx&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;OnQuit&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;OnReminderFire&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;OnStartup&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt; &lt;p&gt;BTW: Thanks to blogger messing up my formatting big-time, I had to shorten the list to just a few sample items so as not to have a whole lot of space wasted. Maybe I'll take a prt-scr later and update this...&lt;/p&gt; &lt;h4&gt;Step 2: Adding some components and code&lt;/h4&gt; &lt;ol&gt; &lt;li&gt;What we are now going to add is an "ADX Outlook Form" which is a small pane where we will be displaying the headers of the selected message, so go to File-&amp;gt;New-&amp;gt;Other, Delphi Projects-&amp;gt;Add-In Express VCL and double click "ADX Outlook Form".  &lt;/li&gt;&lt;li&gt;Save the form (I used &lt;strong&gt;uHeader&lt;/strong&gt; for the unit name).  &lt;/li&gt;&lt;li&gt;Add a TListBox, call it &lt;strong&gt;lbxHeader&lt;/strong&gt; and set it to fill the form.  &lt;/li&gt;&lt;li&gt;We need another component to control creation of these panes. Go on to the main project form (should be empty) and add a "TadxOlFormsManager".  &lt;/li&gt;&lt;li&gt;In this component's events, add the following code to the "OnADXBeforeFormInstanceCreateEx" event:  &lt;pre  style="color:white;"&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; args.FolderObj.EntryID &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; OutboxEntryID &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  args.Cancel :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; true;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;/pre&gt; &lt;/li&gt;&lt;li&gt;Let's add that OutboxEntryID as a protected property to the form (TAddInModule) of type string:  &lt;pre  style="color:white;"&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;property OutboxEntryID: string read FOutboxEntryID;&lt;/span&gt;&lt;/pre&gt; &lt;/li&gt;&lt;li&gt;And the corresponding internal field to the private section of TAddInModule:  &lt;pre  style="color:white;"&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;FOutboxEntryID: string;&lt;/span&gt;&lt;/pre&gt; &lt;/li&gt;&lt;li&gt;And a method to set the value in the protected section (not a setter method though!):  &lt;ul&gt;&lt;/ul&gt;&lt;pre  style="color:white;"&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;procedure&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; SetOutboxEntryID;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;procedure&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; TAddInModule.SetOutboxEntryID;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 4&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 5&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  nameSpace   : Outlook2000.NameSpace;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 6&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  outboxFolder: Outlook2000.MAPIFolder;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 7&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 8&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;try&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 9&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    nameSpace      :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; OutlookApp  .GetNamespace    ( &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;MAPI&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;         );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;10&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    outboxFolder   :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; nameSpace   .GetDefaultFolder( olFolderOutbox );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;11&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    FOutboxEntryID :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; outboxFolder.EntryID;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;12&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;finally&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;13&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    nameSpace    :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;nil&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;14&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    outboxFolder :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;nil&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;15&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;16&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;/pre&gt; &lt;/li&gt;&lt;li&gt;Now click the form and enter the following code to it's "&lt;strong&gt;OnAddInInitialize&lt;/strong&gt;" event:&lt;br /&gt;&lt;pre  style="color:white;"&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;SetOutboxEntryID();&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Finally, let's give the &lt;strong&gt;TadxOlFormsManager&lt;/strong&gt; something to manage: double click it and add a new item. Set the following properties for that item:&lt;/li&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;ExplorerItemTypes&lt;/strong&gt;-&amp;gt;&lt;strong&gt;expMailItem&lt;/strong&gt;, set to &lt;strong&gt;True&lt;/strong&gt; as we want this form displayed on mail folders only; leave all others to false. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;ExplorerLayout&lt;/strong&gt; set to &lt;strong&gt;elTopSubpane&lt;/strong&gt;; (you can play around with it later if you want!) &lt;/li&gt;&lt;li&gt;And finally, let's link it to the form we created above: set &lt;strong&gt;FormClassName&lt;/strong&gt; to our form created above. It will be available on the drop down as soon as you go into &lt;strong&gt;File-&amp;gt;Use Unit&lt;/strong&gt; and select our uHeader unit.&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt; &lt;p&gt;If you build the project, register it and launch outlook, you'll see a blank new pane displayed: Sorry for the large, dimmed and blurred image: it's from my main outlook... :)&lt;/p&gt; &lt;p&gt;&lt;a href="http://fmadsoft.com/mmd/images/DevelopingOfficeAddinstheeasywayPart2of_EF99/EmptyFrame2.png" atomicselection="true"&gt;&lt;img style="border: 0px none ;" src="http://fmadsoft.com/mmd/images/DevelopingOfficeAddinstheeasywayPart2of_EF99/EmptyFrame_thumb.png" border="0" height="140" width="240" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Also, if you notice, so far most of the code was related to adding an exception, that is, we wanted our form to display on mail folders, &lt;strong&gt;unless&lt;/strong&gt; that folder is Outbox.&lt;/p&gt; &lt;p&gt;Now it's time to add our real meat into this.&lt;/p&gt; &lt;h4&gt;Step 3: Adding our application logic&lt;/h4&gt; &lt;ol&gt; &lt;li&gt;Lets go back to our &lt;strong&gt;uHeader&lt;/strong&gt; unit and add the following code to the &lt;strong&gt;onADXSelectionChange&lt;/strong&gt; event:&lt;br /&gt;&lt;pre  style="color:white;"&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;procedure&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; TfrmHeader.adxOlFormADXSelectionChange( Sender: TObject );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  Selection: Outlook2000.Selection;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 4&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  IMail    : _MailItem;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 5&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  IMessage : MAPIDefs.IMessage;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 6&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  PropValue: PSPropValue;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 7&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 8&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  lbxHeader.Items.Clear;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 9&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  Selection :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Self.ExplorerObj.Selection;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;10&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  IMail     :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;nil&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;11&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Selection.Count &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;12&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;try &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Try for a "normal" mail item&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;13&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      Selection.Item(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).QueryInterface( IID__MailItem, IMail );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;14&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;not&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Assigned( IMail ) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;15&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  //&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; If it failed, try for a Read/Delivery Receipt item&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;16&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;        Selection.Item(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).QueryInterface( IID__ReportItem, IMail );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;17&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;18&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;not&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Assigned( IMail ) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;19&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  //&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; I don't use Remote Mail, but for completeness this should be tested also...&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;20&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;        Selection.Item(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).QueryInterface( IID__RemoteItem, IMail );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;21&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;22&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;except&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Ignore exceptions&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;23&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; QueryInterface may throw up an exception, but I don't recall under what condition it was&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;24&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; It was for some non-&gt;relevant item, i.e., one that we're not processing here&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;25&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; That's the bad thing of writing something and not documenting it properly when it happens!&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;26&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;27&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Assigned(IMail) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;28&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;try&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;29&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; IMail.Sent &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;30&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;          IMail.MAPIOBJECT.QueryInterface(MapiDefs.IMessage, IMessage);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;31&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Assigned(IMessage) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;32&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;try&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;33&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;              PropValue :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;nil&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;34&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;              &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; HrGetOneProp(IMessage, PR_TRANSPORT_MESSAGE_HEADERS, PropValue) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; S_OK &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;35&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;                StringToList( PropValue^.Value.lpszA, lbxHeader.Items );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;36&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;              &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;37&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;finally&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;38&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;              MAPIFreeBuffer(PropValue);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;39&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;              IMessage :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;nil&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;40&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;41&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;42&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;43&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;finally&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;44&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;        IMail :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;nil&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;45&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;46&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; If no headers found...&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;47&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      lbxHeader.Items.Add( &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;This type of message does&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;48&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      lbxHeader.Items.Add( &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;not have mail headers&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;49&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;50&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;51&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;/pre&gt; &lt;/li&gt;  &lt;li&gt;Now let's add the MAPI units to our project and to the uses clause in this form:&lt;br /&gt;&lt;pre  style="color:white;"&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;uses&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; MapiDefs, MapiTags, MAPIUtil;&lt;/span&gt;&lt;/pre&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Now all that is left is to add that &lt;strong&gt;StringToList&lt;/strong&gt; function I used to process the semi-colon formatted mail headers into a more readable list:&lt;br /&gt;&lt;pre  style="color:white;"&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;procedure&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; StringToList( Str: string; lstResult: TStrings );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Convert a header string containing CR/LFs and TABs into&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; a stringlist where each new property starts on a new line&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 4&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 5&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  iPos : integer;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 6&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;const&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 7&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  CRLF &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; #&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;13&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;#&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;10&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 8&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 9&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  lstResult.Clear;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;10&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  iPos :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Pos( CRLF, Str );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;11&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (iPos &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;and&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (iPos &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (Length( Str )&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) ) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;do&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;12&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; If the new line starts with a Space or Tab, it's a continuation line&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;13&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (Str[iPos&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;] &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; #&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;9&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;or&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (Str[iPos&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;] &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; #&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;32&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;14&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      Delete( Str, iPos, &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;15&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;begin&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;16&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      lstResult.Add( Copy( Str, &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, Pred(iPos) ) );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;17&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;      Delete( Str, &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, Succ( iPos ) );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;18&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;19&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    iPos :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Pos( CRLF, Str );&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;20&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;21&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt; &lt;/ol&gt; &lt;h4&gt;And we're done!&lt;/h4&gt; &lt;p&gt;Just build again, and re-launch outlook and you'll have something like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://fmadsoft.com/mmd/images/DevelopingOfficeAddinstheeasywayPart2of_EF99/FilledFrame2.png" atomicselection="true"&gt;&lt;img style="border: 0px none ;" src="http://fmadsoft.com/mmd/images/DevelopingOfficeAddinstheeasywayPart2of_EF99/FilledFrame_thumb.png" border="0" height="140" width="240" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;h4&gt;Final thoughts and notes:&lt;/h4&gt; &lt;ol&gt; &lt;li&gt;Don't forget that you can &lt;span style="font-weight: bold;"&gt;regsvr32 dlllname.dll&lt;/span&gt; or &lt;span style="font-weight: bold;"&gt;regsvr32 -u dllname.dll&lt;/span&gt; and any installer will do that for you if you mark the dll as self-registering.&lt;/li&gt; &lt;li&gt;Don't forget that you'll need to close the application you're testing/compiling your add-in for, before you can compile it as the dll will be in use! :)&lt;/li&gt; &lt;li&gt;If you look back, you'll see that you pratically never knew you were handling COM objects and that most of the code was for the application logic with part of the complexity in that arising from using Extended Mapi because Outlook's object model is a bit limited in some places... Creating Excel add-ins is even easier as you don't have to deal with Extended Mapi! ;) You will require some knowledge of the application's Object Model, but that comes out of the box in the form of some VBA help files that you can install with your Office.&lt;/li&gt;&lt;li&gt;I didn't show in this simple demo two other easy to implement features, mostly out of lazyness: adding toolbars/buttons/menus and option pages. Trust me (or don't trust and instead try for yourself!): those are very easy to implement!&lt;br /&gt;&lt;/li&gt; &lt;li&gt;Don't forget to take advantage of the &lt;strong&gt;20% discount&lt;/strong&gt; coupon (see &lt;a title="Blah, Blah, Blah" href="http://memyselfanddelphi.blogspot.com/2007/06/developing-office-add-ins-easy-way-part.html"&gt;Part 1&lt;/a&gt;), and have fun Developing Office Add-ins the Easy Way!&lt;/li&gt;&lt;li&gt;Syntax highlighting done using Steve Trefethen's &lt;a href="http://www.stevetrefethen.com/highlighter/default.aspx"&gt;Syntax Highlighter&lt;/a&gt; and then manually tweaked the generated HTML to fix some coloring bugs.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://memyselfanddelphi.blogspot.com/2007/06/developing-office-add-ins-easy-way-part_14.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7233263441499625568?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7233263441499625568/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7233263441499625568' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7233263441499625568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7233263441499625568'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/developing-office-add-ins-easy-way-part.html' title='Developing Office Add-ins the Easy Way - Part 2 of 2 (AKA: The tutorial stuff...)'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_H01pb6FTsXo/RnF4R7Lu8KI/AAAAAAAAAE8/BTgIvJBiZSY/s72-c/Bugger.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-4583431771645883897</id><published>2008-08-13T18:31:00.005-07:00</published><updated>2008-08-13T18:34:37.581-07:00</updated><title type='text'>Help needed with PDF Processing Library...</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;p&gt;After two days of searching, clicking through hundreds of links, downloading tens of files, trying, browsing, etc, I decided it was about time to give up and ask for help!&lt;/p&gt; &lt;p&gt;I need to process some PDFs, mostly "black-and-whitening" them, that is, converting color boxes and text into black and white. It's not the same as "printing" in black and white though, as I want to replace boxes filled with some color with ones with no color fills and change the corresponding white or light colored text with black text.&lt;/p&gt; &lt;p&gt;Example:&lt;/p&gt; &lt;p&gt;From this:&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="161" alt="Source" src="http://lh6.google.com/Fotos.Madrugas/R5Pbv5xbg-I/AAAAAAAAAR4/ygknKtDkBFE/image%5B9%5D" width="200" border="0"&gt; to this: &lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="161" alt="Destination" src="http://lh4.google.com/Fotos.Madrugas/R5PbwZxbg_I/AAAAAAAAASA/r6YKCGi5cMg/image%5B8%5D" width="200" border="0"&gt; &lt;/p&gt; &lt;p&gt;I'd like to do this in Delphi, but I can do in a million other languages such as Perl, PHP, Python, Java, C# or whatever. I have one restriction though: the library has to be either free or open-source, but this restriction can be waived if there's nothing free or open-source that I can use to solve the problem...&lt;/p&gt; &lt;p&gt;Does anyone know of a library that will allow me to do that? Open a PDF file, loop through all the objects and change characteristics as I see fit, and finally saving the edited file&lt;/p&gt; &lt;p&gt;If you know such a library/tool, please leave a comment... Thank you.&lt;/p&gt;  &lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://memyselfanddelphi.blogspot.com/2008/01/help-needed-with-pdf-processing-library.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-4583431771645883897?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/4583431771645883897/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=4583431771645883897' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4583431771645883897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4583431771645883897'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/help-needed-with-pdf-processing-library.html' title='Help needed with PDF Processing Library...'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1661843880853288430</id><published>2008-08-13T18:31:00.004-07:00</published><updated>2008-08-13T18:34:10.010-07:00</updated><title type='text'>Holidays</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Anyone else out there ever run into the need for a simple little list of holidays? I do a fair amount of stuff that involves questions like "Are we off on such and such a day?" where you have to figure out, "When is Easter this year anyway?" That's pretty easy if you look it up on a calendar. Now try doing that in code.&lt;br /&gt;&lt;br /&gt;At any rate, I wrote a tiny little class to provide some basic holidays out. Help yourself to the code, it's not complicated, just annoying. The biggest trick is &lt;span style="font-weight:bold;"&gt;finding&lt;/span&gt; the information in the first place. This is US-oriented, but I'd be glad to extended it if someone wants some other days in there. It would be helpful if you could provide the holiday information you're interested in though (i.e., My Personal Holiday is the 3rd Tuesday of May or whatever). Oh, one last caveat. If the date doesn't appear (like Inauguration day), the DateTime will be a 0. That's fine for comparisons, but if you just do a dump of the dates, it gives you 1899.&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;unit&lt;/span&gt; holidayDateTime;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;interface&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;uses&lt;/span&gt; sysutils;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;type&lt;/span&gt;&lt;br /&gt;   THolidayClass = &lt;span class="kwrd"&gt;class&lt;/span&gt;&lt;br /&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt;&lt;br /&gt;        YearIs       : &lt;span class="kwrd"&gt;word&lt;/span&gt;;&lt;br /&gt;        NewYears     : TDateTime;&lt;br /&gt;        MLKJr        : TDateTime;&lt;br /&gt;        Inauguration : TDateTime;&lt;br /&gt;        Washington   : TDateTime;&lt;br /&gt;        ArmedForces  : TDateTime;&lt;br /&gt;        Memorial     : TDateTime;&lt;br /&gt;        FlagDay      : TDateTime;&lt;br /&gt;        Independence : TDateTime;&lt;br /&gt;        Labor        : TDateTime;&lt;br /&gt;        Columbus     : TDateTime;&lt;br /&gt;        Veterans     : TDateTime;&lt;br /&gt;        Thanksgiving : TDateTime;&lt;br /&gt;        Christmas    : TDateTime;&lt;br /&gt;        Secretaries  : TDateTime;&lt;br /&gt;        AprilFools   : TDateTime;&lt;br /&gt;        Earth        : TDateTime;&lt;br /&gt;        Fathers      : TDateTime;&lt;br /&gt;        Groundhog    : TDateTime;&lt;br /&gt;        Halloween    : TDateTime;&lt;br /&gt;        Lincoln      : TDateTime;&lt;br /&gt;        Mothers      : TDateTime;&lt;br /&gt;        StPatty      : TDateTime;&lt;br /&gt;        UnitedNations: TDateTime;&lt;br /&gt;        Valentines   : TDateTime;&lt;br /&gt;        Election     : TDateTime;&lt;br /&gt;        Flag         : TDateTime;&lt;br /&gt;        Easter       : TDateTime;&lt;br /&gt;        &lt;span class="kwrd"&gt;constructor&lt;/span&gt; Create(aYear:word);&lt;br /&gt;        &lt;span class="kwrd"&gt;procedure&lt;/span&gt; changeYear(aYear:word);&lt;br /&gt;        &lt;span class="kwrd"&gt;function&lt;/span&gt; getEaster:TDateTime;&lt;br /&gt;        &lt;span class="kwrd"&gt;class procedure&lt;/span&gt; SafeMonth(var month, y:word);&lt;br /&gt;        &lt;span class="kwrd"&gt;class function&lt;/span&gt; getDOW(year, month, dow, weekNum:word):TDateTime;&lt;br /&gt;        &lt;span class="kwrd"&gt;class function&lt;/span&gt; getLastDOW(year, month, dow:word):TDateTime;&lt;br /&gt;     end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;class procedure&lt;/span&gt; THolidayClass.SafeMonth(var month, y:&lt;span class="kwrd"&gt;word&lt;/span&gt;);&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;while&lt;/span&gt; month&amp;gt;12 &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;   dec(month,12);&lt;br /&gt;   inc(y);&lt;br /&gt;   &lt;span class="kwrd"&gt;end;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;end;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;class function&lt;/span&gt; THolidayClass.getDOW(year, month, dow, weekNum:&lt;span class="kwrd"&gt;word&lt;/span&gt;):TDateTime;&lt;br /&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; i:&lt;span class="kwrd"&gt;word&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;result:=EncodeDate(year, month, 1);&lt;br /&gt;&lt;span class="kwrd"&gt;for&lt;/span&gt; i:=0 &lt;span class="kwrd"&gt;to&lt;/span&gt; 7 &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;if&lt;/span&gt; DayOfWeek(result+i)=dow &lt;span class="kwrd"&gt;then&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;      result:=result+i;&lt;br /&gt;      result:=result+((weeknum-1)*7); &lt;span class="rem"&gt;//move to the correct week, 1st week is inc of 0&lt;/span&gt;&lt;br /&gt;      &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;br /&gt;      &lt;span class="kwrd"&gt;end;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;end;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;class function&lt;/span&gt; THolidayClass.getLastdow(year, month, dow:&lt;span class="kwrd"&gt;word&lt;/span&gt;):TDateTime;&lt;br /&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; i:&lt;span class="kwrd"&gt;word;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;//Year has to be on the stack, SafeMonth could change year&lt;/span&gt;&lt;br /&gt;inc(month);&lt;br /&gt;SafeMonth(month,year);&lt;br /&gt;result:=EncodeDate(year,month,1)-1;&lt;br /&gt;&lt;span class="kwrd"&gt;for&lt;/span&gt; i:=0 &lt;span class="kwrd"&gt;to&lt;/span&gt; 7 &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;if&lt;/span&gt; DayOfWeek(result-i)=dow then&lt;br /&gt;      &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;      result:=result-i;&lt;br /&gt;      &lt;span class="kwrd"&gt;break&lt;/span&gt;;&lt;br /&gt;      &lt;span class="kwrd"&gt;end;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;end;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;constructor&lt;/span&gt; THolidayClass.Create(aYear:&lt;span class="kwrd"&gt;word&lt;/span&gt;);&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;ChangeYear(aYear);&lt;br /&gt;&lt;span class="kwrd"&gt;end;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; THolidayClass.getEaster:TDateTime;&lt;br /&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; a,b,c,d,e,f,g,h,i,k,l,m,p  : &lt;span class="kwrd"&gt;integer;&lt;/span&gt;&lt;br /&gt;    Easter_Month, Easter_Day   : &lt;span class="kwrd"&gt;integer;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;   a:=yearis mod 19;&lt;br /&gt;   b:=yearis div 100;&lt;br /&gt;   c:=yearis mod 100;&lt;br /&gt;   d:=b div 4;&lt;br /&gt;   e:=b mod 4;&lt;br /&gt;   f:=(b+8) div 25;&lt;br /&gt;   g:=(b-f+1) div 3;&lt;br /&gt;   h:=(19*a+b-d-g+15) mod 30;&lt;br /&gt;   i:=c div 4;&lt;br /&gt;   k:=c mod 4;&lt;br /&gt;   l:=(32+2*e+2*i-h-k) mod 7;&lt;br /&gt;   m:=(a+11*h+22*l) div 451;&lt;br /&gt;   Easter_Month :=(h+l-7*m+114) div 31; //[3=March, 4=April]&lt;br /&gt;   p:=(h+l-7*m+114) mod 31;&lt;br /&gt;   Easter_Day:=p+1; //(day in Easter Month)&lt;br /&gt;   result:=EncodeDate(YearIs,Easter_Month,Easter_Day);&lt;br /&gt;&lt;span class="kwrd"&gt;end;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;procedure&lt;/span&gt; THolidayClass.ChangeYear(aYear:&lt;span class="kwrd"&gt;word&lt;/span&gt;);&lt;br /&gt;&lt;span class="kwrd"&gt;const&lt;/span&gt;&lt;br /&gt;   DayOfWeek_Sunday    = 1;&lt;br /&gt;   DayOfWeek_Monday    = 2;&lt;br /&gt;   DayOfWeek_Tuesday   = 3;&lt;br /&gt;   DayOfWeek_Wednesday = 4;&lt;br /&gt;   DayOfWeek_Thursday  = 5;&lt;br /&gt;   DayOfWeek_Friday    = 6;&lt;br /&gt;   DayOfWeek_Saturday  = 7;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;YearIs       := aYear;&lt;br /&gt;Easter       := getEaster;&lt;br /&gt;NewYears     := EncodeDate(YearIs,1,1);&lt;br /&gt;MLKJr        := getdow(YearIs, 1, DayOfWeek_Monday, 3);&lt;br /&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (YearIs - 1937) mod 4 = 0 &lt;span class="kwrd"&gt;then&lt;/span&gt;&lt;br /&gt;   Inauguration := EncodeDate(YearIs, 1, 20)&lt;br /&gt;&lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;   Inauguration := 0;&lt;br /&gt;Election     := 0;&lt;br /&gt;Flag         := EncodeDate(YearIs,6,14);&lt;br /&gt;Washington   := getdow(YearIs, 2, DayOfWeek_Monday, 3);&lt;br /&gt;ArmedForces  := getdow(YearIs, 5, DayOfWeek_Saturday, 3);&lt;br /&gt;Memorial     := getLastdow(YearIs, 5, DayOfWeek_Monday);&lt;br /&gt;FlagDay      := EncodeDate(YearIs,6,14);&lt;br /&gt;Independence := EncodeDate(YearIs,7,4);&lt;br /&gt;Labor        := getdow(YearIs, 9, DayOfWeek_Monday,1);&lt;br /&gt;Columbus     := getdow(YearIs, 10, DayOfWeek_Monday,2);&lt;br /&gt;Veterans     := EncodeDate(YearIs,11,11);&lt;br /&gt;Thanksgiving := getdow(YearIs, 11, DayOfWeek_Thursday,4);&lt;br /&gt;Christmas    := EncodeDate(YearIs,12,25);&lt;br /&gt;Secretaries  := getLastdow(YearIs, 5, DayOfWeek_Saturday) - 3; &lt;span class="rem"&gt;//wednesday before last saturday in april&lt;/span&gt;&lt;br /&gt;AprilFools   := EncodeDate(YearIs,4,1);&lt;br /&gt;&lt;br /&gt;Earth        := EncodeDate(YearIs,4,22);&lt;br /&gt;Fathers      := getdow(YearIs, 6, DayOfWeek_Sunday,3);&lt;br /&gt;Groundhog    := EncodeDate(YearIs,2,2);&lt;br /&gt;Halloween    := EncodeDate(YearIs,10,31);&lt;br /&gt;Lincoln      := EncodeDate(YearIs,2,12);&lt;br /&gt;Mothers      := getdow(YearIs, 5, DayOfWeek_Sunday,2);&lt;br /&gt;StPatty      := EncodeDate(YearIs,3,17);&lt;br /&gt;UnitedNations:= EncodeDate(YearIs,10,24);&lt;br /&gt;Valentines   := EncodeDate(YearIs,2,14);&lt;br /&gt;&lt;span class="kwrd"&gt;end;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;end.&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://ruminatedrumblings.blogspot.com/2008/03/holidays.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1661843880853288430?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1661843880853288430/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1661843880853288430' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1661843880853288430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1661843880853288430'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/holidays.html' title='Holidays'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-2039161059563217924</id><published>2008-08-13T18:31:00.003-07:00</published><updated>2008-08-13T18:33:53.959-07:00</updated><title type='text'>Detecting Virtual PC</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Adding to my previous post on detecting virtual environments, here's the code for detecting Virtual PC. Note that it's a conversion from CodeProject, the original author is &lt;a href="http://www.codeproject.com/KB/system/VmDetect.aspx"&gt;here&lt;/a&gt;. I also didn't write the conversion, I'm simply accumulating the VMM detection code here. Original credit for the conversion goes to &lt;a href="http://coding.derkeiler.com/Archive/Delphi/borland.public.delphi.language.basm/2005-03/0652.html"&gt;Dennis Pasamore&lt;/a&gt; who did the bulk of the conversion work with some assistance from Avatar Zonderatau.&lt;br /&gt;&lt;br /&gt;Code:&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; TForm1.IsRunningVirtualPC: &lt;span class="kwrd"&gt;boolean&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;asm&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;push&lt;/span&gt; ebp;&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; ebp, esp;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; ecx, &lt;span class="kwrd"&gt;offset&lt;/span&gt; @exception_handler;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;push&lt;/span&gt; ebx;&lt;br /&gt;  &lt;span class="kwrd"&gt;push&lt;/span&gt; ecx;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;push&lt;/span&gt; dword ptr fs:[0];&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; dword ptr fs:[0], esp;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; ebx, 0; &lt;span class="rem"&gt;// Flag&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; eax, 1; &lt;span class="rem"&gt;// VPC function number&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="rem"&gt;// call VPC&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;db&lt;/span&gt; $0F, $3F, $07, $0B&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; eax, dword ptr ss:[esp];&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; dword ptr fs:[0], eax;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;add&lt;/span&gt; esp, 8;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;test&lt;/span&gt; ebx, ebx;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;setz&lt;/span&gt; al;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;lea&lt;/span&gt; esp, dword ptr ss:[ebp-4];&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; ebx, dword ptr ss:[esp];&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; ebp, dword ptr ss:[esp+4];&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;add&lt;/span&gt; esp, 8;&lt;br /&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;jmp&lt;/span&gt; @ret1;&lt;br /&gt;&lt;br /&gt;@exception_handler:&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; ecx, [esp+0Ch];&lt;br /&gt;  &lt;span class="kwrd"&gt;mov&lt;/span&gt; dword ptr [ecx+0A4h], -1; &lt;span class="rem"&gt;// EBX = -1 -&amp;gt;; not running, ebx = 0 -&amp;gt; running&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;add&lt;/span&gt; dword ptr [ecx+0B8h], 4;  &lt;span class="rem"&gt;// -&amp;gt;; skip past the call to VPC&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;xor&lt;/span&gt; eax, eax;                 &lt;span class="rem"&gt;// exception is handled&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;@ret1:&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://ruminatedrumblings.blogspot.com/2008/04/detecting-virtual-pc.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-2039161059563217924?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/2039161059563217924/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=2039161059563217924' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2039161059563217924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2039161059563217924'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/detecting-virtual-pc.html' title='Detecting Virtual PC'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-8503027426854549482</id><published>2008-08-13T18:31:00.002-07:00</published><updated>2008-08-13T18:33:00.971-07:00</updated><title type='text'>Reputation vs The Resume</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/Steve.Peacocke/SHvNVEIdFpI/AAAAAAAABcI/FLRfwidjY0o/s1600-h/Search%5B6%5D.jpg"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="300" alt="Search" src="http://lh6.ggpht.com/Steve.Peacocke/SHvNWK3aaFI/AAAAAAAABcM/AMwaJbQ85_4/Search_thumb%5B4%5D.jpg?imgmax=800" width="400" align="left" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I have spent a good part of my professional career as a contractor so I was interested when I came across a post titled &amp;quot;&lt;a href="http://sethgodin.typepad.com/seths_blog/2008/03/why-bother-havi.html" target="_blank"&gt;Why bother having a resume?&lt;/a&gt;&amp;quot; on a blog site by Seth Godin. Seth gives an interesting argument that looks at the resume in 2 distinct ways: firstly he suggests that if you have a good reputation, then you won't need a resume; and secondly, that resumes are used by agents and employers in order to reject the bulk of respondents to get down to the interesting few they want to look at. &lt;/p&gt;  &lt;p&gt;I partially agree with Seth on both counts, however experience suggests caution on either front. During the 1990's I was lucky enough to have so many offers for contract work that I could take my pick. Companies were falling over themselves to offer me a contract because I had the distinct advantage of having built up a good reputation in the IT industry here. &lt;/p&gt;  &lt;p&gt;That no longer occurs, so what happened? Did my reputation go bad? No, I am still relatively well known and my reputation has not suffered. Did the job industry dry up? No again, although there are now many more applicants to choose from. The answer to this is much more involved and we have to look at a little history to see what went wrong in the industry here.&lt;/p&gt;  &lt;p&gt;Prior to 2000, there was so much panic over the &amp;quot;&lt;a href="http://en.wikipedia.org/wiki/Y2K" target="_blank"&gt;millennium bug&lt;/a&gt;&amp;quot; that anyone who could spell IT was employed in the industry as a Y2K consultant - not much more technical expertise, or even very much in the way of IQ was required. Once the year 2000 came and went without the predicted worldwide mass destruction, the wonderful Y2K pig trough was taken away and hundreds of thousands of &amp;quot;IT Experts&amp;quot; were out on the street looking for new jobs. A short time later 9/11 hit the whole world (my brother was stuck in Hawaii, cursing that the late arrival of his plane from Malaysia meant that he had missed his connecting flight to be at a meeting planned for 9am near the top of one of the towers). Every IT project in New Zealand just suddenly dried up. This also meant that thousands more IT people, this time mostly good, experienced and employable IT people, were out on the street applying for any IT job available.&lt;/p&gt;  &lt;p&gt;Companies and IT job agencies suddenly found themselves with a problem. For each IT job they advertised, they would get hundreds of applicants. Looking through all those CV's for a half decent applicant to consider was a nightmare. Companies that used to do all the hiring themselves, now started to put into place a &amp;quot;Policy&amp;quot;. For those initiated into the secret language of corporates, a &amp;quot;Company Policy&amp;quot; is a proclamation that is set permanently into the steel frame girders of the head office and emblazoned across the foreheads of all General Managers and others who sometimes think they are in charge. This particular policy states, &amp;quot;No longer can a manager employ staff on their own but must go though an employment agency&amp;quot;.&lt;/p&gt;  &lt;p&gt;The reasoning was sound to begin with. Agencies could sift through the hundreds of applications and forward to them only the few that would be suitable for the role they wanted to fill. Reality however was much bleaker than the rosy view they were sold. What tended to happen was that the agencies, in an effort to cope with the influx of applicants, started hiring new, young people who were then tasked with the job of sifting the applications. I do know of agencies (or I should say &amp;quot;agents&amp;quot;) who would, and still do, simply go through the first applications until they have two candidates that sound like they could do the job, then look no further (i.e. hundreds of job applications were never even opened), then forward those two to the client. Most however instigated the process of elimination that Seth talks about. This followed a simple process whereby firstly they would take out only those applications that had a university degree or higher, then go through those taking out only those who's current role was the same as, or similar to the role they are trying to fill. Only then, when they were down to a small hand full, would they actually look at the names and history of those that they had picked.&lt;/p&gt;  &lt;p&gt;Even ringing the agents that I had built up a good friendship and reputation with was fraught with difficulty during the next 5-6 years. To protect themselves from the pleading masses, they had to resort to employing gate-keepers. These gate keepers would only let through people who were either the companies they dealt with, or the named people that had been selected from the process of elimination. The gate-keepers cared not for reputation and had heard before the pretentious arguments that they were somehow &amp;quot;long lost friends&amp;quot; of the employment agent in charge.&lt;/p&gt;  &lt;p&gt;No job I applied for was going to even see my name unless by some pure fluke, I got through the process of elimination. My excellent reputation built with sweat and blood and now meant diddly-squat - the resume was king. Only of you were one of the first 20 who applied for the role, had a Masters degree from a known university, and had been doing that specific role for the past 5 years would you be deemed competent enough to have your name looked at. &lt;/p&gt;  &lt;p&gt;Although the agencies have relaxed their stance somewhat, and I can again speak directly to the agent in charge, don't forget the power of the resume. Also don' forget the all important qualifications - even with my industry recognition and reputation I had to go back to university to gain qualifications enough to pass through &amp;quot;the process&amp;quot;.&lt;/p&gt;  &lt;p&gt;With recession noises being heard through the world at the moment, we may well find ourselves back in the worst of times again for employment.&lt;/p&gt;  &lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://stevepeacocke.blogspot.com/2008/07/reputation-vs-resume.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-8503027426854549482?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/8503027426854549482/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=8503027426854549482' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8503027426854549482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8503027426854549482'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/reputation-vs-resume.html' title='Reputation vs The Resume'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/Steve.Peacocke/SHvNWK3aaFI/AAAAAAAABcM/AMwaJbQ85_4/s72-c/Search_thumb%5B4%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-6870834908406995399</id><published>2008-08-13T18:31:00.001-07:00</published><updated>2008-08-13T18:31:03.721-07:00</updated><title type='text'>Source beautifier  for SQL statements</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;A lot of developers uses source code beautifier tools for their source code, e.g. our ObjectPascal. But I found a nice online-tool for SQL-statements. You can not only format the SQL-command for the Database-server (Oracle, MSSQL and other) like the following result:&lt;br /&gt;SELECT HHJ,&lt;br /&gt;       CUSTOMER,&lt;br /&gt;       ORDER_ID&lt;br /&gt;FROM   TABLE&lt;br /&gt;&lt;br /&gt;On the right side you have some options for formatting.&lt;br /&gt;&lt;br /&gt;You can format this SQL-Statement for Delphi .....&lt;br /&gt;&lt;br /&gt;var1 := 'SELECT HHJ,' ;&lt;br /&gt;var1 := var1 + '        CUSTOMER,' ;&lt;br /&gt;var1 := var1 + '        ORDER_ID' ;&lt;br /&gt;var1 := var1 + ' FROM   TABLE' ;&lt;br /&gt;&lt;br /&gt;And other languages... e.g. for C# you can choose between&lt;br /&gt;String var1 = "SELECT HHJ," ;&lt;br /&gt;var1 = var1 + "        CUSTOMER," ;&lt;br /&gt;var1 = var1 + "        ORDER_ID" ;&lt;br /&gt;var1 = var1 + " FROM   TABLE" ;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;and&lt;/span&gt;&lt;br /&gt;StringBuilder  var1 = new StringBuilder("SELECT HHJ,");&lt;br /&gt;var1.Append("        CUSTOMER,");&lt;br /&gt;var1.Append("        ORDER_ID");&lt;br /&gt;var1.Append(" FROM   TABLE");&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I found this very usefull for formatting my SQL-statement to read it sometimes later better..&lt;br /&gt;&lt;br /&gt;Here you'll find the &lt;a href="http://www.orafaq.com/cgi-bin/sqlformat/pp/utilities/sqlformatter.tpl"&gt;Online SQL and PL/SQL Formatter&lt;/a&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://rave-notes.blogspot.com/2008/04/source-beautifier-for-sql-statements.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-6870834908406995399?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/6870834908406995399/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=6870834908406995399' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6870834908406995399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6870834908406995399'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/source-beautifier-for-sql-statements.html' title='Source beautifier  for SQL statements'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1878567111003317820</id><published>2008-08-12T14:53:00.005-07:00</published><updated>2008-08-12T20:27:35.727-07:00</updated><title type='text'>CreateInstall Free 4.14.3</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;O CreateInstall Free &amp;#233; uma ferramenta poderosa para a cria&amp;#231;&amp;#227;o de instaladores para suas aplica&amp;#231;&amp;#245;es. Permite um controle completo de todo o processo de instala&amp;#231;&amp;#227;o de uma aplica&amp;#231;&amp;#227;o, desde o processo de prepara&amp;#231;&amp;#227;o dos diret&amp;#243;rios, at&amp;#233; no momento de registros de sua aplica&amp;#231;&amp;#227;o juntamente com o sistema operacional utilizado.Algumas funcionalidades desse software:Todas as opera&amp;#231;&amp;#245;es podem ser modificadas utilizando a linguagem Gentee, tornando as possibilidades ilimitadasControle total durante os processos de instala&amp;#231;&amp;#227;o e desinstala&amp;#231;&amp;#227;oPossibilidade de modificar o visual das caixas de di&amp;#225;logoUtiliza um m&amp;#233;todo de compress&amp;#227;o altamente avan&amp;#231;ado, tornando sua aplica&amp;#231;&amp;#227;o extremamente port&amp;#225;vel, o que facilita a sua distribui&amp;#231;&amp;#227;oPossibilidade de exportar os projetos criados para o CreateInstall e realizar as modifica&amp;#231;&amp;#245;es que necessitarInforma&amp;#231;&amp;#245;es adicionais:Ao clicar no bot&amp;#227;o &amp;quot;Fa&amp;#231;a o download&amp;quot;, voc&amp;#234; poder&amp;#225; tamb&amp;#233;m baixar um pacote de linguagens e poder&amp;#225; modificar o idioma desse software para o Portugu&amp;#234;s - BRO CreateInstall Free &amp;#233; a vers&amp;#227;o freeware do CreateInstall&lt;br&gt;  Roda em Windows         95,  98,  NT,  2000,  Millenium,  XP,  2003 &lt;br&gt;    Baixar: &lt;a href="http://www.superdownloads.com.br/download/159/createinstall-free-gentee-inc/"&gt;http://www.superdownloads.com.br/download/159/createinstall-free-gentee-inc/&lt;/a&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://para-baixar.blogspot.com/2008/08/createinstall-free-4143.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1878567111003317820?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1878567111003317820/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1878567111003317820' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1878567111003317820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1878567111003317820'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/createinstall-free-4143.html' title='CreateInstall Free 4.14.3'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-488724909798311571</id><published>2008-08-12T14:53:00.004-07:00</published><updated>2008-08-12T14:54:04.398-07:00</updated><title type='text'>When being "objective" is being "biased"</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;I did the most unconscionable thing a few weeks ago. Something I've resisted for a very long time. I bought a Mac. For the first time. Ever. I'm not against Macs or Apple in general (I own an iPod and a Zune), in fact I find them very quaint and ...&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://blogs.codegear.com/abauer/2008/03/18/38858" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-488724909798311571?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/488724909798311571/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=488724909798311571' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/488724909798311571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/488724909798311571'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/when-being-objective-is-being-biased.html' title='When being &quot;objective&quot; is being &quot;biased&quot;'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-5070451902289439551</id><published>2008-08-12T14:53:00.003-07:00</published><updated>2008-08-12T14:53:59.850-07:00</updated><title type='text'>Rave BE and Windows Vista</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;I received last week an email about problems with Rave BE and Windows Vista. I installed a version of Vista in VMWare and then Delphi with Rave BE.&lt;br /&gt;&lt;br /&gt;Rave Version 8 (it should be available in the next few days!) works with Vista, of course.&lt;br /&gt;Rave BE and BEX &lt; 8 works with Vista, too&lt;br /&gt;&lt;br /&gt;If you have problems try the following:&lt;br /&gt;&lt;br /&gt;Rave BE is installed in the same directory structure as the version of Delphi was. In general, this will be the "c:\Programme" here in Germany or "c:\Program Files" in english. To attempt to resolve the Windows Vista security restrictions, you need to make sure that your "Group" or "User Name" has the "Full Control" permissions set to "Allow".&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Go to Program Files directory where you install the CodeGear / Borland product Program File\CodeGear\RAD Studio\5.0&lt;/li&gt;&lt;li&gt;Highlight RaveReports&lt;/li&gt;&lt;li&gt;Right Click on RaveReports and Open properties&lt;/li&gt;&lt;li&gt;Click the Security Tab&lt;/li&gt;&lt;li&gt;Select your own user name from the list displayed&lt;/li&gt;&lt;li&gt;Click the Edit button&lt;/li&gt;&lt;li&gt;Select your own uses name again&lt;/li&gt;&lt;li&gt;Go to the "Permissions for Users" dialogue box&lt;/li&gt;&lt;li&gt;Click the 'Full Control' Allow box&lt;/li&gt;&lt;li&gt;Click Apply&lt;/li&gt;&lt;li&gt;accept all the prompts&lt;/li&gt;&lt;/ol&gt;In my next post I'll explain the steps for Rave Reports BEX (Borland Edition eXtended) versions 7 or earlier.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://rave-notes.blogspot.com/2008/04/rave-be-and-windows-vista.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-5070451902289439551?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/5070451902289439551/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=5070451902289439551' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5070451902289439551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5070451902289439551'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/rave-be-and-windows-vista.html' title='Rave BE and Windows Vista'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-5974906199383377440</id><published>2008-08-12T14:53:00.001-07:00</published><updated>2008-08-12T14:53:49.928-07:00</updated><title type='text'>India again</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Last time I went to India I had a great time, I promised pictures I know, I managed to lose most of them when I recently had to rebuild my machine, but good news, I am coming to India again soon, and I will definitely post them up this time (yeah ...&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://blogs.codegear.com/timjarvis/2007/02/15/31828" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-5974906199383377440?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/5974906199383377440/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=5974906199383377440' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5974906199383377440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5974906199383377440'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/india-again.html' title='India again'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-9077225035130568784</id><published>2008-08-11T19:03:00.008-07:00</published><updated>2008-08-11T19:04:01.689-07:00</updated><title type='text'>German ECO book gets an update!</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Wow! Great work, Alois! The German ECO III book got lots and lots of new content. And even better: Alois announced in the newsgroups that an English version is in the works.&lt;br /&gt;&lt;br /&gt;And the best thing about it: it is all available for download for free right &lt;a href="http://www.ecospace.de/ecobook.html"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphi2006.blogspot.com/2006/05/german-eco-book-gets-update.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-9077225035130568784?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/9077225035130568784/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=9077225035130568784' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/9077225035130568784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/9077225035130568784'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/german-eco-book-gets-update.html' title='German ECO book gets an update!'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-4981754475034802529</id><published>2008-08-11T19:03:00.007-07:00</published><updated>2008-08-11T19:03:57.691-07:00</updated><title type='text'>Finally! Another Delphi book!</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://images-eu.amazon.com/images/P/1590593863.03.LZZZZZZZ.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px;" src="http://images-eu.amazon.com/images/P/1590593863.03.LZZZZZZZ.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;The title ".NET 2.0 for Delphi Programmers" might sound misleading at first, but as I have seen the table of contents, which can be looked at &lt;a href="http://www.midnightbeach.com/.net"&gt;here&lt;/a&gt;, I immediatelly pre-ordered it. It is already available in the United States at Amazon.com, but not yet in Germany.&lt;br /&gt;&lt;br /&gt;The book is written for Delphi developers who want to get to know .NET. I was pretty overwhelmed when I looked at Delphi for .NET without actually knowing anything about .NET. At that time, there was only a book that dealt with C# to show what .NET was all about. However, right now I would have the choice to order a book that used Delphi instead of another language.&lt;br /&gt;&lt;br /&gt;So, count yourselves lucky and be happy that you can order a Delphi book that can get you started with .NET and gives you a whole lot of the details you need. I prepared two links: &lt;a href="http://tinyurl.com/pwpsx"&gt;United States&lt;/a&gt; and &lt;a href="http://tinyurl.com/ppg48"&gt;Germany&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Thanks Jon!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note:&lt;/b&gt; venkatesh pointed out that he found an eBook-version that is available for 30$. I just wanted to point it out, but have not googled for it yet.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphi2006.blogspot.com/2006/06/finally-another-delphi-book.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-4981754475034802529?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/4981754475034802529/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=4981754475034802529' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4981754475034802529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4981754475034802529'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/finally-another-delphi-book.html' title='Finally! Another Delphi book!'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1675781403878982743</id><published>2008-08-11T19:03:00.005-07:00</published><updated>2008-08-11T19:03:50.329-07:00</updated><title type='text'>A Unicode teaser</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Here's a small teaser to show you what I've been working on recently:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; EncodeUTF16LEChar(aCodePoint: UCodePoint; aChar: PUTF16Char): Integer;&lt;br /&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt;&lt;br /&gt;  X, W: Word;&lt;br /&gt;  U: LongWord;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;case&lt;/span&gt; aCodePoint &lt;span class="kwrd"&gt;of&lt;/span&gt;&lt;br /&gt;    &lt;span class="rem"&gt;{ Double-byte char }&lt;/span&gt;&lt;br /&gt;    $0000..$D7FF,&lt;br /&gt;    &lt;span class="rem"&gt;{ NOTE: This gap here represents reserved code points, i.e. 'surrogates'! }&lt;/span&gt;&lt;br /&gt;    $E000..$FFFF:&lt;br /&gt;      &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;        Result := 1;&lt;br /&gt;&lt;br /&gt;        PWordArray(aChar)^[0] := Word(aCodePoint);&lt;br /&gt;      &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;    &lt;span class="rem"&gt;{ Quadruple-byte char - surrogate pair }&lt;/span&gt;&lt;br /&gt;    $010000..$10FFFF:&lt;br /&gt;      &lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;        Result := 2;&lt;br /&gt;&lt;br /&gt;        X := Word(aCodePoint);&lt;br /&gt;&lt;br /&gt;        &lt;span class="rem"&gt;{ High surrogate }&lt;/span&gt;&lt;br /&gt;        U := (aCodePoint &lt;span class="kwrd"&gt;shr&lt;/span&gt; 16) &lt;span class="kwrd"&gt;and&lt;/span&gt; ((1 &lt;span class="kwrd"&gt;shl&lt;/span&gt; 5) - 1);&lt;br /&gt;        W := U - 1;&lt;br /&gt;        PWordArray(aChar)^[0] := Word($D800 &lt;span class="kwrd"&gt;or&lt;/span&gt; (Word(W) &lt;span class="kwrd"&gt;shl&lt;/span&gt; 6) &lt;span class="kwrd"&gt;or&lt;/span&gt; (X &lt;span class="kwrd"&gt;shr&lt;/span&gt; 10));&lt;br /&gt;&lt;br /&gt;        &lt;span class="rem"&gt;{ Low surrogate }&lt;/span&gt;&lt;br /&gt;        PWordArray(aChar)^[1] := Word($DC00 &lt;span class="kwrd"&gt;or&lt;/span&gt; (X &lt;span class="kwrd"&gt;and&lt;/span&gt; ((1 &lt;span class="kwrd"&gt;shl&lt;/span&gt; 10) - 1)));&lt;br /&gt;      &lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;raise&lt;/span&gt; Exception.CreateResFmt(@cInvalidCodePoint, [IntToHex(aCodePoint, 8)]);&lt;br /&gt;  &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;I'm not revealing any details for now, so I guess you'll just have to check back. :)&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://developersoven.blogspot.com/2007/02/unicode-teaser.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1675781403878982743?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1675781403878982743/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1675781403878982743' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1675781403878982743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1675781403878982743'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/unicode-teaser.html' title='A Unicode teaser'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-5329723329534156771</id><published>2008-08-11T19:03:00.003-07:00</published><updated>2008-08-11T19:03:46.832-07:00</updated><title type='text'>I was pickpocketed today...</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Yeah. I've involuntarily joined the masses. I guess it was bound to happen, but until now I've foolishly believed I was living in a country where this kind of crime was more of an exception than a rule. Well, that should teach me...&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;I was in a completely empty waiting room at a dentist's office, waiting for my wife to come out (my brave girl had her wisdom tooth extracted today, ouch) and for a minute I turned my back on our coats that were hanging just a few steps from me. I guess that was one minute to long. I only noticed my wallet was missing 20 minutes later, when we were leaving the building...&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;In the end, I consider myself lucky - the wallet was practically empty! They only got about €2 (that's roughly $2.5), my driving licence, the key to my office and some other unimportant knick-knacks. I've recently been reorganizing my wallet and I moved all my credit cards and personal documents out of there and have been keeping it in a separate pocket, which thankfully snuck under the thief's radar.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;The funny thing is, I almost wish they had stolen my credit cards instead of the driving license! All my credit cards and the money on them are insured for theft so I wouldn't actually lose a cent. The driving license, however, had my photo inside. This means, I'm going to have to go and have another one taken, which I kind of hate doing...&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;I still hope the thief shows &lt;span style="font-style: italic;"&gt;some&lt;/span&gt; honesty and takes the €2, buys an envelope and a stamp and returns my driving license to me. Yeah, what can I say... I'm an optimist.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[EDIT 17:30]&lt;/span&gt;&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;It seems this is my lucky day! The police notified me that someone has found my driving license not 200 meters from the scene of crime, just around the corner of the building my wife and I were in. It was accompanied by almost everything else I was keeping in my wallet - except for the €2, the office key and the wallet itself. They said it was probably work of one of the drug addicts that scour the waiting rooms in that area.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Apparently, he'll be able to acquire a week's worth of syringes with the wealth he got from me. My only response to this is: &lt;span style="font-style: italic;"&gt;"Go for it, pal!"&lt;/span&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://developersoven.blogspot.com/2007/02/i-was-pickpocketed-today.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-5329723329534156771?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/5329723329534156771/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=5329723329534156771' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5329723329534156771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5329723329534156771'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/i-was-pickpocketed-today.html' title='I was pickpocketed today...'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7365375469197506220</id><published>2008-08-11T19:03:00.001-07:00</published><updated>2008-08-11T19:03:44.334-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi'/><title type='text'>Still looking at the map.</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;&lt;p&gt;On my last post about the Delphi road map I got very interesting comments. Those comments made me think about what is really needed to take Delphi back to the place it deserves as a development tool.&lt;span id="more-21"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In my opinion CodeGear needs to focus on the Tool instead of the language. Improvements such as Unicode support, 64 bit support, cross platform support (Windows, OS X, Linux, Symbian, etc.), IDE stability, productivity features, new databases support and more.&lt;br /&gt;&lt;br /&gt;I agree with those who think that Codegear should stop playing the “me too game” and stop pursuing the .Net stuff. I&amp;#8217;ll take native development over .Net any day.&lt;br /&gt;&lt;br /&gt;Adding features to the language can be beneficial. But, at this point in time, I think it is secondary. I still can accomplish all that I need with the current language.&lt;br /&gt;&lt;br /&gt;I invite you to post your comments and/or take the poll on the right.&lt;br /&gt;&lt;br /&gt;Thank you for stopping by and happy coding!&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&lt;tr&gt;&lt;td valign=top&gt;&lt;b&gt;Keyword&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Delphi&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://delphibistro.com/?p=21" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7365375469197506220?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7365375469197506220/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7365375469197506220' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7365375469197506220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7365375469197506220'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/still-looking-at-map.html' title='Still looking at the map.'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-6325553882464853213</id><published>2008-08-10T14:24:00.005-07:00</published><updated>2008-08-10T14:24:29.449-07:00</updated><title type='text'>The secret of xs:dateTime</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;One man's dream tool can very well be another's cause of nightmares. The difference is in knowing the right secrets of using the tool...&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Today, I'm going to let you in on one about the xs:dateTime.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;OK, I'll admit - I'm being overly dramatic. It's not really a secret, however it is something that's quite easy to miss.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;But first, what &lt;span style="font-style: italic;"&gt;is&lt;/span&gt; xs:dateTime?&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;In short, it's a standardized way of representing a date/time value in form of a string. It's covered in detail by the current version of &lt;a href="http://www.w3.org/TR/xmlschema11-2/#dateTime"&gt;W3C Schema, Part 2: DataTypes&lt;/a&gt;. It is deeply connected to &lt;a href="http://www.iso.org/iso/en/prods-services/popstds/datesandtime.html"&gt;ISO 8601&lt;/a&gt; and is in fact a subset of that standard.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;I'm not going to bore you with dull definitions, because you can learn everything and more than I could ever tell you by simply following the above links.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Instead, let's take a look at a sample date/time value in xs:dateTime format:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;2007-02-17T14:40:32.000Z&lt;/span&gt;&lt;/blockquote&gt;Even without any specific knowledge of the xs:dateTime, you can tell the year, month, day, hour, minute and second, yes? If not, than go and follow the above links.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;If you're still here, this means you're probably also able to deduce where the milliseconds are hiding. And you may or may not know what that 'Z' at the end stands for. Anyway, that's what I want to talk about in this article, so keep on reading...&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;The 'Z' stands for the &lt;span style="font-style: italic;"&gt;time zone zero&lt;/span&gt;, or 'Zulu', which is a military way of pronouncing the letter 'Z'. In other words, it tells us that the date/time value is specified in &lt;a href="http://en.wikipedia.org/wiki/Coordinated_Universal_Time"&gt;UTC&lt;/a&gt; (Coordinated Universal Time). Simply put, UTC is a common denominator for all the date/time values that different parts of the world use to represent their local dates/times. Any local date/time value can be expressed as a relative difference towards UTC, which itself is constant no matter where on this planet (or even above it) you are.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Here's another example of a xs:dateTime formatted value, this time using the relative difference to UTC approach:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;2007-02-17T15:40:32.000+01:00&lt;/span&gt;&lt;/blockquote&gt;Guess what? It's &lt;span style="font-style: italic;"&gt;the same&lt;/span&gt; date/time value as before! The '+01:00' part tells us that it's a local date/time value with &lt;span style="font-style: italic;"&gt;one additional hour&lt;/span&gt; compared to UTC. This is the formula:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;[Local date/time] = UTC +/- [xx:xx]&lt;/span&gt;&lt;/blockquote&gt;And this is the same formula using the values from the above case:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;2007-02-17T15:40:32.000+01:00 = 2007-02-17T14:40:32.000Z + 01:00&lt;/span&gt;&lt;/blockquote&gt;Incidentally, this date/time value belongs to my local time zone - the Central European Time Zone on Winter Time, to be precise. In summer, the relative difference to UTC changes to '+02:00', because our local clocks are moved one hour ahead to compensate for the &lt;a href="http://en.wikipedia.org/wiki/Daylight_saving_time"&gt;daylight saving&lt;/a&gt;. I won't be going into that here, because that would be well beyond the scope of what I wanted to cover.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;As such, UTC is obviously &lt;span style="font-style: italic;"&gt;the&lt;/span&gt; most appropriate base for date/time comparison - a very common operation in software.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;But is it equally appropriate for display in user interfaces? It turns out this is not as simple as it seems...&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Most human beings on this planet are highly attuned to the natural definition of day and night, which directly corresponds to the relative position of the Sun against our location. That's where everyday phrases like "in the morning", "in the evening", "at noon", "at midnight", etc. come from in the first place. We naturally expect* that 08:00 happens sometime in the morning, wherever we might be at that time.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;* - I'm talking in 24 hour clock format here, of course. I'm &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; getting into any of that 12 hour format nonsense...&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;The problem with this is, that 08:00 in Slovenia isn't quite the same as 08:00 in, say, Washington DC, even if the date part is exactly the same. They're both "in the morning", but the morning in question comes 6 hours earlier for Slovenia than Washington DC!&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Imagine you were writing a software for listing global events. Let's examine the different ways of storing the dates/times of each event entry...&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Say the dates/times of all entries were local to respective event locations... You'd probably have a hard time sorting out, which event came before which without looking up the time zone info for every single event. Sure, you may have all that info, but it'd still require work!&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;How would this look like, if all entries used UTC instead? Sorting would be a no-brainer - just compare the values directly, and voila! But then your users would lose the ability to tell at a glance, in which part of the day a particular event actually happened. They don't want to think about time zone differences to figure out what 03:45 UTC means, remember?&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;So what's left, then? Well, you could keep all entries using local dates/times, but add the relative difference to UTC for each entry. Sorting would still be easy, it'd just require some simple math to add or subtract the relative difference from the base value. And the users would still be able to get the local values they expect.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;OK, so that's nice... But what if only &lt;span style="font-style: italic;"&gt;some&lt;/span&gt; of the users wanted to see the values in the event-local date/time, while others wanted to see them as UTC or even in &lt;span style="font-style: italic;"&gt;their&lt;/span&gt; local date/time? This could very realistically be the case in an online meeting scheduling software - an advanced IM, if you like. Would local date/time with relative difference to UTC be able to cover all possibilities?&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Well, with a little help from client OS, it would and it is... :)&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Given the event-local date/time and its relative difference to UTC, client software can easily calculate all three values:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the event-local date/time directly from input value,&lt;/li&gt;&lt;li&gt;the plain UTC by adding or subtracting the relative difference from base value, and&lt;/li&gt;&lt;li&gt;the user-local date/time, provided the local time zone info from the OS.&lt;/li&gt;&lt;/ul&gt;Although the latter could be done just the same with only the UTC value in the first place, it would be much harder to retrieve the event-local date/time, since there is no info on the event's time zone in plain UTC.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Ah, excellent! It appears we've truly found a winning combo!&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;By storing the date/time values in xs:dateTime format and including the relative difference to UTC, we've both retained the information about the event-local date/time &lt;span style="font-style: italic;"&gt;and&lt;/span&gt; included the implicit UTC value for use in further conversions. All thanks to the expressing power of xs:dateTime!&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;So next time you find yourself deciding on the appropriate storage format for date/time values, think about using the &lt;span style="font-family:courier new;"&gt;yyyy-mm-ddThh:mm:ss.zzz[+/-]xx:xx&lt;/span&gt; variant of xs:dateTime, especially if dealing with XML! It gives you everything a plain UTC variant would, with bonus of preserving the local date/time for when it matters.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://developersoven.blogspot.com/2007/02/secret-of-xsdatetime.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-6325553882464853213?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/6325553882464853213/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=6325553882464853213' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6325553882464853213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6325553882464853213'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/secret-of-xsdatetime.html' title='The secret of xs:dateTime'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-445361793721447461</id><published>2008-08-10T14:24:00.003-07:00</published><updated>2008-08-10T14:24:20.156-07:00</updated><title type='text'>Detecting various Windows versions</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Sometimes you need to know the version of Windows you're running on. Here's a &lt;a href="http://freeweb.siol.net/aoven/SourceCode/WinVerUtils.zip"&gt;simple unit&lt;/a&gt; I've whipped up for myself, that anyone can use.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;I can't guarantee the code actually works as advertised, but it should be able to recognize the following versions of Windows:&lt;br /&gt;&lt;pre class="code"&gt;Windows 95&lt;br /&gt;Windows 95 OSR 2&lt;br /&gt;Windows 98&lt;br /&gt;Windows 98 Second Edition&lt;br /&gt;Windows Millenium&lt;br /&gt;Windows NT 3.5&lt;br /&gt;Windows NT 4.0&lt;br /&gt;Windows 2000&lt;br /&gt;Windows XP&lt;br /&gt;Windows XP Service Pack 2&lt;br /&gt;Windows XP x64&lt;br /&gt;Windows Server 2003&lt;br /&gt;Windows Vista&lt;br /&gt;Windows Server Longhorn&lt;/pre&gt;&lt;br /&gt;No special license applies, so just enjoy! You're welcome to report if you find any problems with the code...&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://developersoven.blogspot.com/2007/02/detecting-various-windows-versions.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-445361793721447461?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/445361793721447461/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=445361793721447461' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/445361793721447461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/445361793721447461'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/detecting-various-windows-versions.html' title='Detecting various Windows versions'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-3376264933816762431</id><published>2008-08-10T14:24:00.001-07:00</published><updated>2008-08-10T14:24:09.628-07:00</updated><title type='text'>Overloading array properties in Delphi/Win32</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;A few days ago, a colleague of mine, &lt;a href="http://leenover.homeip.net/"&gt;Lee_Nover&lt;/a&gt;, approached me with an interesting problem. He was looking for a way to overload an array property of an object, so that items could be accessed by differently typed indexers.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Basically, he wanted to do this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;br /&gt;O := MyObj.Items[0];&lt;br /&gt;O := MyObj.Items[&lt;span class="str"&gt;'ObjName'&lt;/span&gt;];&lt;br /&gt;O := MyObj.Items[Now];&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;blockquote class="blocknote"&gt;The point of this exercise was to accomplish this in Delphi/Win32. C#/.NET has this, but that's only because properties are implemented differently there than they are in Delphi/Win32.&lt;/blockquote&gt;&lt;br /&gt;By the time he got to ask for my help, my colleague had already discovered several ways to do this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;property&lt;/span&gt; Items[&lt;span class="kwrd"&gt;const&lt;/span&gt; aIndex]: TObject ... ;&lt;br /&gt;&lt;span class="kwrd"&gt;property&lt;/span&gt; Items[aIndex: &lt;span class="kwrd"&gt;array&lt;/span&gt; &lt;span class="kwrd"&gt;of&lt;/span&gt; &lt;span class="kwrd"&gt;const&lt;/span&gt;]: TObject ... ;&lt;br /&gt;&lt;span class="kwrd"&gt;property&lt;/span&gt; Items[&lt;span class="kwrd"&gt;const&lt;/span&gt; aIndex: Variant]: TObject ... ;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;All of the above did the job, but none were too elegant. Untyped indexer was great for accepting different types, but offered no elegant way of retrieving the actual type that was being passed into the argument. &lt;span class="code"&gt;Array of const&lt;/span&gt; indexer somewhat solved this problem, but imposed an additional set of square brackets when accessing the property. &lt;span class="code"&gt;Variant&lt;/span&gt; indexer was the most promising, but it still offered no way of limiting the accepted indexer types at compile time.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;After a little bit of thinking, I suggested a different solution: using a record type indexer with overloaded operators -- a feature introduced in Delphi 2006/Win32.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Surely enough, we tried it, and it worked! Here's an example of what we did:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;type&lt;/span&gt;&lt;br /&gt;  TDataType = (dtInteger, dtString);&lt;br /&gt;&lt;br /&gt;  TIndex = &lt;span class="kwrd"&gt;record&lt;/span&gt;&lt;br /&gt;    DataType: TDataType;&lt;br /&gt;&lt;br /&gt;    IntValue: Integer;&lt;br /&gt;    StringValue: AnsiString;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; &lt;span class="kwrd"&gt;operator&lt;/span&gt; Implicit(aValue: Integer): TIndex;&lt;br /&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; &lt;span class="kwrd"&gt;operator&lt;/span&gt; Implicit(&lt;span class="kwrd"&gt;const&lt;/span&gt; aValue: AnsiString): TIndex;&lt;br /&gt;  &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  TNamedObjectList = &lt;span class="kwrd"&gt;class&lt;/span&gt;(TObject)&lt;br /&gt;  ...&lt;br /&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt;&lt;br /&gt;    ...&lt;br /&gt;    &lt;span class="kwrd"&gt;property&lt;/span&gt; Items[&lt;span class="kwrd"&gt;const&lt;/span&gt; aIndex: TIndex]: TObject &lt;span class="kwrd"&gt;read&lt;/span&gt; GetItem &lt;span class="kwrd"&gt;write&lt;/span&gt; SetItem; &lt;span class="kwrd"&gt;default&lt;/span&gt;;&lt;br /&gt;  &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;And here's the implementation of the record's operators:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; &lt;span class="kwrd"&gt;operator&lt;/span&gt; TIndex.Implicit(aValue: Integer): TIndex;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  Result.DataType := dtInteger;&lt;br /&gt;  Result.IntValue := aValue;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; &lt;span class="kwrd"&gt;operator&lt;/span&gt; TIndex.Implicit(&lt;span class="kwrd"&gt;const&lt;/span&gt; aValue: AnsiString): TIndex;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  Result.DataType := dtString;&lt;br /&gt;  Result.StringValue := aValue;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;This way, the property can be accessed by both &lt;span class="code"&gt;Integer&lt;/span&gt; and &lt;span class="code"&gt;AnsiString&lt;/span&gt; indexers. Thanks to overloaded operators, compiler takes care of translating both simple types into a record type -- this is sort of similar to the .NET concept of &lt;span style="font-style:italic;"&gt;"boxing"&lt;/span&gt;.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Accessor methods of the property can then determine the actual value along with its type directly from the record's fields:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; TNamedObjectList.GetItem(&lt;span class="kwrd"&gt;const&lt;/span&gt; aIndex: TIndex): TObject;&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;case&lt;/span&gt; aIndex.DataType &lt;span class="kwrd"&gt;of&lt;/span&gt;&lt;br /&gt;    dtInteger: Result := fList.Objects[aIndex.IntValue];&lt;br /&gt;    dtString:  Result := fList.Objects[fList.IndexOf(aIndex.StringValue)];&lt;br /&gt;  &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;    Result := &lt;span class="kwrd"&gt;nil&lt;/span&gt;;&lt;br /&gt;  &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;procedure&lt;/span&gt; TNamedObjectList.SetItem(&lt;span class="kwrd"&gt;const&lt;/span&gt; aIndex: TIndex; aValue: TObject);&lt;br /&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt;&lt;br /&gt;  Idx: Integer;&lt;br /&gt;  ...&lt;br /&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;case&lt;/span&gt; aIndex.DataType &lt;span class="kwrd"&gt;of&lt;/span&gt;&lt;br /&gt;    dtInteger: Idx := aIndex.IntValue;&lt;br /&gt;    dtString:  Idx := fList.IndexOf(aIndex.StringValue);&lt;br /&gt;  &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;br /&gt;    Idx := -1;&lt;br /&gt;  &lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;  ...&lt;br /&gt;  fList.Objects[Idx] := aValue;&lt;br /&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;This approach has the extra benefit of using compile-time type checking. The way we overloaded the &lt;span class="code"&gt;Implicit&lt;/span&gt; operator, we limited the accepted indexer types to &lt;span class="code"&gt;Integer&lt;/span&gt; and &lt;span class="code"&gt;AnsiString&lt;/span&gt;. Nothing else will be accepted by the compiler. Any other type can be added later by simply adding more overloads to the &lt;span class="code"&gt;Implicit&lt;/span&gt; operator.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Here's a &lt;a href="http://freeweb.siol.net/aoven/SourceCode/PropertyOverloading.zip"&gt;sample project&lt;/a&gt; which demonstrates the usefulness of this approach.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;Obviously, this solution works just as great for interface properties as it does for object properties. The only down side is that it requires a Delphi 2006 compiler or newer. But then again, who's still using anything below that -- especially now, when an enhanced version (i.e. Delphi 2007) is just around the corner? ;)&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;[EDIT 2007-03-15T17:45]&lt;/span&gt;&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;There are times when reading the help can actually save you some work... Commenter Steve found a much simpler way, that can be used when you only need one overloaded property for a given class. Simply declare that property multiple times with different indexers, and mark all copies with &lt;span class="code"&gt;default&lt;/span&gt; directive. Please refer to article's comments for more details.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://developersoven.blogspot.com/2007/03/overloading-array-properties-in.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Parceiros:&lt;br/&gt;&lt;center&gt; |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;BlogTips&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Musas&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker&lt;/a&gt;| &lt;a href="http://bestofweek.blogspot.com/" target=self&gt;News&lt;/a&gt;|&lt;/br&gt; &lt;a href="http://dicasingles.blogspot.com/" target=self&gt;EnglishTips&lt;/a&gt;| &lt;a href="http://delphidicas.blogspot.com/" target=self&gt;TipsDelphi&lt;/a&gt;| &lt;a href="http://futebolisticas.blogspot.com/" target=self&gt;FutOnline&lt;/a&gt;|&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-3376264933816762431?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/3376264933816762431/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=3376264933816762431' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3376264933816762431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3376264933816762431'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/overloading-array-properties-in.html' title='Overloading array properties in Delphi/Win32'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-6670686599062090953</id><published>2008-08-09T20:16:00.001-07:00</published><updated>2008-08-09T20:16:33.709-07:00</updated><title type='text'>Chat em Delphi</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;Certa vez tentei fazer um &lt;a href="http://www.cdmj.com.br/forum/index.php?showtopic=2811"&gt;chat&lt;/a&gt; aonde o usuário movimentasse um personagem pela tela. Essa idéia era baseado no &lt;a href="www.habbo.com.br/"&gt;Habbo Hotel&lt;/a&gt;. Conheci esse serviço &lt;a href="http://www.cdmj.com.br/forum/index.php?showtopic=2721"&gt;nesse tópico&lt;/a&gt; na &lt;a href="http://www.cdmj.com.br/forum/"&gt;CdMJ&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Primeira coisa que fiz foi arrumar um chat pronto em Dephi com o código fonte disponível. Dentre os que achei, decidi utilizar o CHAT WOTT que se divide em &lt;a href="http://www.delphifr.com/codes/CLIENT-CHAT-WOTT_34811.aspx"&gt;Cliente&lt;/a&gt; e &lt;a href="http://www.delphifr.com/codes/SERVEUR-CHAT-WOTT_34810.aspx"&gt;Servidor&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Tela do Cliente&lt;/b&gt;&lt;br /&gt;&lt;img src="http://dprogrammer.files.wordpress.com/2007/05/telachat.jpg" alt="tela cliente chat woot" height="352" width="425" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Tela do Servidor&lt;/b&gt;&lt;br /&gt;&lt;img src="http://dprogrammer.files.wordpress.com/2007/05/servidor_chat.jpg" alt="tela servidor wott" height="328" width="428" /&gt;&lt;br /&gt;&lt;br /&gt;Depois procurei aprender a movimentar um personagem pela tela. Achei um &lt;a href="http://pt.wikipedia.org/wiki/MMORPG"&gt;MMORPG&lt;/a&gt; utilizando os componentes do &lt;a href="http://www.micrel.cz/Dx/"&gt;DelphiX&lt;/a&gt;. Perguei o código responsável pelo movimento e incluir no &lt;a href="http://www.delphifr.com/codes/CLIENT-CHAT-WOTT_34811.aspx"&gt;cliente do chat&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Tela do Cliente Modificado&lt;/b&gt;&lt;br /&gt;&lt;img src="http://dprogrammer.files.wordpress.com/2007/05/tela_chat.jpg" alt="tela cliente wott modificado" height="311" width="435" /&gt;&lt;br /&gt;&lt;br /&gt;Cheguei a fazer alguns testes com o chat que eu modifiquei. Criei um redirecionado no no-ip.com, e rodei o servidor no meu computador. A parte do chat funcionou bem. Só não terminei a parte do personagem. A intenção era que aparecesse um balão no personagem com o que o seu usuário digitou.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Links sobre o assunto na &lt;a href="http://www.cdmj.com.br/forum/"&gt;CdMJ&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cdmj.com.br/forum/index.php?showtopic=2721"&gt;Habbo Hotel&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cdmj.com.br/forum/index.php?showtopic=2811"&gt;CdMJ Chat&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Quem sabe um dia eu termine esse programa.&lt;br /&gt;&lt;br /&gt;Vou procurar o endereço do &lt;a href="pt.wikipedia.org/wiki/MMORPG"&gt;MMORPG&lt;/a&gt; em delphi que eu achei.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Compare Preços:&lt;/b&gt; &lt;a href="http://compare.buscape.com.br/categorias?id=2&amp;amp;c=0&amp;amp;raiz=2&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;Informática&lt;/a&gt;, &lt;a href="http://compare.buscape.com.br/categorias?id=6108&amp;amp;c=0&amp;amp;raiz=6108&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;Assinaturas e Revistas&lt;/a&gt;,&amp;nbsp; &lt;a href="http://compare.buscape.com.br/categorias?id=3482&amp;amp;c=0&amp;amp;raiz=3482&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;Livros&lt;/a&gt;,&amp;nbsp; &lt;a href="http://compare.buscape.com.br/categorias?id=8590&amp;amp;c=0&amp;amp;raiz=0&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;E-Books&lt;/a&gt;,&amp;nbsp; &lt;a href="http://compare.buscape.com.br/categorias?id=2918&amp;amp;c=0&amp;amp;raiz=0&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;HandHeld/Palm Top&lt;/a&gt;,&amp;nbsp; &lt;a href="http://compare.buscape.com.br/categorias?id=6424&amp;amp;c=0&amp;amp;raiz=0&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;Notebook&lt;/a&gt;,&amp;nbsp; &lt;a href="http://compare.buscape.com.br/categorias?id=6019&amp;amp;c=0&amp;amp;raiz=0&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;Revistas CD-ROM&lt;/a&gt;,&amp;nbsp; &lt;a href="http://busca.buscape.com.br/cprocura?produto=console+wii&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;WII&lt;/a&gt;,&amp;nbsp; &lt;a href="http://busca.buscape.com.br/cprocura?produto=console+xbox&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;Xbox 360&lt;/a&gt;,&amp;nbsp; &lt;a href="http://busca.buscape.com.br/cprocura?produto=palm+zire+22&amp;amp;lkout=1&amp;amp;site_origem=1244278"&gt;Zire 22&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Technorati Tags: &lt;a class="performancingtags" href="http://technorati.com/tag/chat" rel="tag"&gt;chat&lt;/a&gt;, &lt;a class="performancingtags" href="http://technorati.com/tag/delphi" rel="tag"&gt;delphi&lt;/a&gt;, &lt;a class="performancingtags" href="http://technorati.com/tag/mmorpg" rel="tag"&gt;mmorpg&lt;/a&gt;, &lt;a class="performancingtags" href="http://technorati.com/tag/delphix" rel="tag"&gt;delphix&lt;/a&gt;, &lt;a class="performancingtags" href="http://technorati.com/tag/avatar" rel="tag"&gt;avatar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="poweredbyperformancing"&gt;Powered by &lt;a href="http://scribefire.com/"&gt;ScribeFire&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;----&lt;br /&gt;Data Original: 2007-05-01 8:58:39 pm&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://dprogrammer.blogspot.com/2007/08/chat-em-delphi.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Apoio |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;Tips For Blogs&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Belas Mulheres&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker e Seguranca&lt;/a&gt;| &lt;a href="http://www.minadeblogs.com/" target=self&gt;Mina de Blogs&lt;/a&gt;|&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-6670686599062090953?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/6670686599062090953/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=6670686599062090953' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6670686599062090953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6670686599062090953'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/chat-em-delphi.html' title='Chat em Delphi'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7262489437128684529</id><published>2008-08-09T11:29:00.001-07:00</published><updated>2008-08-09T11:29:57.164-07:00</updated><title type='text'>Pascal para iniciantes, o vídeo</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;HI,&lt;br /&gt;&lt;br /&gt;Acabei de assistir esse vídeo e tou com dificuldade até agora para respirar. É muito hilário, hehehe.&lt;br /&gt;&lt;br /&gt;Vejam o quanto é complicado determinar se um número é primo ou não.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/DxK3TU42zeU&amp;amp;hl=en"&gt;&lt;embed src="http://www.youtube.com/v/DxK3TU42zeU&amp;hl=en" type="application/x-shockwave-flash" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Até a próxima.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://dprogrammer.blogspot.com/2008/06/pascal-para-iniciantes-o-vdeo.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Apoio |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;Tips For Blogs&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Belas Mulheres&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker e Seguranca&lt;/a&gt;| &lt;a href="http://www.minadeblogs.com/" target=self&gt;Mina de Blogs&lt;/a&gt;|&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7262489437128684529?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7262489437128684529/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7262489437128684529' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7262489437128684529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7262489437128684529'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/pascal-para-iniciantes-o-vdeo.html' title='Pascal para iniciantes, o vídeo'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1937472373420873293</id><published>2008-08-09T09:04:00.001-07:00</published><updated>2008-08-09T09:04:58.244-07:00</updated><title type='text'>Vídeos sobre desenvolvmento de sistemas</title><content type='html'>&lt;style type="text/css"&gt;body {margin:0; padding:0; background:#fff; color:#000}td,body,.form {font-family:Tahoma; letter-spacing:1.1lm;font-size: 9pt}A {color:#336699; text-decoration: none;}&lt;/style&gt;&lt;div style="margin:5px; padding:5px;"&gt;&lt;div ID=divbody &gt;HI,&lt;br /&gt;&lt;br /&gt;Vou colocar aqui os links de alguns vídeos que achei sobre programação.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/pivaggi/delphi-7-dicas-parte-1-video_df8a7e97e.html"&gt;Delphi 7 - Dicas (Parte 1)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/pivaggi/delphi-7-dicas-parte-2-video_2d1ae9343.html"&gt;Delphi 7 - Dicas (Parte 2)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/mastergaurav/aspnet-web-service-hello-world-with-audio-video_aedbf0ca0.html"&gt;ASP.Net Web Service - Hello World (With Audio)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/70k0/the-basics-of-java-programming-video_24ab015cb.html"&gt;The Basics Of Java Programming&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/dextercowley/eclipse-and-java-for-total-beginners-video_626cf45ad.html"&gt;Eclipse and Java for Total Beginners&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/belgampaul/tutorial-creating-web-services-with-netbeans-video_a2987cdf7.html"&gt;Tutorial "creating web services" with NetBeans&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/googledevelopers/uploading-youtube-videos-with-the-php-client-library-video_8926ec3d8.html"&gt;Uploading YouTube Videos with the PHP Client Library&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/cbirdieuk/php-file-upload-video_0e3dc6566.html"&gt;PHP file upload&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/davidmbush/datasets-and-storedprocedures-in-visual-studio-2008-video_6a9e2f959.html"&gt;DataSets and StoredProcedures in Visual Studio 2008&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/ramonduraes/migrando-para-net-framework-visual-studio-2008-video_ce9f8182a.html"&gt;Migrando para .NET Framework - Visual Studio 2008&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipsinaction.com/ramonduraes/qualidade-em-projetos-de-software-video_83ce68422.html"&gt;Qualidade em projetos de software&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Espero que aproveitem os vídeos.&lt;br /&gt;&lt;br /&gt;Até a próxima.&lt;/div&gt;&lt;br&gt;&lt;table cellpadding=0 cellspacing=1&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt; Veja artigo completo &lt;a href="http://dprogrammer.blogspot.com/2008/08/vdeos-sobre-desenvolvmento-de-sistemas.html" target=self&gt;aqui&lt;/a&gt;&lt;br/&gt; Apoio |&lt;a href="http://tips-blogs.blogspot.com/" target=self&gt;Tips For Blogs&lt;/a&gt;| &lt;a href="http://belezasunicas.blogspot.com/" target=self&gt;Belas Mulheres&lt;/a&gt;| &lt;a href="http://hackereseguranca.blogspot.com/" target=self&gt;Hacker e Seguranca&lt;/a&gt;| &lt;a href="http://www.minadeblogs.com/" target=self&gt;Mina de Blogs&lt;/a&gt;|&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1937472373420873293?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1937472373420873293/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1937472373420873293' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1937472373420873293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1937472373420873293'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2008/08/vdeos-sobre-desenvolvmento-de-sistemas.html' title='Vídeos sobre desenvolvmento de sistemas'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-4278036850766821072</id><published>2007-12-24T09:56:00.000-08:00</published><updated>2007-09-10T04:59:47.556-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='listar'/><category scheme='http://www.blogger.com/atom/ns#' term='alias'/><title type='text'>Listando informações dos Aliases</title><content type='html'>Com o código abaixo você poderá desenvolver um pequeno aplicativo para obter informações dos aliases contidos em sua máquina. Inicie uma nova aplicação. Insira no formulário, 4 componentes do tipo TLabel e um TListBox. No evento OnCreate do objeto Form1 digite o seguinte código:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;procedure TForm1.FormCreate(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;Session.GetAliasNames(ListBox1.Items);&lt;br /&gt;end;&lt;br /&gt;Agora no evento OnClick do componente ListBox insira:&lt;br /&gt;procedure TForm1.ListBox1Click(Sender: TObject);&lt;br /&gt;var&lt;br /&gt;tStr: array[0..100] of char;&lt;br /&gt;Desc: DBDesc;&lt;br /&gt;begin&lt;br /&gt;if ListBox1.Items.Count = 0 then&lt;br /&gt;exit;&lt;br /&gt;StrPLCopy(tStr, ListBox1.Items.Strings[ListBox1.ItemIndex], High(tStr));&lt;br /&gt;DbiGetDatabaseDesc(tStr, @Desc);&lt;br /&gt;with Desc do&lt;br /&gt;begin&lt;br /&gt;Label1.Caption := StrPas(Desc.szName);&lt;br /&gt;Label2.Caption := StrPas(Desc.szPhyName);&lt;br /&gt;Label3.Caption := StrPas(Desc.szDbType);&lt;br /&gt;Label4.Caption := StrPas(Desc.szText);&lt;br /&gt;end;&lt;br /&gt;end;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-4278036850766821072?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/4278036850766821072/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=4278036850766821072' title='10 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4278036850766821072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4278036850766821072'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/03/listando-informaes-dos-aliases.html' title='Listando informações dos Aliases'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-5086750399449565857</id><published>2007-10-15T13:20:00.000-07:00</published><updated>2007-11-12T06:41:58.219-08:00</updated><title type='text'>Tools for the Development Team (2)</title><content type='html'>&lt;p&gt;&lt;a href="http://lh4.google.com/Steve.Peacocke/RxPLmK3czhI/AAAAAAAABDU/MkHG6wzuytM/coffeeprocess10.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="304" alt="coffeeprocess" src="http://lh3.google.com/Steve.Peacocke/RxPLm63cziI/AAAAAAAABDc/gGnNmTRZpBo/coffeeprocess_thumb8.jpg" width="404" align="right" border="0" /&gt;&lt;/a&gt;To continue where I left off, the management team, of which I am a member, looked at Jira in a totally different manner. Each person had their own needs for a tool ever so slightly different to Jira. This caused some problems as I was then asked to evaluate a number of other tools that, perhaps with some compromise, everyone can use. Some suggestions were forthcoming and I dutifully took at look at each one. &lt;/p&gt;  &lt;p&gt;The problem with the approach that I made to the management team was that I had obviously failed to impress what the development team needed in the tool. You see, I was out to sell the tool to the rest of the company and in doing so I was focusing on their needs instead of the development team's. This meant that instead of learning how the development team were going to contribute and communicate better, they were thinking "how can I use this new tool", which invariably led to "I need this tool to do X, and I know one that does X much better than this". Of course, that meant that they were thinking of their own needs and Jira just didn't cut it for them. Dang, I missed the plot there.&lt;/p&gt;  &lt;p&gt;I got suggestions to consider like Phpaga (&lt;a href="http://www.phpaga.net"&gt;http://www.phpaga.net&lt;/a&gt;). This is an excellent tool for contacts, invoices, financials, and billing tasks, but it has little to nothing to do with the development process. After discussing this and writing up a small review for the management team I suggested that a CRM package was more in line. They have one so will look again at using it effectively. &lt;/p&gt;  &lt;p&gt;Almost all applications I looked at served a single particular purpose, and added some other purposes somewhere along the scale of between "ok" and "that really sucks". &lt;/p&gt;  &lt;p&gt;So lesson learned. What I should have done is sold it as a development tool. I could have shown the management team how much better the development team was going to be, how much more accountable, how they will now get both statistics and answers from this bunch of strange speaking weirdos that did things magical and totally unknown things that produced the final products. Now they might understand what's going on there and the tool will be well supported.&lt;/p&gt;  &lt;p&gt;As I stated in my last email, I have a number of tools that I will touch on briefly over the next few posts, but as you might have guessed, we have finally decided on Jira. Surprisingly that decision was not made by me. The development team were also asked to review a few of the more successful tools and give their feedback but it was their own decision that we should go with Jira. While Jira did not have the nicest interface or the best reports, and it was only an issues register, it was voted in as the tool to use.&lt;/p&gt;Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-5086750399449565857?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/5086750399449565857/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=5086750399449565857' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5086750399449565857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5086750399449565857'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/10/tools-for-development-team-2.html' title='Tools for the Development Team (2)'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-3758550657804281483</id><published>2007-10-11T14:47:00.000-07:00</published><updated>2007-11-12T06:42:01.769-08:00</updated><title type='text'>Tools for the Development Team</title><content type='html'>&lt;p&gt;We placed Jira onto our live server and began using it for real about 2 weeks ago now. So how's it going? Rather well as it turns out.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;(Jira is from Atlassian (&lt;/em&gt;&lt;a title="http://www.atlassian.com/software/jira/" href="http://www.atlassian.com/software/jira/"&gt;&lt;em&gt;http://www.atlassian.com/software/jira/&lt;/em&gt;&lt;/a&gt;&lt;em&gt;) and is an issue tracker tool, see earlier posts for discussions.)&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I did a demo for the Development Team and they took to it like a duck to water, now that they understood what it's used for and how. I did the same for the rest of the Management Team and they took to it as well, but in a different way.&lt;/p&gt;  &lt;p&gt;Initially it was not used as well as I'd have liked so I put a little pressure on the team by being a bit of a pain in the neck for a couple of days..&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;Me&lt;/strong&gt;: "What are you working on?"&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;Developer&lt;/strong&gt;: "I'm updating xyz here that needs a new abc because Freda from WxyCorp has found a glitch with it"&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;Me&lt;/strong&gt;: "I don't see this in Jira, have you added it?"&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;Developer&lt;/strong&gt;: "Um... (ticidatacida) .. I have now (grin)"&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;Me&lt;/strong&gt;: "Oh, OK then. You know that if you are working on anything, no matter what it is, it .."&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;Developer&lt;/strong&gt;: ".. yea yea, I know, - ..'it needs to be in Jira' (sigh)"&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The developers are good guys and they really understood the reasons for putting everything in Jira but being developers, they wanted to just develop. Now I note that no-one is working on anything without a Jira issue and they themselves police that nicely by suggesting that others create a Jira issue before they can start on any work. Nice.&lt;/p&gt;  &lt;p&gt;This means of course, that all work is logged and reporting and reviewing can be carried out. Issues are assigned to others with questions when more information is needed, and they get an email to tell them when the issue is reassigned back to them with the answer. Once the have completed the work, they "Resolve" the issue and assign it to the QA Manager. Only the QA Manager and myself as Administrator, can "Close" an issue.&lt;/p&gt;  &lt;p&gt;The Management Team has been impressed with Jira but they all have their own ideas of other tools that would work better for what they want to do. Some other tools that I have looked at are...&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;SourceForge Enterprise - &lt;a title="http://sf.net/powerbar/sfee/" href="http://sf.net/powerbar/sfee/"&gt;http://sf.net/powerbar/sfee/&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Trac - &lt;a title="http://trac.edgewall.org/" href="http://trac.edgewall.org/"&gt;http://trac.edgewall.org/&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Mingle - &lt;a title="http://studios.thoughtworks.com/mingle-project-intelligence" href="http://studios.thoughtworks.com/mingle-project-intelligence"&gt;http://studios.thoughtworks.com/mingle-project-intelligence&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Confluence - &lt;a title="http://www.atlassian.com/software/confluence/" href="http://www.atlassian.com/software/confluence/"&gt;http://www.atlassian.com/software/confluence/&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;FDDTracker - &lt;a title="http://www.itps.com.au/dotnetnuke/" href="http://www.itps.com.au/dotnetnuke/"&gt;http://www.itps.com.au/dotnetnuke/&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Other areas I have also look at with a mind to solving some other issues here, they include...&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;TrueCrypt - &lt;a title="http://www.truecrypt.org/" href="http://www.truecrypt.org/"&gt;http://www.truecrypt.org/&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;AllSync - &lt;a title="http://www.allsync.biz/help/a_produktbeschreibung.htm" href="http://www.allsync.biz/help/a_produktbeschreibung.htm"&gt;http://www.allsync.biz/help/a_produktbeschreibung.htm&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;SyncToy - &lt;a title="http://www.microsoft.com/windowsxp/using/digitalphotography/prophoto/synctoy.mspx" href="http://www.microsoft.com/windowsxp/using/digitalphotography/prophoto/synctoy.mspx"&gt;http://www.microsoft.com/windowsxp/using/digitalphotography/prophoto/synctoy.mspx&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;and I'll hope to have others added to that list soon.&lt;/p&gt;  &lt;p&gt;I'll talk on each of those and our eventual decisions as I go along in other posts. In the meantime, I'd like to hear what tools you are using with your team or even on your own to help with development and running a software team.&lt;/p&gt;Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-3758550657804281483?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/3758550657804281483/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=3758550657804281483' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3758550657804281483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3758550657804281483'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/10/tools-for-development-team.html' title='Tools for the Development Team'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-8279961501254048362</id><published>2007-10-05T01:30:00.000-07:00</published><updated>2007-10-16T07:55:58.563-07:00</updated><title type='text'>Firebird System Tables (Part IV)</title><content type='html'>The system table for stored procedure is like here. The purpose of this view is the same like in &lt;a href="http://firebird-with-delphi.blogspot.com/2007/09/firebird-system-table-part-ii.html"&gt;Firebird System Table (Part II)&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;CREATE VIEW "vSYS_FindProcSource"(&lt;br /&gt;    "procName",&lt;br /&gt;    "procSource")&lt;br /&gt;AS&lt;br /&gt;select r.rdb$procedure_name, r.rdb$procedure_source&lt;br /&gt;from rdb$procedures r&lt;br /&gt;where r.rdb$system_flag = 0;&lt;/span&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-8279961501254048362?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/8279961501254048362/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=8279961501254048362' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8279961501254048362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8279961501254048362'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/10/firebird-system-tables-part-iv.html' title='Firebird System Tables (Part IV)'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-3063602725264702442</id><published>2007-09-29T04:48:00.000-07:00</published><updated>2007-10-16T07:55:59.399-07:00</updated><title type='text'>Firebird 2.0.3 is released</title><content type='html'>On 26 September 2007, Firebird version 2.0.3 is released, you can download in &lt;a href="http://www.firebirdsql.org/index.php?op=files&amp;id=engine_203"&gt;here&lt;/a&gt;. This version is only bug fixed version from   FB 2.0Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-3063602725264702442?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/3063602725264702442/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=3063602725264702442' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3063602725264702442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3063602725264702442'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/firebird-203-is-released.html' title='Firebird 2.0.3 is released'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1287091347199790836</id><published>2007-09-27T20:57:00.000-07:00</published><updated>2007-11-12T06:42:02.764-08:00</updated><title type='text'>Installing Jira - The Development Support Tool</title><content type='html'>&lt;p&gt;We are a relatively small (less than 20 employees) software development house with about half a dozen mainline products as well as any number of consulting projects going on. We have some very big name clients in several countries and therefore need to ensure work is completed on time and efficiently.&lt;/p&gt;  &lt;p&gt;While there are normal enhancement projects and major installation projects going on, there are also a number of items that come up for customers wanting changes or where something doesn't go quite as planned. These can disrupt the programmers day and disturb the development of future enhancements or otherwise frustrate the project timelines.&lt;/p&gt;  &lt;p&gt;We have a web based system for clients to record requests and log bugs. This is monitored by our support staff and an email is fired off to developers where necessary.&lt;/p&gt;  &lt;p&gt;All this means that as more emails come in, the developer has to judge the urgency of the email and either drop everything to perform that task, or note that this is another item that he has to do in the future. While they are very good at what they do, I was concerned for several reasons.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I don't have a view on what a developer is doing at any time, or what he has done &lt;/li&gt;    &lt;li&gt;I don't have any way to tell what the workload of a particular developer is. This means I don't know to spread the load between developers when one is overloaded and another is just doing some normal housework &lt;/li&gt;    &lt;li&gt;Programmers can easily forget tasks &lt;/li&gt;    &lt;li&gt;It doesn't assist in any process to development &lt;/li&gt;    &lt;li&gt;I can't plan to ensure enough resources are available. &lt;/li&gt;    &lt;li&gt;I could go on, but you get the idea... &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Generally though, it makes the whole development area invisible to me as the manager.&lt;/p&gt;  &lt;p&gt;I knew that I needed to install a development process, but I knew immediately, I needed a tool to give me the visibility on what's being worked on work to correctly design a development process. I had used Jira before so the decision was an easy one for me. Setting it up was easy and done in minutes, but I wanted a number of changes to the permission and notification schemes, then it was a matter if creating some projects. Done.&lt;/p&gt;  &lt;p&gt;It worked well and I installed a testing project so that people can try out the system without disturbing real work.&lt;/p&gt;  &lt;p&gt;Its been installed now for about a week but the uptake has not been immediate. I'll have to do a demo on Monday to show everyone how it works, assure them that its not going to take over their day with mundane admin tasks, and finally show them a few neat wow bits. After that I'll be enforcing the use of it for the next month.&lt;/p&gt;  &lt;p&gt;If, after that trial, no-one is convinced, then I'll take it away, but I'll need to know what to replace it with if that is the case. There seems to be a few main problems with installing this work request system that I'll have to overcome. These include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font color="#0000ff"&gt;It seems like more work for no reason.&lt;/font&gt; While it may take a minute or less to create a new Jira issue, there are huge benefits for the user, the company, and the client - get over it.&lt;/li&gt;    &lt;li&gt;&lt;font color="#0000ff"&gt;Its a way for the boss to monitor my work so he can breathe down my neck.&lt;/font&gt; In fact, its a way to STOP the boss breathing down your neck as he can see what's going on instead of bugging you every half hour. As for monitoring, your not that interesting that I want to spend all my time "monitoring" what you are doing "right now", I'm a lot busier than that but a quick glance to review workloads will tell me if you have too much work and need help.&lt;/li&gt;    &lt;li&gt;&lt;font color="#0000ff"&gt;I get lots of little emails from lots of people wanting me to do things that only take a minute or two, why should I have to put all these into Jira?.&lt;/font&gt; By putting these into Jira, these little jobs will not only show you how much time they take up, but you will never, ever forget to do them. I have set up an email for each project in Jira, simply forward to the email to that address and it'll create your Jira issue instantly.&lt;/li&gt;    &lt;li&gt;&lt;font color="#0000ff"&gt;I'm a senior developer, surely "I" don't have to do this. &lt;/font&gt;Yes, sadly I'm afraid that you do.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I'm sure that once everyone is using it and the advantages are being seen, then it'll resolve any arguments. To be fair, no argument have been forthcoming, but I can sense what's not being said at times. They are a great bunch or people that I enjoy working with, I just think I can make life easier for them with this tool. I'll let you know how it goes.&lt;/p&gt;Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1287091347199790836?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1287091347199790836/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1287091347199790836' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1287091347199790836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1287091347199790836'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/installing-jira-development-support.html' title='Installing Jira - The Development Support Tool'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-954734242931861789</id><published>2007-09-26T20:04:00.000-07:00</published><updated>2007-10-16T07:56:01.926-07:00</updated><title type='text'>Installing ZeosDBO in Delphi (rev version)</title><content type='html'>I already make some revision on my previous post about how to install ZeosDBO components in Delphi. The revision link is &lt;a href="http://firebird-with-delphi.blogspot.com/2007/07/installing-zeosdbo.html"&gt;here&lt;/a&gt;. ZeosDBO is one of the direct connection components to many RDBMS including Firebird. The idea of ZeosDBO is like JDBC, and to switch from one database to another database is really easy, find it by yourself after trying this amazing components. One thing, this component is FREE and OPEN SOURCEFonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-954734242931861789?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/954734242931861789/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=954734242931861789' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/954734242931861789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/954734242931861789'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/installing-zeosdbo-in-delphi-rev.html' title='Installing ZeosDBO in Delphi (rev version)'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-1038475450461408402</id><published>2007-09-26T19:49:00.000-07:00</published><updated>2007-10-16T07:56:02.964-07:00</updated><title type='text'>Firebird System Tables (Part III rev 1)</title><content type='html'>Here is some revision (from Romkin idea) to the query of Firebird System Tables part III.&lt;br /&gt;In this query, it doesn't need anymore to has "case" statement to get the convertion from numeric type_name to more readable name. And I want to say thank you for the supporting comment on this little articles. Once correction from Milan Babuskov that told me "CONTAINING" is in Firebird since the first versions 1.0. Hope all articles in this blog can be usefull for FB community. Wait for the next Firebird System Tables again, stay tune on the same channel he..he..he.. :)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;CREATE VIEW "vSYS_FindDependencies"(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependentName",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependentType",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependedOnName",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependedOnFieldName",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependedOnType")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;select d.RDB$DEPENDENT_NAME DEPENDENT_NAME,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;       (select t.RDB$TYPE_NAME from RDB$TYPES t&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        where d.RDB$DEPENDENT_TYPE=t.RDB$TYPE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;              and t.RDB$FIELD_NAME = 'RDB$OBJECT_TYPE'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;       ) DEPENDENT_TYPE,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;       d.RDB$DEPENDED_ON_NAME DEPENDED_ON_NAME, d.RDB$FIELD_NAME DEPENDED_ON_FIELD_NAME,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;       (select t.RDB$TYPE_NAME from RDB$TYPES t&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        where d.RDB$DEPENDED_ON_TYPE=t.RDB$TYPE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;              and t.RDB$FIELD_NAME = 'RDB$OBJECT_TYPE'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;       ) DEPENDED_ON_TYPE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;from RDB$DEPENDENCIES d&lt;/span&gt;&lt;/span&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-1038475450461408402?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/1038475450461408402/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=1038475450461408402' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1038475450461408402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/1038475450461408402'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/firebird-system-tables-part-iii-rev-1.html' title='Firebird System Tables (Part III rev 1)'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-4318187949107440621</id><published>2007-09-24T02:01:00.000-07:00</published><updated>2007-11-12T06:42:51.483-08:00</updated><title type='text'>Finally closing this blog</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;Well, it is about time to close this blog officially, however, not without starting a new blog on my own server. So yes, I will start blogging again and I will write about Programming with Delphi (and C#) as well as other aspects of my life.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;The new blog supports categories and is just starting, so you have not missed anything so far ;-)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;To read my new blog, go to &lt;a href="http://www.gumpi.com/"&gt;http://www.gumpi.com/&lt;/a&gt; and start reading.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;Thanks to all readers in the past, and hello to all readers to come.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;strong&gt;* * * THIS BLOG IS CLOSED NOW * * *&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;Fonte: http://delphi-notes.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-4318187949107440621?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/4318187949107440621/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=4318187949107440621' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4318187949107440621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4318187949107440621'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/finally-closing-this-blog.html' title='Finally closing this blog'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-2421995833973417313</id><published>2007-09-20T21:12:00.000-07:00</published><updated>2007-10-16T07:56:03.859-07:00</updated><title type='text'>Firebird System Tables (Part III)</title><content type='html'>This article idea (Part III) is belong to the someone that put comment on my previous article, so I just accomodate his/her idea. And I already arrange to become a view like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;CREATE VIEW "vSYS_FindDependencies"(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependentName",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependentType",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependedOnName",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependedOnFieldName",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "dependedOnType")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  select RDB$DEPENDENT_NAME,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         case RDB$DEPENDENT_TYPE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 0 then 'Table'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 1 then 'View'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 2 then 'Trigger'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 3 then 'Computed field'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 4 then 'Validation'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 5 then 'Procedure'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 6 then 'Expression index'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 7 then 'Exception'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 8 then 'User'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 9 then 'Field'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 10 then 'Index'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 14 then 'Generator'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           else RDB$DEPENDENT_TYPE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         end DEPENDENT_TYPE,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         RDB$DEPENDED_ON_NAME, RDB$FIELD_NAME,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         case RDB$DEPENDED_ON_TYPE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 0 then 'Table'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 1 then 'View'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 2 then 'Trigger'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 3 then 'Computed field'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 4 then 'Validation'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 5 then 'Procedure'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 6 then 'Expression index'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 7 then 'Exception'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 8 then 'User'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 9 then 'Field'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 10 then 'Index'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           when 14 then 'Generator'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;           else RDB$DEPENDED_ON_TYPE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         end DEPENDED_ON_TYPE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  from RDB$DEPENDENCIES;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The idea is to know the dependency on some entity  in the database.  Perhaps it is also usefull for everyone.Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-2421995833973417313?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/2421995833973417313/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=2421995833973417313' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2421995833973417313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2421995833973417313'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/firebird-system-tables-part-iii.html' title='Firebird System Tables (Part III)'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-3312524004895629735</id><published>2007-09-20T14:37:00.000-07:00</published><updated>2007-11-12T06:42:03.754-08:00</updated><title type='text'>Back again</title><content type='html'>&lt;p&gt;Thanks for your patience, I have finally shifted house and started my new role as Software Development Manager for a software house in Hamilton.&lt;/p&gt;  &lt;p&gt;The shift included a few days in Wellington visiting friends and generally spending time away. Holidays have been a very rare occurrence for me, having at one time, spent more than 12 years without a holiday, I find that taking a break occasionally is a requirement.&lt;/p&gt;  &lt;p&gt;The new role is interesting. Based on Oracle technologies the product is a very stable and sizeable system. The team contains some excellent technical expertise and I will be working hard to install some processes and a decent methodology to ensure that they are supported as much as possible.&lt;/p&gt;  &lt;p&gt;That's all for now as I'm still finding my feet here. &lt;/p&gt; Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-3312524004895629735?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/3312524004895629735/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=3312524004895629735' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3312524004895629735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3312524004895629735'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/back-again.html' title='Back again'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-6222498819450341486</id><published>2007-09-19T20:51:00.000-07:00</published><updated>2007-10-16T07:56:06.273-07:00</updated><title type='text'>Firebird System Table (Part II)</title><content type='html'>Another FB system table is system table for trigger. The reason I create this view is to scan for some code inside the  source of the trigger. For example, I want to change  the field  type of table A, then I want to know, this field is being used by which trigger, so I can search thorough this view:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;CREATE VIEW "vSYS_FindTriggerSource"(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "triggerName",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "tableName",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "triggerInactive",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    "triggerSource")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;select r.rdb$trigger_name, r.rdb$relation_name, r.rdb$trigger_inactive, r.rdb$trigger_source&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;from rdb$triggers r&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;where r.rdb$system_flag = 0&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you want to seach some text in the trigger source then you can use this simple query:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;select *&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;from "vSYS_FindTriggerSource"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;where "triggerSource" containing 'some_field'&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The keyword "containing" here (if I'm not forget) is exists from FB 2. The difference between "containing" and "like" is the "like" is case sensitive where "containing" is case insensitive, and also you not need the "%" sign like in "like" keyword.&lt;br /&gt;&lt;br /&gt;That view also display the status of the trigger, if the "triggerInactive" field value is zero, then it means that trigger is active and vice versa.Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-6222498819450341486?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/6222498819450341486/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=6222498819450341486' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6222498819450341486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6222498819450341486'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/firebird-system-table-part-ii.html' title='Firebird System Table (Part II)'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-8293818482462393000</id><published>2007-09-17T23:06:00.000-07:00</published><updated>2007-10-16T07:56:09.203-07:00</updated><title type='text'>Firebird System Tables (Part I)</title><content type='html'>Hi, whew it's has been long time since my last time post, yes I  a little bit busy now, with some of my own project and some of my family work. Ok, now I want to share about Firebird System Tables, they are tables that side on every FB database that consist of metadata of user tables (table that you created), many question about this and also many purpose to know about this.&lt;br /&gt;&lt;br /&gt;I often use this technique when I develop a database that consist of many tables and where there is an error on one of the field and then I must know this field is belong on which table, to solve that problem, I create a view like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;CREATE VIEW "vSYS_FindField"(&lt;br /&gt;"tableName",&lt;br /&gt;"fieldName",&lt;br /&gt;"default_val")&lt;br /&gt;AS&lt;br /&gt;select r.rdb$relation_name, f.rdb$field_name, f.rdb$default_source&lt;br /&gt;from RDB$RELATIONS r, RDB$RELATION_FIELDS f&lt;br /&gt;where r.rdb$system_flag = 0&lt;br /&gt;   and r.rdb$relation_name=f.rdb$relation_name;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;The FB System Tables can be known from "RDB$RELATIONS.RDB$SYSTEM_FLAG" greater than 0 (zero). The "RDB$RELATIONS" is a system table for user table and user view (off course it also contain of many things that you can look by yourself ;P) And "RDB$RELATION_FIELDS" is as you may guess is a system table for user field.  It's now up to you to improve that query, maybe you want to include some more information, then go ahead :)&lt;br /&gt;&lt;br /&gt;NB: Thank's Romkin for the correction, now I already applied your correction in this short article :)Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-8293818482462393000?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/8293818482462393000/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=8293818482462393000' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8293818482462393000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8293818482462393000'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/firebird-system-tables-part-i.html' title='Firebird System Tables (Part I)'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-4147113097554109606</id><published>2007-09-09T13:47:00.000-07:00</published><updated>2007-11-12T06:42:04.509-08:00</updated><title type='text'>Returning the outer directory</title><content type='html'>Returning the directory before the current one should be a simple one-line call but I have so often seen a number of very highly convoluted ways of finding the last slash (\) in the directory string and using copy() and other ways that I have decided to relate a simple and direct way to obtain any or all directories prior to, and including the current one.&lt;br /&gt;&lt;br /&gt;The problem with finding the last slash is that you have to watch out for cases where the current directory is a root directory. The good news is that you can ignore all of that.&lt;br /&gt;&lt;br /&gt;You should know that finding the currently running exe program name including directories is Application.ExeName found in SysUtils. This should return something like..&lt;br /&gt;&lt;br /&gt;C:\Program Files\CodeGear\Delphi\5.0\bin\MyProgram.exe&lt;br /&gt;&lt;br /&gt;Of course the directory structure may be different as I'm sure you're not running your programs in the Delphi \bin directory :o)&lt;br /&gt;&lt;br /&gt;But to get the directory that MyProgram.exe is running in, the call is ExtractFileDir(Application.ExeName). This returns..&lt;br /&gt;&lt;br /&gt;C:\Program Files\CodeGear\Delphi\5.0\bin&lt;br /&gt;&lt;br /&gt;ExtractFilePath() dies something similar. It simply returns the string up to the last delimiter (the slash). In other words, anything past the last delimiter is ignored as it is assumed to be the program name. Excellent, this means that we can use that fact on the above directory structure to return the previous directory.&lt;br /&gt;&lt;br /&gt;&lt;font color="blue"&gt;PreviousDir := ExtractFilePath(ExtractFileDir(Application.ExeName));&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;This should return a directory structure of&lt;br /&gt;C:\Program Files\CodeGear\Delphi\5.0\&lt;br /&gt;&lt;br /&gt;We can continue to use ExtractFileDir() to return each directory in the tree until we reach the root directory (perhaps checking if PreviousDir = LastDir?). For example:&lt;br /&gt;&lt;br /&gt;&lt;font color="blue"&gt;Dir := ExtractFilePath(ExtractFileDir(ExtractFileDir(Application.ExeName)));&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Should return one directory up from the previous dir, or in this case: &lt;br /&gt;C:\Program Files\CodeGear\Delphi\&lt;br /&gt;&lt;br /&gt;So there you have it. A single call that returns the previous directory without having to bother with searching for the slash or worrying about the root directory issue.Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-4147113097554109606?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/4147113097554109606/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=4147113097554109606' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4147113097554109606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4147113097554109606'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/returning-outer-directory.html' title='Returning the outer directory'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7012900080369608238</id><published>2007-09-06T04:43:00.000-07:00</published><updated>2007-11-12T06:42:05.311-08:00</updated><title type='text'>Accessing Interbase/Firebird Metadata in Delphi</title><content type='html'>&lt;i&gt;&lt;b&gt;WARNING:&lt;/b&gt; Interbase and Firebird system tables are not for the faint hearted. It is not recommended that you alter anything in these tables if you ever want to use them again - and keep your job. Major stuff-ups can occur.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I was looking at some old Delphi 7 code of mine when I was attempting to get in behind the scenes of Interbase and Firebird tables and fields to learn a little more about them. I came across these little pieces of information I'd like to share.&lt;br /&gt;&lt;br /&gt;The following will list all the tables in one grid and, for each table, list all the fields in another grid. Drop on your TIBDatabase and direct it at your Interbase or Firebird server.&lt;br /&gt;&lt;br /&gt;Now drop a TIBTransaction, TIBQuery, TDataSource, and a TDBGrid and connect them all. &lt;br /&gt;&lt;br /&gt;Enter the following query into the IBQuery1...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="Blue"&gt;  SELECT DISTINCT RDB$RELATION_NAME as MyTable&lt;br /&gt;  FROM RDB$RELATION_FIELDS&lt;br /&gt;  WHERE RDB$SYSTEM_FLAG=0 &lt;br /&gt;  AND RDB$VIEW_CONTEXT IS NULL&lt;br /&gt;  ORDER BY RDB$RELATION_NAME&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and make IBQuery1 live. Now drop on another TDBGrid, TIBQuery and TDataSource and connect them. This time, select IBQuery2 and add TDataSource1 in the "DataSource" Property. This will ensure that the second query will look to the first query to fill in the parameters. That parameter will be the field MyTable.&lt;br /&gt;&lt;br /&gt;Enter the following query string into the SQL property of IBQuery2...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="Blue"&gt;  SELECT RDB$FIELD_NAME AS FIELDS&lt;br /&gt;  FROM RDB$RELATION_FIELDS&lt;br /&gt;  WHERE RDB$RELATION_NAME = :MyTable&lt;br /&gt;  ORDER BY RDB$FIELD_POSITION&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and make that query live. When you run that program, selecting tables in the first grid will show all the field information for that table in the second grid.&lt;br /&gt;&lt;br /&gt;So far I have the following types in the field RDB$FIELD_TYPE. These can translate to... &lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;8 = Integer   &lt;br /&gt;&lt;li&gt;10 = Float    &lt;br /&gt;&lt;li&gt;12 = Date     &lt;br /&gt;&lt;li&gt;13 = Time     &lt;br /&gt;&lt;li&gt;14 = Char     &lt;br /&gt;&lt;li&gt;35 = TimeStamp&lt;br /&gt;&lt;li&gt;37 = VarChar  &lt;br /&gt;&lt;li&gt;261 = Blob&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;There'll be a definitive list somewhere but that's all I have needed so far. I got that list from the internet somewhere but it was so long ago that I have forgotten where (thanks to whoever that was).&lt;br /&gt;&lt;br /&gt;That will get you started, but here are some other queries that will return more metadata information...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Return indexes for a table&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="Blue"&gt;  SELECT RDB$INDEX_NAME &lt;br /&gt;  FROM RDB$INDICES &lt;br /&gt;  WHERE RDB$RELATION_NAME = :MyTable&lt;br /&gt;  AND RDB$UNIQUE_FLAG IS NULL &lt;br /&gt;  AND RDB$FOREIGN_KEY IS NULL&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Return all Generators&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="Blue"&gt;  SELECT RDB$GENERATOR_NAME &lt;br /&gt;  FROM RDB$GENERATORS &lt;br /&gt;  WHERE RDB$SYSTEM_FLAG IS NULL&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Return all Triggers&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="Blue"&gt;  SELECT * FROM &lt;br /&gt;  RDB$TRIGGERS &lt;br /&gt;  WHERE RDB$SYSTEM_FLAG IS NULL&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;  &lt;br /&gt;The shifters are coming in the morning so I'll post this now, please excuse any typing errors. Enjoy your day.&lt;br /&gt;&lt;br /&gt;Remember: &lt;i&gt;A positive attitude may not solve all your problems, but it will annoy enough people to make it worth the effort. Herm Albright (1876 - 1944)&lt;/i&gt;Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7012900080369608238?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7012900080369608238/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7012900080369608238' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7012900080369608238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7012900080369608238'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/accessing-interbasefirebird-metadata-in.html' title='Accessing Interbase/Firebird Metadata in Delphi'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-6659702607324142921</id><published>2007-09-04T13:12:00.000-07:00</published><updated>2007-11-12T06:42:06.060-08:00</updated><title type='text'>Scrolling to the right place in TMemo</title><content type='html'>After programmatically inserting a number of lines I find that the TMemo will show at the last line as it normally should. However, sometimes what I really want is for TMemo to move to the first line, or perhaps even move to the top of the last lot of inserted lines.&lt;br /&gt;&lt;br /&gt;Here are a few little gems I have picked up on my travels that work a treat.&lt;br /&gt;&lt;br /&gt;Move to a particular line in a Memo...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color=blue&gt;function MemoMoveToLine(LineNo: integer);&lt;br /&gt;begin&lt;br /&gt;    with Memo1 do&lt;br /&gt;    begin&lt;br /&gt;        SelStart := Perform(EM_LINEINDEX, LineNo, 0);&lt;br /&gt;        Perform(EM_SCROLLCARET, LinePos, 0);&lt;br /&gt;    end;&lt;br /&gt;end;&lt;/font&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;What this is doing is calling TControl.Perform. This function actually uses a Windows message to perform some task, in this case placing the cursor at a line number, and then scrolling to that line. Let's take a look at using that function...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color=blue&gt;var&lt;br /&gt;    CurrentLine: integer;&lt;br /&gt;begin&lt;br /&gt;    &lt;i&gt;// Get the current position&lt;/i&gt;&lt;br /&gt;    with Memo1 do&lt;br /&gt;        CurrentLine := Perform(EM_LINEFROMCHAR, SelStart, 0);    &lt;br /&gt;    AddLotsOfLines;&lt;br /&gt;    &lt;i&gt;// Move to the line we started at&lt;/i&gt;&lt;br /&gt;    MemoMoveToLine(CurrentLine);&lt;br /&gt;    &lt;i&gt;// Now Move to the end&lt;/i&gt;&lt;br /&gt;    MemoMoveToLine(Memo1.Lines.Count);&lt;br /&gt;    &lt;i&gt;// Now Move to the start&lt;/i&gt;&lt;br /&gt;    MemoMoveToLine(0);&lt;br /&gt;end;&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And there you have it.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Ramblings&lt;/h3&gt;&lt;br /&gt;I'm well into packing in the evenings now and surrounded by boxes. The truck comes in 2 days to take my furniture to Hamilton where I will start work as Software Development Manager about mid month. I look forward to the challange of a new team and new company.&lt;br /&gt;&lt;br /&gt;Although it will be hard to leave the Mount and this wonderful job and environment, my family is still at the Mount so I'll be back often. Its only a short drive to get here to see them and I'll probably end up with a caravan here for easy weekend stays.&lt;br /&gt;&lt;br /&gt;I'll still be codeing in Delphi for my own programs (and sanity), always have, always will. This will ensure that the blog stays relative to Delphi, although I might introduce a few new subjects as well.Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-6659702607324142921?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/6659702607324142921/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=6659702607324142921' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6659702607324142921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6659702607324142921'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/09/scrolling-to-right-place-in-tmemo.html' title='Scrolling to the right place in TMemo'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7752339663286154676</id><published>2007-08-30T13:00:00.000-07:00</published><updated>2007-11-12T06:42:07.284-08:00</updated><title type='text'>What's this Soundex in Delphi?</title><content type='html'>Delphi has a Soundex routine found in StrUtils, so why am I giving you another? This blog is about how Soundex works. understanding Soundex will help you decide how and when to use it to enhance your program. I am not suggesting for a moment that you dump the already written Soundex routine within Delphi, unless you really want to, but rather I am suggesting that this may be a way to understand how a Soundex code is put together. &lt;br /&gt;&lt;br /&gt;In the early 1980's I wrote a Soundex routine in Turbo Pascal and released it to the world through the bulletin boards that were available back then (before the Internet became readily available to the masses). By releasing it to the public domain, I was more interested in sharing than in copyrighting everything.&lt;br /&gt;&lt;br /&gt;Over the following years, to my great amusement, I found my routine copied several times, sometimes word for word, line for line including comments, with my name replaced with someone else claiming to be the author (I would not be so amused these days). As far as I could tell with the limited searching available at the time, I was the first person to write a Soundex routine entirely in Turbo Pascal, but it is a simple routine so I could easily be wrong on that count.&lt;br /&gt;&lt;br /&gt;The original Turbo Pascal source has been lost to .. well .. somewhere in that box of 5.5" floppies over in the corner there that I've been taking to the dump any day now for about the last 15 years.&lt;br /&gt;&lt;br /&gt;Soundex converts a name to four characters (one letter and three numbers). The conversion will result in the same numbers for like-sounding names. For example all the following names will all result in a Soundex code of "S530" - smith, Smith, smythe, smitt, shmidt, shmidt, snith, snyth, snythe, smmith, etc. This means that if a user enters "Smith", and I search the database for the Soundex code rather than the name "Smith", I will be presented with all those and other similar sounding names.&lt;br /&gt;&lt;br /&gt;Soundex was originally invented by Robert C. Russel and Margaret K. Odell around 1918-1922 and initially used for immigration and census information. Being before computers, the Soundex code is naturally simple so that people can calculate Soundex manually. It is used most in computer applications now. Searching your own database for names that sound like 'Smith', for spell checking and other areas.&lt;br /&gt;&lt;br /&gt;While Soundex is clever, it is not infallible so common sense must prevail. 'Clark', and 'Klark' will come out with a different Soundex code. other examples are Bate (B300), will not be the same as Bates (B320), or Gate (G300).&lt;br /&gt;&lt;br /&gt;In other instances names that really don't sound the same can sometimes, by sheer coincidence, have the same soundex code. Have you ever wondered why sometimes your spell checker wants to replace a mistyped word with something completely different and totally out of context? You are left wondering how on earth the spell checker came up with that word. Well, now you know. Its Soundex.  However, it is still clever enough for most uses.&lt;br /&gt;&lt;br /&gt;So what's the process? Well, it was simple for a reason (above) and still is. &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Take the first letter&lt;br /&gt;&lt;li&gt;Replace the letters BFPV with '1'&lt;br /&gt;&lt;li&gt;Replace the letters CGJKQSXZ with '2'&lt;br /&gt;&lt;li&gt;Replace the letters DT with '3'&lt;br /&gt;&lt;li&gt;Replace the letter L with '4'&lt;br /&gt;&lt;li&gt;Replace the letters MN with '5'&lt;br /&gt;&lt;li&gt;Replace the letter R with '6'&lt;br /&gt;&lt;li&gt;Ignore all other letters and ignore double letters (e.g. the 2 T's in "Letterman").&lt;br /&gt;&lt;li&gt;If the result is less than 4 characters, then pad out with zeros.&lt;br /&gt;&lt;li&gt;If result is greater than 4 characters then use only the first 4  &lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;And there you have your Soundex code.  &lt;br /&gt;&lt;br /&gt;There are many ways to implement Soundex and I have chosen one that I hope will allow you to follow what is happening. Take a look at the Soundex routine in StrUtils for another way.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color=blue&gt;function MySoundex(sName: string): string;&lt;br /&gt;var&lt;br /&gt;    Ch, LastCh: Char;&lt;br /&gt;    i               : integer;&lt;br /&gt;    sx              : string;&lt;br /&gt;begin&lt;br /&gt;    sName := UpperCase(trim(sName));&lt;br /&gt;    if length(sName) &lt; 1 then&lt;br /&gt;        sx := '' &lt;i&gt;// got nothing, send nothing back&lt;/i&gt;&lt;br /&gt;    else&lt;br /&gt;    begin&lt;br /&gt;        LastCh := #0;&lt;br /&gt;        for i := 1 to length(sName) do&lt;br /&gt;        begin &lt;i&gt;// step through each character in the name&lt;/i&gt;&lt;br /&gt;            if i = 1 then&lt;br /&gt;                sx := sName[1] &lt;i&gt;// store the first character&lt;/i&gt;&lt;br /&gt;            else&lt;br /&gt;            begin&lt;br /&gt;                ch := #0;&lt;br /&gt;                if sName[i] &lt;&gt; LastCh then&lt;br /&gt;                begin&lt;br /&gt;                    case sName[i] of&lt;br /&gt;                        'B', 'F', 'P', 'V': ch := '1';&lt;br /&gt;                        'C', 'G', 'J', 'K',&lt;br /&gt;                            'Q', 'S', 'X', 'Z': ch := '2';&lt;br /&gt;                        'D', 'T': ch := '3';&lt;br /&gt;                        'L': ch := '4';&lt;br /&gt;                        'M', 'N': ch := '5';&lt;br /&gt;                        'R': ch := '6';&lt;br /&gt;                        &lt;i&gt;// Note no ELSE - ignore all other letters&lt;/i&gt;&lt;br /&gt;                    end;&lt;br /&gt;                    if ch &lt;&gt; #0 then&lt;br /&gt;                        sx := sx + ch;&lt;br /&gt;                    if length(sx) &gt; 3 then&lt;br /&gt;                        break; &lt;i&gt;// we got all we need&lt;/i&gt;&lt;br /&gt;                end;&lt;br /&gt;            end;&lt;br /&gt;            LastCh := sname[i];&lt;br /&gt;        end;&lt;br /&gt;        while length(sx) &lt; 4 do&lt;br /&gt;            sx := sx + '0'; &lt;i&gt;// pad out remaining with zero&lt;/i&gt;&lt;br /&gt;    end;&lt;br /&gt;    result := sx;&lt;br /&gt;end;&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are lots of variations and improvements on that depending on what you are doing.&lt;br /&gt;&lt;br /&gt;So where would we use Soundex? One obvious way would be to give your users the ability to search for a name by the way it sounds.&lt;br /&gt;&lt;br /&gt;Consider a database full of hundreds of thousands of customers. Simply add a field to the Customer table called .. oh I don't know, how about "Soundex". Then add the soundex code for the customer surname on each customer.&lt;br /&gt;&lt;br /&gt;Because of the way Soundex works, you may find that finding all customers that sound like "Smith" may be a lot faster than finding all customers with the exact name of "Smith". How can this be? Well, since there will be less unique Soundex codes than unique surnames, the index will have less problems finding a Soundex code. Lets say that you are searching for a name in Auckland (approx 1.3 mill), an index on unique surnames will possibly total around 800,000 (&lt;i&gt;rough guess&lt;/i&gt;). However an index on unique Soundex codes for surnames may only total about 100,000 (&lt;i&gt;another wild guess with no substance at all, but you get the idea&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Ramblings&lt;/h3&gt;&lt;br /&gt;Its beautiful outside again today and although yesterday the wind was getting up a little, I can start to feel the rumblings of spring around here. Are we at last getting out of the deep dark winter that held our grip for the past few months and kept us close to our box of tissues, warm jerseys, and heaters? I hope so. It made me think of where I would be if I had accepted the offer to spend the next few years in Mongolia. I would have loved the experience of learning a new culture and language, but "The Mount" has a way of making me smile.&lt;br /&gt;&lt;br /&gt;I climbed to the top of the mount again last weekend where the view is spectacular. &lt;br /&gt;&lt;A Href="http://www.virtualoceania.net/newzealand/photos/cities/tauranga/066j.shtml"&gt;Mount Maunganui from the top of the Mount&lt;/a&gt;. It was sad to think I'll soon be moving inland to Hamilton, an hour and a half away.&lt;br /&gt;&lt;br /&gt;Have a wonderful day wherever you are and God's blessings.Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7752339663286154676?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7752339663286154676/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7752339663286154676' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7752339663286154676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7752339663286154676'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/what-this-soundex-in-delphi.html' title='What&amp;#39;s this Soundex in Delphi?'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-3404465122215244639</id><published>2007-08-22T16:32:00.000-07:00</published><updated>2007-11-12T06:42:08.278-08:00</updated><title type='text'>Have an iif() function in Delphi</title><content type='html'>There are many advantages to learning other programming languages, but there are also some problems as well. The "Immediate If" (iif) function is one of those. In most, if not all, the other languages there is an immediate if function that makes programming just a little easier and allows you to say things in much less lines. Consider the following...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font face="Times New Roman" color=blue size=2&gt;    if Str = 'Top' then&lt;br /&gt;        s := 'Woohoo!'&lt;br /&gt;    else&lt;br /&gt;        s := 'Climb some more';&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;        &lt;br /&gt;While in Delphi we can effectively write this on one line as...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font face="Times New Roman" color=blue size=2&gt;    if Str = 'Top' then s := 'Woohoo!' else s := 'Climb some more';&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;        &lt;br /&gt;This looks untidy. If we were using another language with immediate if, that would look like this...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font face="Times New Roman" color=blue size=2&gt;    s := iif(Str='Top', 'Woohoo!', 'Climb some more');&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;    &lt;br /&gt;Now I realise to some Delphi programmers that are not multiple programming language experienced, all that seems a little esoteric but it is standard use in even Excel. Here's how it works...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font face="Times New Roman" color=blue size=2&gt;iif(condition, TrueResult, FalseResult) : String;&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The iif() function first looks at the boolean condition. If that condition is true, then it return the TrueResult, and if it is false, then it returns the FalseResult. Here's the declaration&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font face="Times New Roman" color=blue size=2&gt;function iif(Test: boolean; TrueR, FalseR: string): string;&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The 1st parameter is the Test condition, this can be anything (e.g.: x &gt; y).&lt;br /&gt;The 2nd parameter is the string to return if the test condition is True.&lt;br /&gt;The 3rd parameter is the string to return if the test condition is False.&lt;br /&gt;&lt;br /&gt;Here's the full function...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font face="Times New Roman" color=blue size=2&gt;function iif(Test: boolean; TrueR, FalseR: string): string;&lt;br /&gt;begin&lt;br /&gt;    if Test then&lt;br /&gt;        Result := TrueR&lt;br /&gt;    else&lt;br /&gt;        Result := FalseR;&lt;br /&gt;end;&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;but in other languages, the 'type' we return can vary. For example we may want to return 99 if true or 0 of false. How do we do that in Delphi? By using the 'overload' directive.  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font face="Times New Roman" color=blue size=2&gt;function iif(Test: boolean; TrueR, FalseR: string): string; overload;&lt;br /&gt;function iif(Test: boolean; TrueR, FalseR: integer): integer; overload;&lt;br /&gt;function iif(Test: boolean; TrueR, FalseR: extended): extended; overload;&lt;br /&gt;&lt;br /&gt;Implementation&lt;br /&gt;&lt;br /&gt;function iif(Test: boolean; TrueR, FalseR: string): string;&lt;br /&gt;begin&lt;br /&gt;    if Test then&lt;br /&gt;        Result := TrueR&lt;br /&gt;    else&lt;br /&gt;        Result := FalseR;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function iif(Test: boolean; TrueR, FalseR: integer): integer; &lt;br /&gt;begin&lt;br /&gt;    if Test then&lt;br /&gt;        Result := TrueR&lt;br /&gt;    else&lt;br /&gt;        Result := FalseR;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function iif(Test: boolean; TrueR, FalseR: extended): extended; &lt;br /&gt;begin&lt;br /&gt;    if Test then&lt;br /&gt;        Result := TrueR&lt;br /&gt;    else&lt;br /&gt;        Result := FalseR;&lt;br /&gt;end;&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We can even extend these to bytes or even TObject if we want to. The only thing we can't do is have the same parameter types and return a different type, e.g...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font face="Times New Roman" color=blue size=2&gt;function iif(Test: boolean; TrueR, FalseR: string): string; overload;&lt;br /&gt;function iif(Test: boolean; TrueR, FalseR: string): integer; overload;&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is a no-no. Why? Delphi will decide which function to run based on the parameter types. If all the parameter types are the same, Delphi will not compile as it will see this as an error.&lt;br /&gt;&lt;br /&gt;As already stated, Delphi decides which function it will used based on the types used in the parameters. It will always use the least type for the job. For example, if you have iif()'s set up for both integer and byte, and then use &lt;font face="Times New Roman" color=blue&gt;iif(x=y,5,10)&lt;/font&gt;, then Delphi will use the byte function and return a byte. In most cases this will still work ok even if you are expecting an integer returned.Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-3404465122215244639?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/3404465122215244639/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=3404465122215244639' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3404465122215244639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3404465122215244639'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/have-iif-function-in-delphi.html' title='Have an iif() function in Delphi'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-8240867711700326130</id><published>2007-08-15T19:37:00.000-07:00</published><updated>2007-10-16T07:56:09.987-07:00</updated><title type='text'>Firebird Won 2 Sourceforge Community Awards</title><content type='html'>&lt;span style="font-size:100%;"&gt;From InfoWorld:&lt;br /&gt;&lt;strong&gt;SourceForge unveils the winners of the ‘open-source Oscars’&lt;/strong&gt;&lt;br /&gt;&lt;em&gt;“…The &lt;strong&gt;Firebird relational database was another double winner&lt;/strong&gt;, being voted both best project for the enterprise and the project providing the best user support.”&lt;br /&gt;&lt;/em&gt;&lt;/span&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-8240867711700326130?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/8240867711700326130/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=8240867711700326130' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8240867711700326130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8240867711700326130'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/firebird-won-2-sourceforge-community.html' title='Firebird Won 2 Sourceforge Community Awards'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7146973597869512081</id><published>2007-08-15T19:34:00.000-07:00</published><updated>2007-10-16T07:56:10.678-07:00</updated><title type='text'>Firebird 5th International Conference</title><content type='html'>This years conference will be held in the Telekom Conference Hotel in Hamburg, Germany. There are different international flights to Hamburg. We recommend to check &lt;a href="http://www.air-berlin.com/" target="_blank" onclick="javascript:urchinTracker ('/outbound/article/www.air-berlin.com');"&gt;www.air-berlin.com&lt;/a&gt; with a lot of european destinations and very cheap pricing. Hamburgs international airport code: HAM&lt;a href="http://www.ham.airport.de/index_en.phtml" target="_blank" onclick="javascript:urchinTracker ('/outbound/article/www.ham.airport.de');"&gt; http://www.ham.airport.de/index_en.phtml&lt;/a&gt; &lt;p&gt;There is a public train station nearby conference hotel. A map of the location with traveling infos will be send to all visitors&lt;/p&gt; &lt;p&gt;This year we have a special entry level track on thursday and friday. For advanced visitors you find a seperate thread. In the codecamp, you can ask on both days the experts and let them analyze your real world problem. On saturday you will find more general session topics.&lt;/p&gt; &lt;p&gt;Early bird conference fees (valid until 20th sep 2007):&lt;br /&gt;-Full Conference Package 599 Euro *&lt;br /&gt;3 days conference, 4 nights in the conference hotel&lt;br /&gt;(17.-21.) , breakfast, lunch, dinner, evening events&lt;/p&gt; &lt;p&gt;-Conference Only Package 399 Euro *&lt;br /&gt;3 days conference, lunch&lt;/p&gt; &lt;p&gt;-Main Conference Day only Package 169 Euro *&lt;br /&gt;saturday only conference, 1 night in the conference hotel (20.-21.), breakfast, lunch, dinner, saturday evening event&lt;/p&gt; &lt;p&gt;-Main Conference Day only 99 Euro *, saturday only&lt;br /&gt;conference, lunch&lt;/p&gt; &lt;p&gt;* all prices excl 19% VAT, required for all visitors 2nd visitor discount 10%, 3rd visitor discount 15% Please use the website www.firebird-conference.com or email info@h-k.de or fax +4970042397378 to send us your reservation. We hope to see you in Hamburg.&lt;/p&gt; &lt;p&gt;Naturally, we are still looking for sponsors! If you have been thinking about being a conference sponsor, NOW is the time to act. It is also possible to add special product sponsoring packages. Please contact hklemt@ibexpert.biz as soon as possible.&lt;/p&gt;&lt;p&gt;&lt;span style="font-style: italic;"&gt;Taken from Firebird News&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7146973597869512081?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7146973597869512081/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7146973597869512081' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7146973597869512081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7146973597869512081'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/firebird-5th-international-conference.html' title='Firebird 5th International Conference'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-142535338249607688</id><published>2007-08-15T19:28:00.000-07:00</published><updated>2007-10-16T07:56:12.297-07:00</updated><title type='text'>New site Firebird FAQ</title><content type='html'>Hi guys, there is a new site for Firebird, it is &lt;a href="http://www.firebirdfaq.org"&gt;Firebird FAQ&lt;/a&gt;&lt;br /&gt;This site is built by Firebird users, for Firebird users to answer the most frequently ask question (FAQ). It's also has a good index to separate question topic. So if you want to know more about this fenomenal database, check it out :)Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-142535338249607688?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/142535338249607688/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=142535338249607688' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/142535338249607688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/142535338249607688'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/new-site-firebird-faq.html' title='New site Firebird FAQ'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7694275831861113605</id><published>2007-08-15T15:33:00.000-07:00</published><updated>2007-11-12T06:42:09.022-08:00</updated><title type='text'>Practical Development Methodologies</title><content type='html'>&lt;p&gt;Over the years I have designed and installed a number of development methodologies into various organisations (I'll not list them here). What I'm interested in is a description of the development methodology that is adopted by your company, why, and how well its working.&lt;br /&gt;&lt;br /&gt;I'd also like to know &lt;b&gt;&lt;i&gt;your&lt;/i&gt;&lt;/b&gt; description of the development method, not just the company's blurb sheet. For example, I was once working for a company who was the major client of a software development company. I was asked to report on the development methodology that the software company had adopted and how well it was working in favour of the client.&lt;br /&gt;&lt;br /&gt;The company, like a great many others I know, proudly advertised their methodology as "Agile". Agile is not itself a methodology but rather a concept. There are a number of methodologies which come within the concept of "Agile". Upon investigation, the company was operating under "Iterative and Incremental Development" (IID). After getting to know both the development company, and the client, I was able to report that the IID methodology worked exceedingly well for both the development company, and their major client in this case.&lt;br /&gt;&lt;br /&gt;In most of the methodologies I have installed, I have yet to install a stock-standard, out of the book methodology. I much prefer to look at several areas within the company I am contract to, to ensure a good fit. These areas include:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;How the programming team currently works, what works well and what needs improvement.&lt;br /&gt;&lt;li&gt;The major applications that the team completes, e.g. large developments that take longer than 6 months to deliver, or daily support and enhancements to legacy applications.&lt;br /&gt;&lt;li&gt;The major clients of the team. This may be serving in-house applications (in which case the customer may be another business area) or small, large, or corporate external customers. each has its own unique needs.&lt;br /&gt;&lt;li&gt;The slant that management wants to portray to the outside world.&lt;br /&gt;&lt;li&gt;Both the history and the perceived future of the development team.&lt;br /&gt;&lt;li&gt;The history and quality of the delivered products.&lt;br /&gt;&lt;li&gt;The location and proximity of the team. For example, some companies I have worked with perform all their development in India with local staff consisting of Business Analysis and Technical Architects. Others have split their development team between two cities.&lt;br /&gt;&lt;li&gt;The makeup of the team. Some teams may have 'prima donna' programmers that simply will not conform to changes unless they are subtle or suit their own needs.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;All these will have an effect on the eventual development methodology that will be designed and installed.&lt;br /&gt;&lt;br /&gt;One example of a change to the standard methodology was where I designed and installed a standard Waterfall methodology to cope with external programmers, but changed the process to be used for Functions, instead of whole applications. This reduced the time it took for the external programmers to return their first cut that could be tested and, where necessary, returned for minor alterations. This meant that for any application there were several waterfalls operating at any one time. A sort of RAD-ified, or even XP'd Waterfall.&lt;br /&gt;&lt;br /&gt;So what's your advertised methodology? What's your actual methodology? How well does it work for the team? And how well does it work for the client/customer?&lt;br /&gt;&lt;br /&gt;You don't need to tell me the company you work for, and in most cases it may not be prudent.Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7694275831861113605?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7694275831861113605/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7694275831861113605' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7694275831861113605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7694275831861113605'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/practical-development-methodologies.html' title='Practical Development Methodologies'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7921237509266659793</id><published>2007-08-14T16:34:00.000-07:00</published><updated>2007-11-12T06:42:11.450-08:00</updated><title type='text'>The Shell Sort</title><content type='html'>Yes, I know Delphi comes with a number of sorting routines, but I thought I'd describe a shell sort as it is fascinating little sort routine that is easily understood and a very fast routine.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;[Steve: Although the "Shellsort" algorythm was first published by Donald Shell (as pointed out by Anthony Mills, thanks Anthony), this 'Shell Sort' uses a different approach that would be closer to a "Bubble Sort" with some changes. I therefore take a little 'artistic licence' in describing it in ways that people can visually understand]&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The name "Shell Sort" comes from those games that are played by the magician, conman, or simply the swift of hand when they try to get money from the average passerby. Having usually 3 shells, a small coin or marble is placed under one of the shells. The shells are then swapped around at speed and the passerby is asked to bet on which shell contains the marble.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_PDRhMtwI0ss/RsI9QC_jwBI/AAAAAAAABBA/k3CSWx3Lex8/s1600-h/Shell1.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_PDRhMtwI0ss/RsI9QC_jwBI/AAAAAAAABBA/k3CSWx3Lex8/s400/Shell1.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5098705074027479058" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The shell sort routine does that same swapping around, but only to place all the shells in order. Consider that each shell is numbered, in this case, 1 to 5, but we'll first get our 'swift of hand' guy to jumble them up a little.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_PDRhMtwI0ss/RsI9bi_jwCI/AAAAAAAABBI/vWwUrQuH0ok/s1600-h/Shell2.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_PDRhMtwI0ss/RsI9bi_jwCI/AAAAAAAABBI/vWwUrQuH0ok/s400/Shell2.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5098705271595974690" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For the purposes of this blog, I'll limit the sort to only 5 integer numbers (or shells) although these could be words or extended reals or whatever. So long as you can compare them to see which is the greatest, this routine is the same or similar.&lt;br /&gt;&lt;br /&gt;What this routine does is traverse the 5 shells many times. Each time, it will check each shell and see if it is greater than the next shell, if it is, it will swap the two shells. This will have the effect of moving the largest numbers to the right and the smaller numbers to the left - in other words, sorting them.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_PDRhMtwI0ss/RsI9oC_jwDI/AAAAAAAABBQ/odB9q_dqT5Y/s1600-h/Shell3.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_PDRhMtwI0ss/RsI9oC_jwDI/AAAAAAAABBQ/odB9q_dqT5Y/s400/Shell3.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5098705486344339506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Consider the first time through, looking at each shell in turn, and swapping them with the next if it is larger, would, by default, move the largest number to the end. &lt;br /&gt;&lt;br /&gt;Lets take a look at what will happen on the first run through.&lt;br /&gt;&lt;br /&gt;35241 &lt;i&gt;(look at 1st number, swap if 3 &gt; 5)&lt;/i&gt;&lt;br /&gt;35241 &lt;i&gt;(look at 2nd number, swap if 5 &gt; 2)&lt;/i&gt;&lt;br /&gt;32541 &lt;i&gt;(look at 3rd number, swap if 5 &gt; 4)&lt;/i&gt;&lt;br /&gt;32451 &lt;i&gt;(look at 4th number, swap if 5 &gt; 1)&lt;/i&gt;&lt;br /&gt;32415 &lt;br /&gt;&lt;br /&gt;This moved the largest number (5) to the end. This means that the next time through, we would only need to look at the first 4 numbers, and so on until there is only one number left. That will tell us that the shells are sorted. BTW: Did you notice that we only stepped throuigh the first 4 numbers? That's because the last number is, well, it's the last number and doesn't have a next number to compare to.&lt;br /&gt;&lt;br /&gt;Another way to know if they are all sorted (after all, we don't yet know if they are in order before we start) is if we traverse the shells and none needed to be swapped. If we didn't swap any then its in order and we can stop.&lt;br /&gt;&lt;br /&gt;Let's start. Create a new project in Delphi with a form. Drop a TMemo and a TButton on the form. We'll put all the code on the OnClick event of the button, so we can follow it easier. First declare the counters; the shells themselves; and a true/false variable to tell us that no swaps were made during the last traversal.&lt;br /&gt;&lt;br /&gt;&lt;font face="Times New Roman"&gt;&lt;pre&gt;&lt;br /&gt;var&lt;br /&gt;    i, LastShell: integer;&lt;br /&gt;    Shell : Array[1..5] of integer;&lt;br /&gt;    NoSwap: boolean;&lt;br /&gt;&lt;/pre&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then we'll place a procedure inside the OnClick event (something that I would not normally do, but we're keeping it all tight for you). This procedure will simply display the current state and order of the shells so we can see what's happening.&lt;br /&gt;&lt;br /&gt;&lt;font face="Times New Roman"&gt;&lt;pre&gt;&lt;br /&gt;procedure ShowShells;&lt;br /&gt;var&lt;br /&gt;    i: integer;&lt;br /&gt;    s: string;&lt;br /&gt;begin&lt;br /&gt;    &lt;i&gt;// display the shell order in the TMemo&lt;/i&gt;&lt;br /&gt;    s := '';&lt;br /&gt;    for i := 1 to 5 do&lt;br /&gt;        s := s + IntToStr(Shell[i]);&lt;br /&gt;    Memo1.lines.Add(s);&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Go on, say ShowShells shix times quickly. Then we'll add another procedure. This one will swap a shell with the next and tell us that the swap occured.&lt;br /&gt;&lt;br /&gt;&lt;font face="Times New Roman"&gt;&lt;pre&gt;&lt;br /&gt;procedure Swap(var First, Second: integer);&lt;br /&gt;var temp: integer;&lt;br /&gt;begin&lt;br /&gt;    Temp := First;&lt;br /&gt;    First := Second;&lt;br /&gt;    Second := Temp;&lt;br /&gt;    NoSwap := false;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Note that I declared variable parameters, but I also could have swapped the array directly. Either way would have been acceptable in this situation.&lt;br /&gt;&lt;br /&gt;Now we can start writing code in the OnClick event itself. First we'll fill the array with the current order of the shells.&lt;br /&gt;&lt;br /&gt;&lt;font face="Times New Roman"&gt;&lt;pre&gt;&lt;br /&gt;begin&lt;br /&gt;    Shell[1] := 3;&lt;br /&gt;    Shell[2] := 5;&lt;br /&gt;    Shell[3] := 2;&lt;br /&gt;    Shell[4] := 4;&lt;br /&gt;    Shell[5] := 1;&lt;br /&gt;    memo1.Clear;&lt;br /&gt;    ShowShells;&lt;br /&gt;&lt;/pre&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Now we can do the actual sorting, using the counters. Remember, we are going down in the number of shells we need to sort each time (the largest will move to the end each time).&lt;br /&gt;&lt;br /&gt;&lt;font face="Times New Roman"&gt;&lt;pre&gt;&lt;br /&gt;    memo1.lines.add('now sorting...');&lt;br /&gt;    for LastShell := 5 downto 1 do&lt;br /&gt;    begin&lt;br /&gt;        NoSwap := true; &lt;i&gt;// No swaps this time through yet&lt;/i&gt;&lt;br /&gt;        &lt;i&gt;// traverse the unsorted shells &lt;/i&gt;&lt;br /&gt;        for i := 1 to LastShell-1 do&lt;br /&gt;        begin&lt;br /&gt;            if Shell[i] &gt; Shell[i+1] then&lt;br /&gt;                &lt;i&gt;// its greater than next, swap them&lt;/i&gt;&lt;br /&gt;                Swap(Shell[i], Shell[i+1]);&lt;br /&gt;            ShowShells;&lt;br /&gt;        end;&lt;br /&gt;        if NoSwap then&lt;br /&gt;            &lt;i&gt;// we traversed the shells and didn't need to swap&lt;/i&gt;&lt;br /&gt;            &lt;i&gt;// any therefore its sorted and we can stop.&lt;/i&gt;&lt;br /&gt;            break;&lt;br /&gt;    end;&lt;br /&gt;    memo1.lines.add('Done');&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Note that we only traversed the shells to LastShell-1? that's because we can't look to swap the lastshell with the next one as its the last shell :-)&lt;br /&gt;&lt;br /&gt;Here's the full code...&lt;br /&gt;&lt;br /&gt;&lt;font face="Times New Roman"&gt;&lt;pre&gt;&lt;br /&gt;procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;var&lt;br /&gt;    i, LastShell: integer;&lt;br /&gt;    Shell : Array[1..5] of integer;&lt;br /&gt;    NoSwap: boolean;&lt;br /&gt;&lt;br /&gt;    procedure ShowShells;&lt;br /&gt;    var&lt;br /&gt;        i: integer;&lt;br /&gt;        s: string;&lt;br /&gt;    begin&lt;br /&gt;      s := '';&lt;br /&gt;      for i := 1 to 5 do&lt;br /&gt;          s := s + IntToStr(Shell[i]);&lt;br /&gt;      Memo1.lines.Add(s);&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;    procedure Swap(var First, Second: integer);&lt;br /&gt;    var temp: integer;&lt;br /&gt;    begin&lt;br /&gt;        Temp := First;&lt;br /&gt;        First := Second;&lt;br /&gt;        Second := Temp;&lt;br /&gt;        NoSwap := false;&lt;br /&gt;    end;&lt;br /&gt; &lt;br /&gt;begin&lt;br /&gt;    &lt;i&gt;// assign numbers to the array&lt;/i&gt;&lt;br /&gt;    Shell[1] := 3;&lt;br /&gt;    Shell[2] := 5;&lt;br /&gt;    Shell[3] := 2;&lt;br /&gt;    Shell[4] := 4;&lt;br /&gt;    Shell[5] := 1;&lt;br /&gt;    memo1.Clear;&lt;br /&gt;    ShowShells;&lt;br /&gt;    memo1.lines.add('now sorting...');&lt;br /&gt;    for LastShell := 5 downto 1 do&lt;br /&gt;    begin&lt;br /&gt;        NoSwap := true; &lt;i&gt;// No swaps this time through yet&lt;/i&gt;&lt;br /&gt;        &lt;i&gt;// traverse the unsorted shells &lt;/i&gt;&lt;br /&gt;        for i := 1 to LastShell-1 do&lt;br /&gt;        begin&lt;br /&gt;            if Shell[i] &gt; Shell[i+1] then&lt;br /&gt;                &lt;i&gt;// its greater than next, swap them&lt;/i&gt;&lt;br /&gt;                Swap(Shell[i], Shell[i+1]);&lt;br /&gt;            ShowShells;&lt;br /&gt;        end;&lt;br /&gt;        if NoSwap then&lt;br /&gt;            &lt;i&gt;// we traversed the shells and didn't need to swap&lt;/i&gt;&lt;br /&gt;            &lt;i&gt;// any therefore its sorted and we can stop.&lt;/i&gt;&lt;br /&gt;            break;&lt;br /&gt;    end;&lt;br /&gt;    memo1.lines.add('Done');&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;/font&gt;Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7921237509266659793?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7921237509266659793/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7921237509266659793' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7921237509266659793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7921237509266659793'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/shell-sort.html' title='The Shell Sort'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PDRhMtwI0ss/RsI9QC_jwBI/AAAAAAAABBA/k3CSWx3Lex8/s72-c/Shell1.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-6830286304330341677</id><published>2007-08-13T17:07:00.000-07:00</published><updated>2007-11-12T06:42:12.654-08:00</updated><title type='text'>The Delphi/Pascal Sentence</title><content type='html'>...or "When/Where to use semicolons".&lt;br /&gt;&lt;br /&gt;Apologies to all you long time Pascal gurus, but in the last few days I was pondering on the advice I gave a few students learning Pascal and felt that Today's post should be directed at those learning the language.&lt;br /&gt;&lt;br /&gt;Many new-comers find it difficult to grasp when they should be using a semicolon. The rules seem complex and inconsistant to them, when in fact they are reasonably consistant. Consider this...&lt;br /&gt;&lt;br /&gt;"Pascal is a sentence"&lt;br /&gt;&lt;br /&gt;Writing in Delphi Pascal is writing sentances, its that simple. Consider the following simple piece of code...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;if x &gt; 0 then&lt;br /&gt;  ShowMessage('x is worth something')&lt;br /&gt;else&lt;br /&gt;  ShowMessage('x is worthless');&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That equates to a sentence of "If x is greater than zero then x is worth something otherwise x is worthless.". Some people call that a Pascal statement, but I like to think of it as a sentence. Sentences are normally ended in a full stop, but in Pascal, sentances are ended in a semicolon and only the program is ended in a full stop. in the above Pascal sentence, the semicolon comes at the end as it should, and not half way through. You wouldn't say "If x is greater than zero. Then x is worth something. Otherwise. X is worthless." would you? That's 4 parts of a sentence that are seperated into 4 sentences that are meaningless.&lt;br /&gt;&lt;br /&gt;So why can't we just place a semicolon before the else? Well think of it. If someone is talking to you in fluent english and finishes the sentence, then a little later (when you are thinking of something else), states "otherwise...", you would say "Huh? what do you mean 'Otherwise'". The Delphi Pascal compiler would state the equivelent of "Huh?" at that point and totally fail to understand you.&lt;br /&gt;&lt;br /&gt;"OK-ish", I hear you saying "but what about all that begin/end stuff, nobody says that in real life", and normally you'd be right. Consider the following...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;if x &gt; 0 then&lt;br /&gt;begin&lt;br /&gt;  y := x;&lt;br /&gt;  ShowMessage('x and y are the same');&lt;br /&gt;  y := y * 10;&lt;br /&gt;  ShowMessage('and now they are not')&lt;br /&gt;end;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;How does that equate to a sentence? Well, there is an overriding sentence there that says something like "If x is greater than zero then do some things...". (There's more to that sentence that I'll add soon).&lt;br /&gt;&lt;br /&gt;You can think of begin/end as brackets if you like, that's what C and some other languages do, but Pascal is ever so slightly different. When speaking fluent Pascal (Pascal is a language after all), and you want to say some other sentences in the middle of your main sentence, you will need to let the listener know that by saying 'begin' and 'end'.&lt;br /&gt;&lt;br /&gt;Each of the lines ending in a semicolon are their own sentences: "make y equal to x"; "say 'x and y are the same'"; "make y equal to y times 10". Being sentences in their own right, they can even have their own begin/ends for their sentences if they need them.&lt;br /&gt;&lt;br /&gt;What about that last ShowMessage() statement? Well, here's where the Pascal sentence comes in. The overriding sentence actually says "If x is greater than zero then do some things and say 'and now they are not'.". More correctly, in fluent Pascal the true sentence is "If x is greater than zero then &lt;i&gt;begin&lt;/i&gt; do some things and say 'and now they are not' &lt;i&gt;end&lt;/i&gt;."&lt;br /&gt;&lt;br /&gt;When speaking Pascal you do have to say the 'begin' and 'end' words in a sentence.&lt;br /&gt;&lt;br /&gt;Now I can also hear you saying "but I have seen a semicolon before the 'end' many times". Yes, and pascal is smart enough to understand that you are saying nothing. Placing a semicolon before the 'end' is the equivilent of stating an empty sentence before finishing the outer sentence. Sweet nothings.&lt;br /&gt;&lt;br /&gt;So what about Procedures and Functions? Procedures and functions are just teaching the Pascal language new words to use. For example...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;Procedure Swap(var x, y: integer);&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;...says "I'm going to teach you the word 'Swap' and it will involve 2 whole numbers". Here's the full procedure which takes 2 numbers and swaps their values so that x equals what y did and y equals what x did (normally used in something like a simple shell sort) ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;Procedure Swap(var x, y: integer);&lt;br /&gt;var i : integer;&lt;br /&gt;begin&lt;br /&gt;  i := x;&lt;br /&gt;  x := y;&lt;br /&gt;  y := i&lt;br /&gt;end;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In this case, the sentence doesn't flow unless you expand it a little.&lt;br /&gt;&lt;br /&gt;"Here's a new Pascal Word 'Swap' that takes 'x' and 'y' as variable parameters.&lt;br /&gt;'i' is a new variable just for the word 'Swap'.&lt;br /&gt;&lt;i&gt;begin&lt;/i&gt; do some things and then make y equal i &lt;i&gt;end&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;The 'do some things' were some other sentences as you can see.&lt;br /&gt;&lt;br /&gt;Are you now more confused than ever? Don't worry, that's normal, you are becoming a programmer after all :-)Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-6830286304330341677?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/6830286304330341677/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=6830286304330341677' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6830286304330341677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6830286304330341677'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/delphipascal-sentence.html' title='The Delphi/Pascal Sentence'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-2535965529587849761</id><published>2007-08-09T20:39:00.000-07:00</published><updated>2007-11-12T06:42:13.542-08:00</updated><title type='text'>Use of Try/Except/Finally</title><content type='html'>&lt;i&gt;[Steve: I have altered the example to a more suitable one - that should teach me to quickly post then leave for the weekend without reading it].&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I have seen a number of discussions recently showing that some developers can be confused over try/except and try/finally blocks. I can give an example in the kind of work that I was doing this morning.&lt;br /&gt;&lt;br /&gt;I often read or write to an external device (let's just call it "the device" as it could be any external device). That device can sometimes send back confusing errors that I try to trap. However because those errors are confusing, I must let the user know all the various issues and ways around them.&lt;br /&gt;&lt;br /&gt;Here's a simplified version of my code (the procedures can raise their own exception with the error message returned from the device).&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;var&lt;br /&gt;    curSave         : TCursor;&lt;br /&gt;begin&lt;br /&gt;    try&lt;br /&gt;        curSave := Screen.Cursor;&lt;br /&gt;        Screen.Cursor := crHourGlass; // Show hourglass cursor&lt;br /&gt;        try&lt;br /&gt;            OpenDeviceConnection; // each will raise an exception if error&lt;br /&gt;            DoStuffWithDevice;          &lt;br /&gt;            ObtainReadings;&lt;br /&gt;            CalculateNewFigures;&lt;br /&gt;            UpdateDevice;&lt;br /&gt;            If not CloseConnection then // raise my own error&lt;br /&gt;                raise exception.create('Cant Close Connection');&lt;br /&gt;        finally&lt;br /&gt;            // return the cursor to what it was&lt;br /&gt;            Screen.Cursor := curSave; &lt;br /&gt;        end;&lt;br /&gt;    except&lt;br /&gt;        // the original exception is now being handled&lt;br /&gt;        // we can re-raise it, but in this case we'll&lt;br /&gt;        // raise a new exception with additions&lt;br /&gt;        on e:exception do &lt;br /&gt;            raise exception.create(e.message + #13+#10&lt;br /&gt;               + 'Please check that the device is switched on' +#13+#10 &lt;br /&gt;               + 'and that the cables are properly connected.'); &lt;br /&gt;    end;&lt;br /&gt;end;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Exceptions created by any of the procedure calls will now result in an error message something like the following...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PDRhMtwI0ss/Rr9ity_jwAI/AAAAAAAABA4/aKJ1cPKufL8/s1600-h/t.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_PDRhMtwI0ss/Rr9ity_jwAI/AAAAAAAABA4/aKJ1cPKufL8/s400/t.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5097901842128683010" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note that I have also placed a try/finally block inside the try/except. This is to ensure that we get the cursor back.&lt;br /&gt;&lt;br /&gt;I can raise an exception myself with "raise exception.create", the process then heads immediately to the except block, but before doing that, it must complete the finally block.&lt;br /&gt;&lt;br /&gt;The order that finally and except will be executed depends on the order that you give it. In the above sequence, finally will be completed before the except. Usually you will see them the other way around where the exception is processed before the finally block.Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-2535965529587849761?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/2535965529587849761/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=2535965529587849761' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2535965529587849761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2535965529587849761'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/use-of-tryexceptfinally.html' title='Use of Try/Except/Finally'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PDRhMtwI0ss/Rr9ity_jwAI/AAAAAAAABA4/aKJ1cPKufL8/s72-c/t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7208900369857985163</id><published>2007-08-01T16:04:00.000-07:00</published><updated>2007-11-12T06:42:14.205-08:00</updated><title type='text'>More on Delphi's early days</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_PDRhMtwI0ss/RrEYBS_jv-I/AAAAAAAABAo/i7-dwWymYTA/s1600-h/TurboToolbox.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5093879064090099682" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_PDRhMtwI0ss/RrEYBS_jv-I/AAAAAAAABAo/i7-dwWymYTA/s200/TurboToolbox.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_PDRhMtwI0ss/RrEX5S_jv9I/AAAAAAAABAg/RPb1CV6ctdo/s1600-h/Turbo_pascal_30_cover.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5093878926651146194" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_PDRhMtwI0ss/RrEX5S_jv9I/AAAAAAAABAg/RPb1CV6ctdo/s200/Turbo_pascal_30_cover.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_PDRhMtwI0ss/RrEXsS_jv7I/AAAAAAAABAQ/75xqxVujyfg/s1600-h/TurboPascal-1.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5093878703312846770" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_PDRhMtwI0ss/RrEXsS_jv7I/AAAAAAAABAQ/75xqxVujyfg/s200/TurboPascal-1.jpg" border="0" /&gt;&lt;/a&gt;My last post generated a bit of discussion, so I was trawling through the websites looking at the early Turbo Pascal information and I came across some interesting tidbits.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;As has already been pointed out by one of the readers, there was life even before turbo Pascal. The Pascal &lt;a href="http://en.wikipedia.org/wiki/Pascal_(programming_language)"&gt;Wiki&lt;/a&gt; states:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"In the 1980s Anders Hejlsberg wrote the Blue Label Pascal compiler for the Nascom-2. A reimplementation of this compiler for the IBM PC was marketed under the names Compas Pascal and PolyPascal before it was acquired by Borland ... renamed to Turbo Pascal."&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are a few pages that I found that are worthy of looking into:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://dn.codegear.com/article/20693"&gt;Antique Software: Turbo Pascal v1.0&lt;/a&gt; - you can even download the IBM-PC version&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.bbc.co.uk/dna/h2g2/A550829"&gt;Turbo Pascal&lt;/a&gt; - a short history of Turbo Pascal before it became Delphi&lt;/li&gt;&lt;li&gt;Brief &lt;a href="http://www.emsps.com/oldtools/borpasv.htm"&gt;descriptions and photos&lt;/a&gt; of Turbo Pascal versions&lt;/li&gt;&lt;li&gt;A more &lt;a href="http://delphi.about.com/cs/azindex/a/dhistory.htm"&gt;detailed history &lt;/a&gt;from About.com&lt;/li&gt;&lt;li&gt;CodeGear has a &lt;a href="http://dn.codegear.com/museum"&gt;number of historical documents&lt;/a&gt; that you can browse&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;By the later 1980's I dropped the Turbo Pascal IDE in favour of &lt;a href="http://www.multiedit.com/"&gt;MultiEdit&lt;/a&gt;. Its still around, and I still use it on occasion, but the Delphi IDE no longer needs it.&lt;/p&gt;&lt;p&gt;A reader in my last post pricked a memory or two over the character "Frank Borland". On searching, I came across this &lt;a href="http://dn.codegear.com/article/20283"&gt;CodeGear piece about Frank&lt;/a&gt;. It is definately worth a read.&lt;/p&gt;&lt;p&gt;Ok, now playtime is over and I must get back to work.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7208900369857985163?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7208900369857985163/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7208900369857985163' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7208900369857985163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7208900369857985163'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/08/more-on-delphi-early-days.html' title='More on Delphi&amp;#39;s early days'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PDRhMtwI0ss/RrEYBS_jv-I/AAAAAAAABAo/i7-dwWymYTA/s72-c/TurboToolbox.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-454355830353872647</id><published>2007-07-30T16:34:00.000-07:00</published><updated>2007-11-12T06:42:16.543-08:00</updated><title type='text'>Delphi/Pascal Through the Ages</title><content type='html'>(I apologise that this is a long post. if you are in a hurry, then please at least read the last 3 paragraphs)&lt;br /&gt;&lt;br /&gt;Delphi started out life as Turbo Pascal on CP/M. For those of you old enough to remember, CP/M was prior to MS-DOS, which in turn was prior to Windows. While getting to grips with Pascal MT+, I saw an add for a new compiler called Turbo Pascal in the very early 1980's and I bought myself a copy.&lt;br /&gt;&lt;br /&gt;From this simple, small and very fast compiler I wrote a small business accounting program that I sold on the Amstrad Computer. I used some code I found in another Borland addition called 'Database Toolbox' to add file and indexing routines.&lt;br /&gt;&lt;br /&gt;It was about mid 1980's that my accounting program The Trader Series had a serious following in New Zealand amongst Amstrad computer users and I decided to devote all my time porting it to MS-DOS, I gave up my job as Marketing Manager for Panasonic Computers in New Zealand to become a programmer. Coding in Turbo Pascal was fun. There were several enhancements since that first version 1 that I purchased, these included such powerful things as Overlays. We were restricted to 640 Kilobytes of memory so using overlays I could now write much larger programs.&lt;br /&gt;&lt;br /&gt;There were also a lot of third party programs and additions around, including a simple debugger which helped me a great deal. "The Trader Series", the accounting program I wrote, expanded to five separate modules and over half a million lines of code. Having much greater access to memory, I totally rewrote the screen handling so that all screens were built in memory and "shifted" to the screen, making it seem lightening fast for the user. I also abandoned Turbo Toolbox and rewrote the indexing system with a doubly linked, self-balancing B++ tree. These enhancements, along with using linked lists for transactions made it the fastest accounting program on the market at the time.&lt;br /&gt;&lt;br /&gt;I remember running a demo for the company I selected to distribute the program (I decided that I can't be both a programmer and salesman/marketing person). Their high end product took as much as 30 to 40 hours to run an end of month process. I had built up a database of 30,000 debtors, each with about a dozen transactions. After the demo they asked me to perform an end of month and turning to leave, asked when I would be back in to see the result. I told them it had been done. I spent all afternoon proving that it could run an end of month process in less than a minute. That program won the New Zealand Computer Software Awards in 1987 and became New Zealand's largest selling small business accounting program for the next 10 years.&lt;br /&gt;&lt;br /&gt;Turbo Pascal was a great language. Object Pascal raised its head in version 4.0 and I stayed with Turbo Pascal until I sold The Trader Series in 1990.&lt;br /&gt;&lt;br /&gt;By now Windows was getting a grip and I needed to move into this arena. Borland's Pascal for Windows just didn't do it for me. I went with a number of other languages including FoxPro, C++, Visual Basic, and I even tried a new language called Java (it'll never amount to anything but hype, or so I thought - Sigh, I have been proven wrong before).&lt;br /&gt;&lt;br /&gt;Borland then introduced Delphi and I managed to get myself a pre-release copy. Finally a great environment. Something that equaled the environment of Turbo Pascal when it was first introduced. Delphi however had a much larger price tag, but I purchased anyway and was thrilled with the power that even this first release had. Delphi was written in Object Pascal and the source code was included. You could learn lot with that source code and programmers were able to write their own components. The Component market was created with many outstanding components pretty soon there were thousands to choose from.&lt;br /&gt;&lt;br /&gt;Delphi, the new Turbo Pascal, was alive and kicking again. I was a contractor through the 1990's and contracted to many different companies and corporations and was able to persuade more than a few to look at Delphi for their future needs (where appropriate).&lt;br /&gt;&lt;br /&gt;While Delphi was indeed an excellent development environment, I was more and more disappointed in its growing price tag. By 2003, Borland had priced itself completely out of the market. The price for Delphi was now about the same price as a good second hand car in New Zealand and more than almost all other development environments.&lt;br /&gt;&lt;br /&gt;I could no longer afford my favourite development language and companies everywhere in New Zealand were coming to the same conclusion. Sadly, I was shifting to Microsoft and C#. I still had, and still use, Delphi 7, but the call to C# was strong as the companies left Borland, and as Borland lost interest in Delphi. I could not find work as a Delphi contractor any more.&lt;br /&gt;&lt;br /&gt;Earlier this year, I was invited along to the Delphi 2007 pre-release roadshow. There I learned that Borland had shifted Delphi into a separate company and concentrated on its team tools. CodeGear had been created to take over Delphi as its flagship product. Personally I thought it should have been the other way around, but that's the way it is. The price of Delphi was dropped by several thousand from what it was in 2003, and it had been given several enhancements since I last saw it in Delphi 7.&lt;br /&gt;&lt;br /&gt;I saw this as a resurrection of Delphi and a possible push to get Delphi back to its space as one of the top programming environments. They have a long way to go to get back the loyalty that they once had. Companies had dropped them and now few companies will look at Delphi again.&lt;br /&gt;However, in my intervening years with other development environments I have learned a few things: A team of 3 dedicated Delphi developers can totally outperform a team of 40 developers in Java and other Microsoft languages for a similarly large corporate application - by a factor of several months. I have also learned that, although Delphi can do .NET, Win32 can often deliver to the customer a far superior product, much more aligned with the customer's needs, in a much reduced timeframe/cost. And I learned that even a single developer armed with some excellent Delphi tools, can take on the giants.&lt;br /&gt;&lt;br /&gt;CodeGear, your work now is not with enhancing Delphi (other than in the helpscreens), its marketing that will win the lost corporates and large companies back. You won't win them all, the "We're a Microsoft Shop" syndrome is too well entrenched for that. But you can win over a lot and make your headway in the world again, and give back the power to the average programmer.&lt;br /&gt;&lt;br /&gt;I must admit, it's nice to be able to get back to programming without fighting the tool every single step of the way.Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-454355830353872647?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/454355830353872647/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=454355830353872647' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/454355830353872647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/454355830353872647'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/delphipascal-through-ages.html' title='Delphi/Pascal Through the Ages'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-4389431447873718189</id><published>2007-07-24T13:53:00.000-07:00</published><updated>2007-11-12T06:42:20.630-08:00</updated><title type='text'>Getting the Time to Program</title><content type='html'>How many others have the same problem?&lt;br /&gt;&lt;br /&gt;I have a number of ideas that I would love to program in my spare time. I have produced many retail programs previously with success so know the pitfalls. I have worked out most of the kinks in the logic of how to implement many of the features. I just need to program them.&lt;br /&gt;&lt;br /&gt;The problem is that I spend a great many hours in the day programming at work. New Zealand is known for being a wonderful place to live, but its also getting known as the hardest working. Us poor Kiwis (the kiwi is our native bird and also the name we call ourselves), have the second highest rate of average hours worked per year compared to all other OECD countries. This means that when I get home, I am in serious need of relaxation and the things I want to program get put off for another night.&lt;br /&gt;&lt;br /&gt;I have some wonderful ideas that I know will be good sellers, I just need the time to program them. Often the time I do spend on these ideas at home, ends up as code that is used in my work programs. This keeps the boss happy (I hope), but doesn't get my programs finished.&lt;br /&gt;&lt;br /&gt;Mind you, with spending every weekend with my Fiance and her daughter, and spending about an hour on the phone to her every night (we live in different towns) does not help the situation so I suppose I'm my own worst enemy.&lt;br /&gt;&lt;br /&gt;How do you make sure that you put aside the time and energy to program in the evenings?Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-4389431447873718189?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/4389431447873718189/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=4389431447873718189' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4389431447873718189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4389431447873718189'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/getting-time-to-program.html' title='Getting the Time to Program'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7912033769406393767</id><published>2007-07-18T15:46:00.000-07:00</published><updated>2007-11-12T06:42:30.411-08:00</updated><title type='text'>Different Programming Styles</title><content type='html'>I was reading &lt;a href="http://blog.dragonsoftru.com/2007/07/18/programmers-and-temperaments/"&gt;Serge’s Blog&lt;/a&gt; on Programmers and Temperaments this morning and it reminded me of a project I did for a company in Wellington once. It was a large international company (no, I'm not going to tell you which) and they had a very large project that they needed to produce. The project was technically difficult requiring a lot of thought each step of the way.&lt;br /&gt;&lt;br /&gt;After a lot of design by their chief software architect, they called for programmers. About twelve of us were hired for this one project and it was really fun to get to work with a number of others on one project like that. We were given regular daily meetings to try to bring us all up to speed on the technical requirements, and then shown to a large, open plan room with a computer on each desk to choose our own work area.&lt;br /&gt;&lt;br /&gt;What was most interesting though was a discussion that I was having with the project manager about a week later. He commented on the work styles of each of the programmers from the perspective of an observer. This wasn't a moan or gossip session, but a discussion on a real observation.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;After all the meetings and the whiteboard sessions were over, we all drifted into the desks and work practices we wanted. The project manager observed the following different styles...&lt;br /&gt;&lt;br /&gt;I found my niche in a corner desk that was on its own, then got out my pad and spent the next 2 days planning what and how I was to approach my part of the project, before I even touched the keyboard. I wanted to completely understand the requirements (which were mostly in the architect's head, given out on the whiteboard sessions). Once I understood and had a clear plan, then it was a matter of programming.&lt;br /&gt;&lt;br /&gt;Two others immediately grabbed two desks that were joined to each other so they were sitting side by side, then simply pulled one chair over to the other desk to together at the same desk, one computer between them, and designed and programmed together. They needed to talk through what they were doing and help each other plan and program. Occasionally the second programmer would move to the computer on the other desk to program a sample procedure to help explain to the other his thoughts on a subject.&lt;br /&gt;&lt;br /&gt;Another programmer sat down at the first available desk and started pounding out code. He needed to try out various prototypes and work from there, building up his code as he went.&lt;br /&gt;&lt;br /&gt;Various others worked somewhere along the spectrum of the above three different styles. Some couldn't handle it and after a few days left for greener and much easier pastures.&lt;br /&gt;&lt;br /&gt;What was interesting over the following several months was the general effectiveness of the different styles. I (admittedly somewhat surprisingly as there were some seriously experienced programmers that I enjoyed working with) ended up producing the end result much faster, followed by the pair/buddy approach. The person who immediately started coding, had to change and restart so many times that he turned out to be the least effective.&lt;br /&gt;&lt;br /&gt;I'd love to hear your comments on what you have found in your experiences.&lt;/p&gt;Fonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7912033769406393767?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7912033769406393767/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7912033769406393767' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7912033769406393767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7912033769406393767'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/different-programming-styles.html' title='Different Programming Styles'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-2108697704362661100</id><published>2007-07-09T16:43:00.000-07:00</published><updated>2007-11-12T06:42:32.230-08:00</updated><title type='text'>My Delphi 2007 program isn't debugging!</title><content type='html'>I think I've just found a little "think first" when using Delphi 2007. &lt;br /&gt;&lt;br /&gt;Trying to step through the code with the debugger to find out how and why something isn't happening as it should, I placed a break point on the first line of my FormCreate method. When I ran the application in debug mode, my breakpoint changed to a green cross and the program didn't stop.&lt;br /&gt;&lt;br /&gt;Aha! said I to myself thinking myself clever (always a mistake), It's a project option. I must have turned off the debugger. Nope - that wasn't it.&lt;br /&gt;&lt;br /&gt;Aha then! (yes, clever again) I must have changed some other compiler directive somewhere. Nope - stumped.&lt;br /&gt;&lt;br /&gt;Realisation is now dawning on me that I wasn't half as clever as I thought I was and I eventualy even reverted to the old "Microsoft's fault" fix-all - Exit Delphi and all other programs, close down and start the whole computer up again. Load up Delphi, place the breakpoint, run and ... Nope - that wasn't it either.&lt;br /&gt;&lt;br /&gt;Several minutes of frustration followed in which it would not be prudent to relate all the details (I am Christian after all).&lt;br /&gt;&lt;br /&gt;Then it dawned on me. A small 'thank-you' to Him and off I go to Project Options, Build Events. Yes, I had a Post-Build event.&lt;br /&gt;&lt;br /&gt;My normal process is to build the application, then move the application to the ..\bin directory where it needs to be in order to run correctly. Being exceptionally clever (or so I thought at the time), I placed those steps into the Post Build event. That was several weeks ago and I had forgotten.&lt;br /&gt;&lt;br /&gt;In order to correctly debug the program today, I changed the project's output Directory to the ..\bin directory where it needed to be to run.&lt;br /&gt;&lt;br /&gt;What all that meant was that when I ran build (F9), I expected the program to run to the breakpoint and then stop. However, Delphi knew that I wanted some things to happen in the Post build routine and copied over the just-built exe with an older version sitting in the ..\source directory. Now there is an exe running that does not have the breakpoint and does not relate to the code I am expecting to run.&lt;br /&gt;&lt;br /&gt;A interesting morning's lesson on trying to be too clever for my own good.&lt;br /&gt;&lt;br /&gt;Have a great day.&lt;br /&gt;&lt;br /&gt;SteveFonte: http://stevepeacocke.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-2108697704362661100?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/2108697704362661100/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=2108697704362661100' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2108697704362661100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2108697704362661100'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/my-delphi-2007-program-isn-debugging.html' title='My Delphi 2007 program isn&amp;#39;t debugging!'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-2331011145151288762</id><published>2007-07-08T20:18:00.000-07:00</published><updated>2007-10-16T07:56:13.047-07:00</updated><title type='text'>Vote for Firebird in Sourceforge Awards</title><content type='html'>&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;Firebird is a finalist in four categories of the Sourceforge&lt;br /&gt;Community Choice Awards for 2007.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;In each category the Firebird project is up against 9 other&lt;br /&gt;projects all selected for excellence from hundreds of thousands of SF&lt;br /&gt;projects. Categories are Best Tool or Utility, Best Project for the&lt;br /&gt;Enterprise, Best User Support and Best Project Overall.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;Voting is open until July 20 so take this opportunity to credit&lt;br /&gt;Firebird with your recognition. Full details and links here:&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://sourceforge.net/community/index.php/landing-pages/cca07/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;http://sourceforge.net/communit&lt;wbr&gt;y/index.php/landing-pages&lt;wbr&gt;/cca07/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-2331011145151288762?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/2331011145151288762/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=2331011145151288762' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2331011145151288762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2331011145151288762'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/vote-for-firebird-in-sourceforge-awards.html' title='Vote for Firebird in Sourceforge Awards'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-8325402303713452661</id><published>2007-07-05T22:24:00.001-07:00</published><updated>2007-10-16T07:56:21.776-07:00</updated><title type='text'>FB Date Manipulation</title><content type='html'>&lt;p&gt;Last week I have a question from Delphindo (Indonesian Delphi community) thorough YM conference. The question is how to make SQL query for Firebird to obtain the same result as we do this (to_char(sysdate, 'YYMM');) in Oracle. I must admit that Firebird doesn't have this "to_char" built in function, but we can create the same result with the trick like this:&lt;/p&gt; &lt;p&gt;select current_date,&lt;br /&gt;substring(extract(year from current_date) from 3)||&lt;br /&gt;case&lt;br /&gt;when char_length(extract(month from current_date))=1&lt;br /&gt;    then '0'||extract(month from current_date)&lt;br /&gt;else&lt;br /&gt;    extract(month from current_date)&lt;br /&gt;end as Year_Month&lt;br /&gt;from rdb$database&lt;/p&gt; &lt;p&gt;Thank's to the new feature of Firebird 2, that can make this happen without installing any UDF. I use the "char_length" and "substring" built in function that come in Firebird 2 (version 1.5xx still not support this built in function).&lt;/p&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-8325402303713452661?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/8325402303713452661/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=8325402303713452661' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8325402303713452661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8325402303713452661'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/fb-date-manipulation.html' title='FB Date Manipulation'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-8169338348318264939</id><published>2007-07-05T22:24:00.000-07:00</published><updated>2007-10-16T07:56:18.559-07:00</updated><title type='text'>Nice Function Added in Firebird 2.1 (beta)</title><content type='html'>&lt;p&gt;Here is the list of &lt;a href="http://www.firebirdsql.org/devel/doc/rlsnotes/html/rlsnotes21.html#rnfb21-appx-A"&gt;built in function&lt;/a&gt; in Firebird 2.1 (now, it's still beta). My favourite function:&lt;/p&gt; &lt;p&gt;String function: LPAD, RPAD, LEFT, RIGHT, POSITION, REPLACE, REVERSE&lt;/p&gt; &lt;p&gt;Date function: DATEDIFF, DATEADD&lt;/p&gt; &lt;p&gt;Numeric function: ROUND,  TRUNC, ABS, MIN_VALUE, MAX_VALUE, GEN_UUID, HASH&lt;/p&gt; &lt;p&gt;So with this new built in function, my previous article can be achieve with more short statement like this:&lt;/p&gt; &lt;p&gt;select current_date,&lt;br /&gt;right(extract(year from current_date), 2) ||&lt;br /&gt;right('0' || extract(month from current_date), 2) as Year_Month&lt;br /&gt;from rdb$database&lt;/p&gt; &lt;p&gt;But in my opinion it would be nice if Firebird team extend the capability of SUBSTRING function like this: the "length" value can be negative so it can achieve the same result like RIGHT function with the capability of "start position". Example:&lt;/p&gt; &lt;p&gt;Substring('Hello World' from 9 to -3) will result "Wor"&lt;/p&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-8169338348318264939?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/8169338348318264939/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=8169338348318264939' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8169338348318264939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8169338348318264939'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/nice-function-added-in-firebird-21-beta.html' title='Nice Function Added in Firebird 2.1 (beta)'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-172985909332067659</id><published>2007-07-05T22:23:00.001-07:00</published><updated>2007-10-16T07:56:23.677-07:00</updated><title type='text'>Firebird 2.1 is in Alpha state</title><content type='html'>Here is the link of release note &lt;a href="http://www.firebirdsql.org/devel/doc/rlsnotes/html/rlsnotes21.html"&gt;FB2.1Alpha&lt;/a&gt;. Wow it's time to try.&lt;br /&gt;Some cool feature:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Use of domains for Trigger/SP variable definition (SQL Server or MySQL doesn't have it (CMIIW))&lt;/li&gt;&lt;li&gt;Global temporary tables&lt;/li&gt;&lt;li&gt;Common table expressions, recursive queries&lt;/li&gt;&lt;li&gt;Database Triggers&lt;/li&gt;&lt;li&gt;Database Monitoring via SQL&lt;/li&gt;&lt;li&gt;Admin information via select&lt;/li&gt;&lt;li&gt;Get ODS Version and Dialect via SQL&lt;/li&gt;&lt;/ol&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-172985909332067659?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/172985909332067659/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=172985909332067659' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/172985909332067659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/172985909332067659'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/firebird-21-is-in-alpha-state.html' title='Firebird 2.1 is in Alpha state'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-6574779857650861764</id><published>2007-07-05T22:23:00.000-07:00</published><updated>2007-10-16T07:56:22.674-07:00</updated><title type='text'>Firebird Date Literals</title><content type='html'>Today I go to firebirdnews and found that this article is good and it may guide you to know more about FB date time. &lt;a href="http://www.firebirdsql.org/doc/contrib/FirebirdDateLiterals.html"&gt;Here is the link&lt;/a&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-6574779857650861764?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/6574779857650861764/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=6574779857650861764' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6574779857650861764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6574779857650861764'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/firebird-date-literals.html' title='Firebird Date Literals'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-4818967862287413202</id><published>2007-07-05T22:22:00.001-07:00</published><updated>2007-10-16T07:56:25.145-07:00</updated><title type='text'>Backup in Firebird</title><content type='html'>There is nice article in &lt;a href="http://www.destructor.de/firebird/gbak.htm"&gt;here&lt;/a&gt; that explain a lot of things about backup database in Firebird (including command reference). This article is lack of explanation about Firebird new incremental backup (but you can find about this incremental backup on your Firebird 2 release notes). Hope you like it.Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-4818967862287413202?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/4818967862287413202/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=4818967862287413202' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4818967862287413202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/4818967862287413202'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/backup-in-firebird.html' title='Backup in Firebird'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-6098333298168259744</id><published>2007-07-05T22:22:00.000-07:00</published><updated>2007-10-16T07:56:24.435-07:00</updated><title type='text'>Firebird 2.0.1 and ZeosDBO 6.6.1 beta</title><content type='html'>Yeah I know it's late to let you know thorough this Blog that Firebird 2.01 and ZeosDBO 6.6.1 beta is released, but if you don't know then I hope this little blog can let you know more.&lt;br /&gt;&lt;br /&gt;Firebird 2.0.1 is only bug fixed and there is nothing new feature.&lt;br /&gt;ZeosDBO 6.6.1 beta is only bug fixed and there is nothing new feature.Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-6098333298168259744?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/6098333298168259744/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=6098333298168259744' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6098333298168259744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/6098333298168259744'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/firebird-201-and-zeosdbo-661-beta.html' title='Firebird 2.0.1 and ZeosDBO 6.6.1 beta'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7821176717087161477</id><published>2007-07-05T22:21:00.000-07:00</published><updated>2007-10-16T07:56:26.046-07:00</updated><title type='text'>Recomended Page Size in Firebird</title><content type='html'>If you using Firebird database then the best setting for id set the page size to 4096 and use SQL Dialect 3Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7821176717087161477?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7821176717087161477/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7821176717087161477' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7821176717087161477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7821176717087161477'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/recomended-page-size-in-firebird.html' title='Recomended Page Size in Firebird'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-2255859511216032022</id><published>2007-07-05T22:20:00.000-07:00</published><updated>2007-10-16T07:56:26.966-07:00</updated><title type='text'>FB2.0 New Interesting Feature</title><content type='html'>&lt;div style="text-align: justify;"&gt;Today, I just know after reading my email from firebird-support that show the new feature of FB2.0 the complete article can be found &lt;a href="http://entwickler-magazin.de/zonen/magazine/psecom,id,8,online,783,p,0.html"&gt;here&lt;/a&gt; but that article is not in English :( (If someone here know what language in that site is used, please tell me because I want to translate it using Altavista Babel fish) I just read the example from that article and try it. The one that I like, is the new function on ODS 11 and it can be used like this:&lt;br /&gt;&lt;/div&gt;&lt;pre class="code"&gt;select rdb$get_context('SYSTEM', 'NETWORK_PROTOCOL') as protocol&lt;br /&gt;    , rdb$get_context('SYSTEM', 'CLIENT_ADDRESS') as client_address&lt;br /&gt;from rdb$database;&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;In ODS 11 we have the built in UDF rdb$get_context and rdb$set_context you can read more information from the doc directory that come with FB2.0 the file is:&lt;br /&gt;&lt;/div&gt;"README.context_variables2.txt"Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-2255859511216032022?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/2255859511216032022/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=2255859511216032022' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2255859511216032022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2255859511216032022'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/fb20-new-interesting-feature.html' title='FB2.0 New Interesting Feature'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7412155634941967625</id><published>2007-07-05T21:34:00.000-07:00</published><updated>2007-10-16T07:56:27.946-07:00</updated><title type='text'>Upgrading Firebird 1.5 to 2.0</title><content type='html'>Yeah, last week I try to install the new Firebird 2.0. And it's easy to migrate the old ODS 10.1 (FB 1.5) to ODS 11 (FB2.0) what you need to do is:&lt;br /&gt;&lt;br /&gt;1. Uninstall Firebird 1.5.3 (if yu wish not to use it again)&lt;br /&gt;2. Install the Firebird 2.0&lt;br /&gt;3. Backup your old database with this new gbak from FB2.0&lt;br /&gt;4. Restore them back with gbak from FB 2.0&lt;br /&gt;5. Now you have the new database with ODS 11&lt;br /&gt;&lt;br /&gt;Hope this little article can help you :)Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7412155634941967625?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7412155634941967625/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7412155634941967625' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7412155634941967625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7412155634941967625'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/upgrading-firebird-15-to-20.html' title='Upgrading Firebird 1.5 to 2.0'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-8457905683272715670</id><published>2007-07-05T21:33:00.001-07:00</published><updated>2007-10-16T07:56:29.950-07:00</updated><title type='text'>Firebird 2.0 is Out, what about me?</title><content type='html'>On 13 November 2006 Firebird 2.0 is launch on the opening of Firebird Conference. I already download it, but I'm still using version 1.5.3 for my real application and just try version 2.0 in my research computer. Why? because I still wait for the version 2.1 =) As you know usually the early version still have a bug or the feature that is not yet complete. But if you are a new Firebird user then you must download this 2.0 and evaluate it. I still wait for the roadmap of the Firebird development that usually out after the Firebird conference to see what feature that I neeed most for my current project. It's happy to see that this community so activeFonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-8457905683272715670?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/8457905683272715670/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=8457905683272715670' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8457905683272715670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/8457905683272715670'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/firebird-20-is-out-what-about-me.html' title='Firebird 2.0 is Out, what about me?'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-3346590977387707724</id><published>2007-07-05T21:33:00.000-07:00</published><updated>2007-10-16T07:56:29.033-07:00</updated><title type='text'>ReInstalling Component That Using ZeosDBO 6.6 beta</title><content type='html'>Today I try again to ReInstall my components that using ZeosDBO. I want to try this new beta version (version 6.6 beta) so I must clean up my past ZeosDBO 6.1.5. The difficulty that I found when intalling version 6.6 beta is that the seacrh directory and the output directory (from the ZeosDBO.bpg) must be set first (so It's not easy installation for Delphi user that just learn how to install Delphi components), I think they will fix this later for stable version (as they did for 6.1.5 version).&lt;br /&gt;&lt;br /&gt;The point is this new version has a simple bpl &amp; dcp created. Before version 6.6 there is many bpl &amp; dcp respectively for the "ZComponent", "ZCore", "ZPlain" and others. But in this 6.6 version the bpl &amp; dcp is only "ZComponentDesign.dcp" and "ZComponentDesign70.bpl" so I must delete the requires dcp for my components and replace with this new dcp. That's all and everythings goes well (of course after I fix the property "RequestLive" with "ReadOnly")Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-3346590977387707724?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/3346590977387707724/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=3346590977387707724' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3346590977387707724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/3346590977387707724'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/reinstalling-component-that-using.html' title='ReInstalling Component That Using ZeosDBO 6.6 beta'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-2485753003974383349</id><published>2007-07-05T21:30:00.001-07:00</published><updated>2007-10-16T07:56:32.243-07:00</updated><title type='text'>Explicit Cursor in Firebird PSQL</title><content type='html'>Explicit cursor is a new this in Firebird because it's only available in version 2. We can found this syntax in the release notes on Stored Procedure Language (PSQL) section. The example below is taken from that release notes&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;DECLARE RNAME CHAR(31);&lt;br /&gt;DECLARE C CURSOR FOR ( SELECT RDB$RELATION_NAME FROM RDB$RELATIONS );&lt;br /&gt;BEGIN&lt;br /&gt; OPEN C;&lt;br /&gt; WHILE (1 = 1) DO&lt;br /&gt; BEGIN&lt;br /&gt;   FETCH C INTO :RNAME;&lt;br /&gt;   IF (ROW_COUNT = 0) THEN&lt;br /&gt;     LEAVE;&lt;br /&gt;   SUSPEND;&lt;br /&gt; END&lt;br /&gt; CLOSE C;&lt;br /&gt;END &lt;/pre&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-2485753003974383349?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/2485753003974383349/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=2485753003974383349' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2485753003974383349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/2485753003974383349'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/explicit-cursor-in-firebird-psql.html' title='Explicit Cursor in Firebird PSQL'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-7734909728655174257</id><published>2007-07-05T21:30:00.000-07:00</published><updated>2007-10-16T07:56:31.211-07:00</updated><title type='text'>Implicit Cursor in Firebird PSQL</title><content type='html'>Firebird has an implicit cursor, we can found the example in the example database employee.fdb, and we can find in the "DEPT_BUDGET" stored procedure, lets look into the source, the implicit cursor has the syntax:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;FOR [select statement] into [local variable that hold the value from select]&lt;br /&gt;DO&lt;br /&gt;BEGIN&lt;br /&gt; [your statement]&lt;br /&gt;END&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The local variable is must defined for each of the field that selected and remember the  datatype must be the sameFonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-7734909728655174257?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/7734909728655174257/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=7734909728655174257' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7734909728655174257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/7734909728655174257'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/implicit-cursor-in-firebird-psql.html' title='Implicit Cursor in Firebird PSQL'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-5083767786130302852</id><published>2007-07-05T21:28:00.000-07:00</published><updated>2007-10-16T07:56:32.964-07:00</updated><title type='text'>Sweeping</title><content type='html'>&lt;p&gt; Sweeping is NOT just organized garbage collection. What sweeping seeks to do is to move the Oldest Interesting Transaction up, and reduce the size of transaction masks. It does so by changing rolled back transactions to committed transactions. &lt;/p&gt;&lt;p&gt; "What!!!", you say. "The woman is nuts."   &lt;/p&gt;&lt;p&gt; But that's what a sweep does. It removes all the changes made by a rolled back transaction then changes it state to committed. (Remember we agreed earlier that a read-only transaction that rolled back could be considered committed for all the harm it did. Remove the damage, and its safe to consider the transaction committed.) &lt;/p&gt;&lt;p&gt; At the same time, sweep garbage collects like any other transaction.   &lt;/p&gt;&lt;p&gt;A new thread is started and sweeps the database while everybody else goes about life as normal. Well, more or less normal, where the less is the amount of CPU and I/O bandwidth used by the sweep.&lt;/p&gt;&lt;span style="font-style: italic;"&gt;Taken from IBPhoenix&lt;/span&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-5083767786130302852?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/5083767786130302852/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=5083767786130302852' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5083767786130302852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/5083767786130302852'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/sweeping.html' title='Sweeping'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_cDJEXlmYK70/RcSTOkWtxjI/AAAAAAAAAAU/wbajaqI4_os/s320/minha+foto.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8094471332664349731.post-953110542699943499</id><published>2007-07-05T21:27:00.001-07:00</published><updated>2007-10-16T07:56:34.624-07:00</updated><title type='text'>Oldest Active Transaction</title><content type='html'>This one sounds easy - but it's not. The oldest active transaction is not the oldest transaction currently running. Nor is it the oldest transaction marked Active in the TIP. (Alas). It is the oldest transaction that was active when the oldest transaction currently active started. The bookkeeping on this is hairy and I frankly don't remember how it was done - &lt;a href="http://www.ibphoenix.com/main.nfs?a=ibphoenix&amp;page=ibp_expert4c"&gt;now I do&lt;/a&gt; -, but that's the rule, and it does work.   &lt;p&gt; Any record version behind a committed version created by a transaction older than the oldest transaction active when the oldest transaction currently active started is garbage and will never be needed ever again. &lt;/p&gt;&lt;p&gt; That's pretty dense. Lets ignore the commit/rollback question briefly.   &lt;/p&gt;&lt;p&gt; &lt;b&gt;Simple case:&lt;/b&gt; I'm transaction 20 and I'm the only transaction running. I find a record created and committed by transaction 15. I modify it and commit. You are transaction 25, and when you start, you are also the only transaction active. You read the same record, recognize that all active transactions can use the version of the record created by me, so you garbage collect the original version. In this case, your threshold for garbage collection (aka Oldest Active) is yourself. &lt;/p&gt;&lt;p&gt; &lt;b&gt;Harder case:&lt;/b&gt; You continue puttering around, modifying this and that. Another transaction, say 27 starts. You are its oldest active. It too can modify this and that, as long as it doesn't modify anything you modified. It commits. I start a transaction 30. You are also my oldest active transaction, and I can't garbage collect any record version unless the newer version is older than you. I run into a record originally created by transaction 15, modified by transaction 20, then modified again by 27. All three of those transactions are committed, but I can garbage collect only the original version, created by transaction 15. Although the version created by transaction 27 is old enough for me, it is not old enough for you, and being cooperative, I have to consider your needs too. &lt;/p&gt;&lt;p&gt; &lt;b&gt;Hardest case&lt;/b&gt;: I'm transaction 87, and when I started, all transactions before 75 had committed, and everybody from 75 on was active. Transaction 77 modifies a record, created originally by transaction 56. I continue to read the 56 version. All is well. Transaction 77 commits. You are transaction 95. When you start, I, number 87, am the oldest active. You read the record created by 56 and modified by 77. You can't garbage collect anything in that record because I can't read records created by any transaction newer than 74. &lt;/p&gt;&lt;p&gt; Maybe you know now why descriptions of the oldest active tend to be a little peculiar.&lt;/p&gt;&lt;span style="font-style: italic;"&gt;Taken from IBPhoenix&lt;/span&gt;Fonte: http://firebird-with-delphi.blogspot.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8094471332664349731-953110542699943499?l=delphidicas.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphidicas.blogspot.com/feeds/953110542699943499/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8094471332664349731&amp;postID=953110542699943499' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/953110542699943499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8094471332664349731/posts/default/953110542699943499'/><link rel='alternate' type='text/html' href='http://delphidicas.blogspot.com/2007/07/oldest-active-transaction.html' title='Oldest Active Transaction'/><author><name>Dantas</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blog
