The first application I'll create will be similar to sample ones I had tried in RadPHP. They were simple PHP tutorials and they worked--somewhat. I had some issues, but don't remember whether it was getting all the right libraries in the right place or whether it worked from some locations or browsers or what. In any case, I'm hoping HTML5 Builder will make the process a little smoother.
It's been a year since my last blog entry and while I've been busy writing Windows applications with Delphi, I've kept an eye on web technologies. I've done some PHP in the past and had purchased RadPHP XE but didn't upgrade to the XE2 version because there were practically no new features and the documentation, which was pitiful, was not improved one bit--in fact it was still labeled XE!
While working on a project accessing a slow web service, I found myself needing to extend the timeout of the HTTPRIO component. The web service, when executed straight from a browser, would happily take as long as it needed to before successfully completing. But my Delphi application was timing out.
In the last entry, I gave an overview of the large software update I delivered to a client, an update that should've been done incrementally over a period of several months. From database schema changes, to swapping out a reporting engine, to switching from ANSI to Unicode, I really bit off more than I could chew at once. But it's now working well and I'm once again sleeping at night!
This portion of the story deals with the database changes that were made, both the structure and the character set.
I recently gave a client a major update to their custom application. Actually, "major" doesn't even do it justice. It was more like "mega major" and I don't think I'll take the approach I did ever again. But I wanted to move their code to the latest compilers and to support the latest operating systems. I also needed to change some low-level database constructs. Why all this? Because I'm a best-practices sort of guy.
In the old DOS days, things were simple. You had 25 rows and 80 columns of text. Period. Well, if you knew the right tricks, you could double the rows or columns, but still it was pretty limited. This made programming fairly easy--you knew how much space you had to deal with. With a GUI, or Graphical User Interface, things can get stretched out, you can have larger fonts, and you can have themes on or off. So knowing how much space you have to display stuff isn't quite as cut and dried. But I'm going to look at just one aspect that can be surprising: themes.
Adding theme support to your application can give your program a whole new look (if you use standard Windows controls) without changing anything else. This works because the controls will actually use a different set of DLLs behind the scene. In Delphi 2007, this is accomplished with a simple checkbox in the project options. (Visit the Delphi Wikia page and search for "Adding Theme Support" for more information.) The DateTimePicker is one of these and I just discovered its new capabilities when themed on Vista or Windows 7.
Consider the following psuedocode fragment:
for each FieldValue in RecordList do begin
if ValidSearchValue(FieldValue) then
found := Search(FieldValue)
ShowMessage('Invalid search criteria: ' + FieldValue);
if found then
In Delphi, a warning will be generated near the bottom of this code where it says "if found ..." saying:
Variable 'found' might not have been initialized
To prevent that warning, you would initialize "found" just inside the "for each" loop with something like
found := False;
But then, Delphi emits the following hint:
Value assigned to 'found' never used
It seems that Delphi's Hints are smarter than its Warnings. It knows that with the "Continue" statement, the "found" value will either be overwritten or simply not used at all because the Continue statement takes control to the top of the next iteration.
Unfortuneately, the Warning is generated even though the "if found" section will never be encountered unless the found variable was already initialized.
The work around? Well, you could turn off hints, but I wouldn't advise it. I keep all hints on and strive to eliminate every one of them. It makes my code much cleaner and prevents headaches down the road.
Instead, simply moving the "found" initialization outside the "for" loop gets rid of the hint and suppresses the warning.
Delphi is one of the greatest development environments every produced for Windows. It has an easy to learn, yet strict language that leads to less confusion than C++ and better coding practices than Visual BASIC. Unfortuneately, it has been marketed by a company that has made so many changes in direction and name that people have laughed it off. One more change has happened recently, here is the story, which actually starts over 25 years ago, before Windows.
In November, 1983, Borland released Turbo Pascal 1. It was an inexepensive DOS-based Pascal compiler written by Anders Hejlsberg in Denmark and only produced .COM files. But it did them well and did them fast. Hobbiests and students snapped up copies, and the phenomenon was born.
I started using Turbo Pascal 4 professionally in 1988 and in a few years, Borland renamed it to Borland Pascal, upped the price, and entered the professional developer market, competing directly with Microsoft. With Borland Pascal 8, you could use OWL (Object Windows Library) to create 16-bit Windows applications. But it was a huge library and not many were brave enough to tackle it.
Fortuneately, there was a new and much better solution coming. In 1995, Borland released Delphi 1, the first development tool to use the concept of visual components placed on a form to encapsulate library code--which is now prevelent in nearly all IDEs. The next year, they released Delphi 2 to address the 32-bit capability of Windows 95; this version also added visual form inheritance.
Delphi 3 was a solid product and added some nice IDE enhancements, but more importantly added support for ActiveX and introduced WebBroker.
Delphi 4 came during a time when Borland was entering some troubling years. The company was renamed to Inprise Corporation, supposedly to align it with more enterprise-level customers and break into more application-life cycle products. The developer community was not happy--especially since Delphi 4 was so buggy. However, the IDE continued to break new ground and add new features that have been adopted by other companies.
In 1999, Delphi 5 was released and was a very strong product (still in use today by some hold-outs). Again more features and IDE enahancements were made, including support for ADO. By this time, everyone realized that renaming the company was a mistake, so the product was branded as "Borland Delphi 5--by Inprise Corporation."
With the new millenium, came another version, Delphi 6. Many changes to the compiler broke backwards compatibility, but allowed for cross-platform development with Kylix, the company's Linux experiment that died after only 3 versions. But more significantly, support for web services was added and many other internet, COM, ADO, database, and IDE features and enhancements made into the product.
Many say that Delphi 7 was the last great Delphi. It used the same familiar IDE that existed in Delphi 1, used the fast WinHelp online help system, and was faster and more solid than Delphi 6. The company had changed its name back to Borland by now and developers were very happy (and productive) with Delphi.
But Microsoft .NET (architected largely by Anders Hejlsberg who left Borland in 1996) was here and Borland had to address the new technology. So they added a .NET preview compiler as part of the "studio" package for Delphi 7 on the 8th anniversary of Delphi.
Delphi 8 was the "real" version of the .NET compiler for Delphi. In fact, if you bought the "studio" package, the Win32 compiler part of the deal was actually Delphi 7. However, Delphi 8 had so many problems as to be practically unusable.
Delphi 2005 finally married both Win32 and .NET development in a single IDE, and even though it was still terribly buggy, at least it worked. Borland made huge efforts to keep backwards compatibility to help bring Win32 devlopers over to .NET by providing VCL for .NET. This actually worked amazingly well--for the most part.
One of the biggest complaints of Delphi 2005 was the radical departure from the fast and familiar WinHelp to the new Microsft Compiled HTML Help format. Even though this new format was more flexible, it loaded far slower. Worse yet, very little of the old help text had been ported over to the new format and resources at Borland were stretched to the max for supporting several different products, technologies, and newly acquired companies.
With a buggy compiler, a slow and inadequate help system, and Borland's increasing interest in ALM and decreasing interest in developer tools, many customers around the world began looking at other solutions, or simply did not upgrade from Delphi 7. Confidence in the company was shaken and many questions were raised about the future of Delphi.
Borland continued to promise support of Delphi and delivered that to some extent the next year with a much improved Delphi 2006. The enterprise versions of the "studio" package included requirements, modeling, version control, testing frameworks for both Win32 and .NET, multiple database support, installation, and of course all the languages: Delphi Win32, Delphi for .NET, C++Builder, and C#Builder! It was quite an impressive package, but still developers were uneasy and asking hard questions.
The grumbling about the departure from Delphi 7's efficent editing never seemed to stop. But other concerns were escalating. With Borland acquiring more ALM companies and putting out buggy products with incomplete documentation, developers couldn't help but wonder if the speculation over the years about Borland's eventual demise would finally come true. Or if it stayed afloat, would there be enough support for them? Many jumped ship, but others stayed on to see what would happen.
What did happen was quite surprising to many. In February, 2006, Borland announced that it was going to sell off the Developer Tools Group, the team that worked on all the development and database tools. Lots of speculation ensued--and the future was still uncertain. (The original announcement has been taken down, but an InfoWorld article still exists that talks about it.)
The DTG started "evangelizing" Delphi by offering tutorials, soliciting customer feedback, and even reviving the old DOS-day "Turbo" name by offering Turbo Delphi, Turbo C++ and other "Turbo" products for free. The products offered had some limitations of course, and were basically the single-product versions of Borland Developer Studio 2006, but probably did some good in bringing back fond memories, or at least reminding people that Delphi had some serious history. (I'm not sure if the key reason for the Turbo products--to raise awareness for Delphi and bring in new customers--was terribly successful.)
A new level of excitement arose (albeit mixed with trepidation) and in November, 2006, Borland officially formed CodeGear as a wholly owned subsidiary from the Developer Tools Group.
Many saw this as a very positive sign that not only was the group of people working on the products going to stay, but they would manage their own company and focus solely on developer tools. To answer this, CodeGear released Delphi 2007 only four months later. While mostly a bug fix for Delphi 2006, it introduced a few nice IDE features and Blackfish SQL (a revamped JDataStore). But more importantly, it was a sign that the new company was active and committed to producing a quality product which addressed the customers' concerns.
A little over a year later, Embarcedero purchased the CodeGear division from Borland. Delphi had finally left the company that took it from learning tool, to serious programming language, to enterprise-wide development platform. But even with a full suite of languages and platform support and now with the backing of a company who really wanted the products, the story had another twist coming.
In 2008, Delphi 2009 for Win32 was released with unicode support--the most significant upgrade ever for the Delphi line. Strangely missing was the .NET component.
Meanwhile, another company, RemObjects (which had produced several Delphi libraries) had written the only other Pascal compiler on the planet (well, since Microsoft Pascal for DOS in the early 1990s), but instead of providing a rich development environment like Delphi, built it as a plug-in to Microsoft's Visual Studio IDE. This product was named Chrome. There was no upgrade path from Delphi Win32 or Delphi for .NET, but that was by design--they didn't want to bring along lots of historical baggage. Their release for Visual Studio 2005 had been slowly gaining ground.
Then in October, 2008, RemObjects and CodeGear jointly announced Delphi Prisim which was the Delphi IDE coupled with RemObjects Pascal compiler for .NET, or version 3 of Chrome that works either in Delphi or as a plug-in to Visual Studio 2008.
The story will continue, no doubt, for several more years. I am still developing most everything in Win32 Delphi--as a vast number of Delphi developers are. I suppose someday, Microsoft will force the issue and stop supporting the platform, but when I look at the applications stil coming from them, I'm not worried that it will be any time soon.
The .NET platform is well-engineered and has lots of features built-in that currently require 3rd-party libraries or lots of programming for equivalent functionality in Win32. I am excited about learning the new technology, but there is always a learning curve and there must be a good reason to move.
For now, I will continue to support and trust the Delphi product line. I still believe it is a very solid product and I also believe there will be a company behind it for quite some time.
For a long time, I've enjoyed a handy method in Delphi's TStringList class to read in and write out a CSV-formatted line of text. For example,
is a typical CSV string with each field delimited by commas and each string delineated by double quotes. The CommaText function turns that string into a list of 4 strings:
- Fred A.
- Lake Oswego
Notice that both the field delimiting commas and the string quotes are removed from the parsed fields.
Now what happens if a string has an embedded quote?
TStringList.CommaText falls apart. And well it should because the double-quotes are being used for two purposes: both as a field delimiters and as string quotes. Unfortunately, CommaText doesn't have any way to handle this.
There's another drawback to using CommaText, but it is a minor one. When exporting text, it only adds the string quotes if it really needs to. For example if I have the following fields in a TStringList:
- Fred A.
- Lake Oswego
and use it to export a CSV line, only the first and third would actually contain the string quote marks:
This probably won't be a problem in most cases, but is inconsistent and if the application that needs to import this text expects string quotes, it will have problems on the fields without. Worse, if importing or viewing with a spreadsheet, unquoted numbers may be formatted or even interpreted incorrectly.
If you're still using Delphi 5, you're stuck with CommaText, using a third-party string library, or writing your own routines to handle these deficiencies.
However in Delphi 6, a new method appeared in the TStringList class: DelimitedText. This now allows the programmer to set the QuoteChar, a quote character that encompasses a string, and the Delimiter, a character to separate the fields. The default QuoteChar is a double-quote (") and the default Delimiter is a comma (,). Thus, by simply replacing all instances of CommaText with DelimitedText and doing nothing else, you'll have the same functionality as before (easy migration).
But with DelimitedText, you now have the capability to handle embedded quotes by using a different string QuoteChar. For example, with the pipe character (|) as QuoteChar, the following text will now be read in and parsed correctly:
And if you need to, you can even replace the field Delimiter with something else:
So why am I mentioning this now, when Delphi 6 came out 8 years ago in 2000? Because having used Delphi since Delphi 1 and Turbo Pascal before that, I've developed a set of routines for doing a lot of different things over the years and don't always read all of the What's New list in each version--especially since I don't always purchase each version. DelimitedText is actually a new find for me and just in case someone else finds themselves in the same position, I thought I'd share my late discovery.