Delphi Developer Days 2013 Course Book

Over the past month and a half, Bob Swart and I have been writing the material for Delphi Developer Days 2013 ( In all we produced seven chapters each. Bob and I each wrote two of the joint sessions, and we each wrote our own four individual sessions. We also each wrote our half of the Tips, Tricks, and Techniques session. This is why the course book has 14 chapters while Delphi Developer Days includes 13 unique sessions.

Loy Anderson, who manages Delphi Developer Days, had given us an early April deadline in order to have the course books printed in time for Chicago. It was a lot of work, but we did it, and Loy worked hard to compile our chapters into a unified book as we finished each chapter. She submitted the book for printing on April 7th, and we fully anticipated getting the books in time for our Chicago event, which begins on May 6th.

To our amazement, the books arrived this week, both those intended for Chicago as well as a European delivery of books for our Frankfurt and Amsterdam events. The book is over 400 pages in length, and we are not talking slideshows here. As you can see in the following picture, our chapters are detailed, and include screenshots and code samples.

Of course, this detail is necessary for our individual sessions. During these sessions, Bob and I break out into separate rooms to present our specific topics. If you decide to go to Bob’s presentation, you can always catch up on my presentation by reading my chapter on the topic in the book. But we feel that detailed chapters are also important for our joint sessions, giving you something to refer back to long after Delphi Developer Days is over.

I am especially pleased this year with our content. Like I have done in the past with Marco Cantù, Bob and I worked hard to create a solid selection of topics that should be of interest to almost every Delphi developer. Some of our sessions cover the absolute latest information on Delphi, including Delphi XE4, which was announced just over a week ago. These talks include iOS development, Delphi’s new NextGen compiler, and FireDAC, the new data access component framework.

There is also plenty of material to engage developers using older versions of Delphi. For example, there are talks on multithreaded development, DataSnap, debugging, browser-based clients, and Windows services. When appropriate, these talks discuss features added in recent versions of Delphi. However, the bulk of the information in these chapters applies to older versions of Delphi (some going back as far as the original Delphi).

In addition to working to find a balance of topics, Bob and I also worked to organize the talks intelligently. For example, talks on data access (including FireDAC) and multithreaded development are presented prior to those on DataSnap (which assumes knowledge about data access and multithreaded programming).

Likewise, we tried to pair our individual presentations in a meaningful way. When one of us is speaking about one of the most recent versions of Delphi, the other is presenting a topic that appeals to developers using older versions. Likewise, we tried to match an Internet-related presentation with one that applies to traditional workstation applications.

Although the book is printed (and in our hands), we all continue preparing for the actual events. Loy has a lot of organizational details to complete, including the printing of name badges and onsite signage, as well as arranging for lunches and our various guest speakers. Bob and I continue to work on our talks, creating our slideshows, and adding to, and improving, the demo projects that we’ll use.

We are really looking forward to this year’s event, and I am looking forward to this first year presenting with Bob Swart. For those of you who have already registered, we look forward to seeing your there. While Chicago has sold out, we still have space available in both Frankfurt and Amsterdam, but we expect these cities to sell out as well. Furthermore, at the time of this posting we still have a 10% discount for early registration in Europe, which ends April 30, 2013. See for details and pricing.

Delphi Developer Days is fun, and we are looking forward to it. We hope you are, too.

Read More

Read More

Initial thoughts on Delphi XE4 – iOS development

So the main thrust of my blog entries in the past few years have been about how I've wanted to make the leap from Delphi 6 to the latest version, currently Delphi XE3. As you may have read so far, we're now there and it has brought us so many benefits that I have promised I'll post about later. In the meantime, because of purchasing XE3, I've also been allowed to take part in the beta testing of
Read More

Using with POCO classes

SQLite has become one of the most pervasive embedded databases around.  It's built into Android, iOS and OSX and is a part of many applications.  It has also become the recommended client side database for WinRT applicationsThe go-to solution for using SQLite in .net is  It’s a simple ORM that comes as one (or two if you want async support) source files.  You can get the full source from github or just the main files from Nuget. lets you store nearly any object in the database without needing to descend from a specific type.  However to make it work well, you need to decorate your objects with data attributes denoting primary keys, indexes and so on.For example:       public class Valuation       {             [PrimaryKey, AutoIncrement]             public int Id { get; set; }             [Indexed]             public int StockId { get; set; }             [Indexed]              public DateTime Time { get; set; }             public decimal Price { get; set; }       }On startup, you register your class with SQLite as follows:       var myConnection = new SQLiteConnection ("Stocks.db");       myConnection.CreateTable<Valuation> ();This will check to see if the table exists in the database and create or update it if required.  You can then start using the database in your code.       var valuations = myConnection.Table<Valuation>().Where(...);However for my use case (cross platform application with data objects defined in a portable class library and used in WPF, WinRT and MVC applications), the attribute approach didn’t work.  The nice thing about open source though is that you can always change things…The latest github version of now has an optional argument for CreateTable that allows defining indexes by convention.   Acceptable values are:    [Flags]    public enum CreateFlags    {        None = 0,        ImplicitPK = 1,    // create a primary key for field called 'Id'         ImplicitIndex = 2, // create an index for fields ending in 'Id'          AllImplicit = 3,   // do both above        AutoIncPK = 4      // force PK field to be auto inc    }So to define and register a class, we can now use something like the following:    public class Valuation    {        public int Id { get; set; }        public int StockId { get; set; }        public DateTime Time { get; set; }        public decimal Price { get; set; }    }And then        myConnection.CreateTable<Valuation>(CreateFlags.AllImplicit | CreateFlags.AutoIncPK);This will create the table, make Id into an auto incrementing primary key and add an index for StockId.  To explicitly add additional indexes, use the CreateIndex methods.  E.g.        myConnection.CreateIndex<Valuation>(v => v.Time);The main advantage of this approach is that it lets you separate storage details of the object from it's definition.  This is great for cases when you don't want to, or can't, use the sqlite attributes in the main class.  The main disadvantages are that you have now separated storage from definition, and currently there is no way to set the field size.Sample applications demonstrating both approaches can be found on github.  The sqlite.dll binaries can be downloaded from here.
Read More

SOURCE – DataSnap Photo Album Server & Admin Client

Intro With my previous blog post ( I shared with you a sample application written in Delphi XE2 using DataSnap to make a client/server application for sharing albums of photos. With this post I want to show you the code and explain parts of it to you. First off, this is where you can download […] … Read More

Read More

More on FireDAC

I’ve yet to pull down and start playing with FireDAC, but it was featured in an Embarcadero event in London yesterday (Thursday). Some points with it were clarified by DavidI, which I thought were quite enlightening: As well as Embarcadero acquiring the intellectual property and all that goes with AnyDAC from DASoft, the original AnyDAC developer, Dmitriy Arefief, is now on a very long-term contract with Embarcadero to keep the development of the product moving forwards. FireDAC is intended as the replacement for dbExpress (DBX). Ultimately dbExpress will be deprecated, but doubtless will still be available for many versions to come (after all, WebSnap is still shipped in the box and hasn’t been focused on for a long time). DataSnap currently relies on dbExpress and Indy. Over time DataSnap will be worked on to make use of FireDAC instead of DBX. FireDAC was attractive to Embarcadero as it covers a much wider range of databases when compared with DBX: Oracle, DB2, SQL Server, InterBase/Firebird, PostgreSQL, MySQL, SQLite, Sybase SQL Anywhere, Advantage DB and Access, along with support for ODBC and dbExpress drivers. It also has a number of useful features, including a performance monitor (ADMonitor), a database explorer (ADExplorer) and a migration tool to convert BDE apps to use FireDAC components. Additionally, I see in the FireDAC FAQ that if you are not yet an XE3 user you can still make use of FireDAC in older IDEs by installing it with a particular command-line parameter. According to Marco Cantù the command-line for installation into XE2 is /IDE:DXE2. However I’m not sure how many versions back are supported. [ Edit: there is now a support article showing how to install into any IDE using the installer’s /showide command-line switch ] Another change with the AnyDAC –> FireDAC transition is the dropping of support for Lazarus/Free Pascal Compiler, so Linux targeting is now out of the question. If you’re a Delphi customer, this is unlikely to ruffle your feathers, but I guess Lazarus users might be more rightfully irked.
Read More

Rakefiles for Delphi

It’s not a secret that I’m a big advocate of Continuous Delivery and I’ve also found that I’ve been using a lot of Ruby and Python development workflow tooling recently because I like those languages in this setting and I find the tools to be relatively easy to use (I recently wrote about Fabric for push deployments). I wanted a build tool to run the builds of my multi-platform targeted Delphi XE2 application because it was getting tedious to publish. As with any Continuous Delivery pipeline, the first step is to map out the steps involved in getting the application to the customer. For this particular application, there were several steps: Build the application in Release configuration for each platform (Win32 and MacOS32) Compile a zip file for each platform Create a manifest XML file with the version for auto-update purposes Upload the applications binary zip files to Amazon S3 Upload the manifest to Amazon S3 Rake is a fairly mature Ruby based build tool which Martin Fowler has written about in the past. There were a couple of articles about using Rake with Delphi, one from Ed Vander Hoek and another from Shawn Oster but they were both a little out of date for my purposes. So I thought I’d cover enough Rake to get you started with a Delphi Rakefile. The msbuild driven versions of Delphi make building your Delphi project considerably simpler than trying to wrangle the appropriate dcc32 flags. If you’re already familiar with Ruby or Python then you will find building Rakefiles much easier. If you’re not familiar with ruby, I’d suggest RubyMonk. To start with, we define a function which will run msbuild after running rsvars.bat to setup the environment: def release_project(project_file, platform) buildcmd = "msbuild #{project_file} /t:Rebuild /p:Config=Release /p:Platform=#{platform}"; result = `"#{RAD_STUDIO_BIN_PATH}\rsvars.bat"&#{buildcmd_win}` if result.include? 'Build succeeded.' puts "Successfully built Windows 32 project #{project_file}" else puts result puts "Our build failed, there were build errors!" raise "Errors during Windows build" end end We can then call put this into a simple rake task to build the Win32 version like this: desc "Builds MyProject.dproj for Win32 in release configuration" task :build_release do puts 'Building Project MyProject.dproj..' release_project('MyProject.dproj', 'Win32') end We can then call this via: > rake build_release We can also list the tasks that rake has via: > rake -T rake build_release # Builds MyProject.dproj for Win32 in release configuration We can adapt this method to enable us to run any DUnit tests and code coverage tests. In order to find the version of our executable, we need to call GetFileVersionInfo on the Windows API. Luckily, there was a StackOverflow question on calling GetFileVersionInfo with Ruby. This gives us something like this: def get_version(artefact_path) require "Win32API" s=""'version.dll', 'GetFileVersionInfoSize', ['P', 'P'], 'L').call(artefact_path, s) if (vsize > 0) result = ' '*vsize'version.dll', 'GetFileVersionInfo', ['P', 'L', 'L', 'P'], 'L').call(artefact_path, 0, vsize, result) rstring = result.unpack('v*').map{|s| s.chr if s<256}*'' r = /FileVersion..(.*?)\000/.match(rstring) "#{r ? r[1] : '??' }" else raise "GetFileVersionInfoSize returned 0 for #{artefact_path}" end end We can create our zip file in two different ways, we can either use a zip gem for Ruby native creation or we can shell out to a command line version. This function uses the zip gem and takes an array of files to zip and a name for the zip file. def make_zip_distro(files_to_zip, zip_name) require 'zip/zip', Zip::ZipFile::CREATE) { |zipfile| files_to_zip.each { |file_to_zip| if File.exists?(file_to_zip) zipfile.get_output_stream(File.basename(file_to_zip)) { |f| do |in_file| while blk =**2) f << blk end end } else raise "Could not find #{file_to_zip}" end } } end For the manifest file, we can either generate it using Ruby string interpolation or a template system like erb, depending on how complex your requirements are. The final step is the upload all artefacts (the manifest, the artefacts): # You need to define AWS_ENDPOINT, AWS_BUCKET, AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID def upload_to_s3(file, s3_destination) require "aws/s3" if File.exists?(file) AWS::S3::DEFAULT_HOST.replace AWS_ENDPOINT AWS::S3::Base.establish_connection!( :access_key_id => AWS_ACCESS_KEY_ID, :secret_access_key => AWS_SECRET_ACCESS_KEY ), open(file), AWS_BUCKET, :access => :public_read) puts "Uploaded #{file} to #{s3_destination}" else puts "Could not file #{file} to upload to S3" end end You will need to define the access keys, secret keys, endpoints and bucket. The next step is to put it into composite parts and draw up a set of tasks. Rake tasks can be standalone or can have prerequisite dependencies: task :my_task => [:dependent_task_1, :dependent_task_2] do # task implementation end Rake tasks can also have parallel prerequisite dependencies like this: multitask :my_task => [:build_task1, :build_task2] do puts "Built all the things!" end Rake tasks can also have parameters, this might be useful if you wanted to pass in a version number manually at build or publish time. Back to our project pipeline from earlier, here are a selection of tasks that wrap everything together: desc "Builds the Win32 release of MyProject.dproj" task :build_win_release do puts 'Building Project MyProject.dproj for Windows' release_project('MyProject.dproj', 'Win32') end desc "Builds the Mac OS X release of MyProject.dproj" task :build_mac_release do puts 'Building Project MyProject.dproj for Mac' release_project('MyProject.dproj', 'MacOS32') end desc "Writes the manifest out to manifest.xml in the current working dir" task :write_manifest => [:build_win_release] do puts 'Writing the update manifest' v = get_version(get_executable_path(:Win32)) write_update_manifest_to(File.join(get_cwd(), 'manifest.xml'), v) end desc "Uploads the manifest to Amazon S3" task :upload_manifest => [:write_manifest] do puts 'Uploading the manifest..' upload_to_s3(File.join(get_cwd(), 'manifest.xml'), 'myproject/manifests/manifest.xml') end desc "Builds the Windows zip distributable" task :make_win_zip => [:build_win_release] do exe = get_executable_path(:Win32) v = get_version(exe) zip_name = 'MyProject-win-' + v + '.zip' make_zip_distro([exe], zip_name) puts "Create zip: " + zip_name end desc "Builds the Mac zip distributable" task :make_mac_zip => [:build_mac_release] do exe = get_executable_path(:MacOS32) # Call get_version on the Win32 executable. If the Win and Mac OS X version numbers # differ, you will need to extract the version from the generated Info.plist instead. v = get_version(get_executable_path(:Win32)) zip_name = 'MyProject-mac-' + v + '.zip' make_zip_distro([exe], zip_name) puts "Create zip: " + zip_name end desc "Uploads all of the zip files" task :upload_zips => [:make_win_zip, :make_mac_zip] do v = get_version(get_executable_path(:Win32)) win_name = 'MyProject-win-' + v + '.zip' mac_name = 'MyProject-mac-' + v + '.zip' puts 'Uploading the win zip version .. ' + v upload_to_s3(win_name, 'myproject/downloads/' + win_name) puts 'Uploading the mac zip version .. ' + v upload_to_s3(mac_name, 'myproject/downloads/' + mac_name) end desc "Builds, zips and uploads the artefacts and manifests" task :release_all => [:upload_zips, :upload_manifest] You can build your releases, create the manifest and upload all with: > rake release_all Simple, repeatable and easy to extend when you have more steps to your pipeline. Further steps for your project might be adding in your acceptance tests or automatically generating and publishing some release notes from your git logs. Other Links Using Rake – An introduction to Rake by Thoughtworker Martin Fowler. Rake RDocs – The official rake documentation. Using rake to automate tasks – A pretty comprehensive introduction to rake tasks. Building Delphi with Ruby – the EDN article from Ed Vander Hoek, including a generic framework for Delphi Rakefiles but which is limited in version support. A Simple Delphi Rakefile – A straightforward rake file for Delphi apps from Shawn Oster.
Read More

Flotsam and Jetsam #80

Despite all my slaving over a hot keyboard, bringing you a never ending supply of intellectually stimulating and hopelessly useful content, in the entire history of this website, no one has ever donated to me via PayPal.  And there is a reason for that – the stupid donate button doesn’t work.  Well, I fixed it.  Or at least I think I did.  And now, you can donate Bitcoins to me as well!  Just click on that little blue button on the right that says “Donate Bitcoins”.  Hey, hope springs eternal! I think by now pretty much everyone in the Delphi community knows that Embarcadero has acquired AnyDAC.  I’m pleased by that, and I think you should be, too.  Anyway, it looks like they are going to rename it “FireDAC”.  I like that name.  And according to that link, you’ll be able to download it for XE3.  Just another reason to upgrade to the latest version of RAD Studio XE3. (It appears that this page on the wiki has now been removed.  Hmmm…..) Tim Anderson has an interesting article about cross-platform development and the different strategies a framework can take towards producing a user interface for each platform.  I mention it because he discusses FireMonkey in it.  Jeroen pointed out this cool table that has all the Delphi compiler defines for each specific version.  Nice.
Read More

Review of the Mobile Preview Webinar

I watched the RAD Studio Mobile Preview Webinar today.  Anders O, JT Thomas, Marco, and Sarina DuPont did a very nice job presenting the product, including some pretty cool demos.  Here are my thoughts in my ever-present bullet form.  Everything here is from notes I took during the webinar. First, the webinar was today, and it hasn’t been put up on the web for general consumption yet.  They said that would happen soon.  I’ll make sure to point to it when it is up. Overall, this is very, very impressive.  I really thought it was cool.  It appears that Embarcadero has really made developing for iOS easy and very “Delphi-ish”.  I don’t own any Apple products, but I must confess that this tool might make me jump on the bandwagon (though I am most looking forward to the Android side of things – see below….) The IDE looked great.  The designer works just like the Windows designer you know and love. They showed using FireMonkey in a very nice looking designer with a cool graphic of an iPhone.  You can even choose a “palette” of iPhone 4, iPhone 5, or an iPad and the designer adjusts and looks just like the device.  You can rotate the designer to see how things will render at any orientation.  The styling and controls looked very “iPhone-ish” to me.  I’m not an expert, but it looks like they’ve gone to a large effort to make an iOS-based Fire Monkey app look perfect on an iPhone.  I couldn’t tell exactly how native controls entered into things, but they definitely mentioned that the calendar control and the list box control were native controls.   There were countless styles for the buttons, tabs, and other controls that made everything look like apps on the iPhone/iPad are supposed to look.  This question got asked about 400 times, and the team was very patient in answering it each time.  You need a Macintosh computer to develop and deploy on iOS. I repeat, you need a Mac.  There is no way around this. This isn’t a technical requirement – it’s the rules according to Apple.  They only allow deployment using a Mac and xCode, and so Embarcadero has to honor that.  Further notes in this area: This doesn’t work like Kylix did -- the RAD Studio IDE runs in Windows and Windows only.  It can run in BootCamp or Parallels on the Mac. They said that a MacMini will work fine.  I don’t know much about OS X, but they said that you’ll need at least Lion to run things. Debugging happens via a server on the mac that talks to the IDE over TCP/IP.  You debug in the IDE (on Windows) just like you normally do. Yes, you can develop in Windows on the Mac via a virtual machine, and deploy and run in the same Mac.  You can’t run the simulator on Windows as Apple doesn’t have a simulator that runs on Windows. You can’t run OSX in a virtual machine on Windows because Apple doesn’t allow that – you can only run OSX on Apple hardware. Sarina deployed both to the simulator and her actual device (though her device was emulated on the screen by an app designed to do that – she did hold it up to take a picture and you can see that in the presentation…….) Database access was interesting and appeared to be very much what we’d expect it to be. Marco demonstrated a clientdataset hooking  up to a local file.  Then he demoed the dbExpress controls talking to both SQLite and Interbase ToGo locally – that is, to the DB itself residing on the device.  Or at least that was how I understood it. Having TClientDataset on mobile devices is very cool.  I presume this means that the providers will work and allow you to talk to a DataSnap server.  That could be very powerful and cool.  I can see this being a cool thing for sharing apps between phones and the web. No mention of how AnyDAC will enter into things. A bunch of people asked about Android development, including me. JT said that it would be available later this year.  Same with C++ for both iOS and Android. He said the goal was to have the same exact FireMonkey code compile and run on iOS and Android.  That would be very, very cool.  The question that I had was about styling – but I presume there is a way to dynamically change the styling depending on the OS.  I hope so, as I don’t want an Android app looking like an iOS app, or vice-versa. There were a lot of folks asking about this – I personally am really looking forward to doing Android development with Delphi.  A lot. The compiler is Embarcadero’s – no more FreePascal involved anywhere in the tool chain. Pricing, packaging and all that kind of stuff will come later.  You can get on the beta if you are an XE3 customer.  Just another reason to buy Delphi XE3.  Did I mention that you need a Mac to develop for iOS? Further thoughts: I’m anticipating that there will be many Delphi-built apps showing up on Apple’s AppStore in the coming year, including some cool DataSnap-based apps. The mobile development space has finally come alive, and Delphi’s right there on the leading edge.  Xamarin has recently announced a cross-platform solution for Android and iOS, but they don’t provide a UI framework.  FireMonkey is right there with everything you need.  This should be a very compelling and competitive offering from Embarcadero.    And they appear to be doing this just at the right time as things really get hopping in the mobile tooling marketplace.  For once, Delphi will be doing something that Microsoft will never, ever do.  Microsoft will never provide tools for developing for iOS and Android.  Or at least I can’t conceive of them ever doing it.  So this is green fields for Delphi.  Competitors are broader and smaller – HTML5 and JavaScript (for which they have an excellent tool in HTML5 Builder) and Xamarin appear to be the main competitors at this point.  This is a nice change and a great opportunity for Embarcadero to get away from the head-to-head competition with Microsoft.  Again, I was very impressed overall.  The demos were pretty cool, FireMonkey looks really good on the iPhone, and the database access looks like it’s exactly what we Delphi developers would expect.  This is a cool opportunity for Delphi developers.
Read More

Flotsam and Jetsam #79

Today is Delphi’s 18th Birthday.  I'll always wear it as a badge of honor that I was there at the launch at SD ‘95 in the Moscone Center.  Quite a privilege.  Thanks to everyone who has made Delphi such a great tool to use. I am signed up for the RAD Studio Mobile Preview Webinar.  Are you going to attend? Colin Johnsun reports that the JVCL has migrated over to use GitHub.  I consider this good news.  While I prefer Mercurial, Git is a Distributed Version Control System, and DVCS’s are vastly superior to server based systems like SVN.  First off, they are designed to branch and merge with ease, meaning that coordinating development and contributing changes is way, way easier (the process of “pull requests” that Colin talks about).  If you aren’t using a DVCS, you don’t know what you are missing. In case anyone cares, my entire tweet archive is now online here on my site.  Here’s the tweet that started it all.
Read More

Delphi comes of age

18 years ago today Delphi 1 was launched as a revolutionary way of building native compiled, unmanaged, non-interpreted 16-bit Windows 3 applications using UI-driven RAD principles. Today Delphi targets Win32, Win64, OS X and at some point soon will also target iOS and Android. Happy birthday Delphi! Delphi has come a long way in 18 years, but the basic principles of building Windows applications are just the same today as they were then. The VCL library has expanded and grown considerably, and the IDE has had countless useful features and options added to it over the years. It’s easy to miss some of the IDE features or forget a useful keystroke. To help you remember some of the more useful ones, please refer to any of these resources: My blog post Delphi IDE productivity keystrokes from July 2012 where I run through some of my favourite IDE keystrokes, mainly in the code editor. My CodeRage 7 session IDE Productivity Tips & Techniques from November 2012 where I demonstrate some of my favourite IDE keystrokes, mainly in the code editor. Cary Jensen’s Delphi Editor (Updated) Key Combination Table. I spent quite some time working with Cary on this (hopefully) comprehensive “cheat sheet” of keystrokes available from the Delphi editor’s default keymapping. It’s a big list and many of the supported functions are accessible through more than one keystroke combination, which makes the list even longer. If you want to find how to do something in the editor with a keystroke shortcut, this is the resource to refer to.Note that the online Delphi keystroke documentation is unfortunately deficient and errant in various regards. I made a concerted effort to correct those oversights in this updated shortcut collection. Keep using Delphi for your native Windows applications and we’ll still be celebrating Delphi’s birthday for many years to come!
Read More

Happy Birthday Delphi – 18 years and looking great!


On February 14th Delphi will be 18. Looking back it sure came a long way from version 1. I remember when I first walked into a Compusa store and bought my first copy of Delphi. I was beside myself with excitement. Moving from Turbo Pascal to Delphi, moving from DOS to Windows development. That was a very challenging and interesting time indeed.
I am proud of have been a part (as a developer) of that journey. Being a Delphi developer wasn’t always easy. But I am very happy I stuck to my conviction that this is the best tool to develop in and didn’t stray away from it.
Exciting times are ahead, as exciting as picking up my very own copy of Delphi 1. I say that because the future looks very promising and exciting. Cross-platform is here and mobile development are just around the corner.
What better time to be  a Delphi developer? I can proudly answer, now!
So raise your glasses and salute our dev tool! Happy Birthday and many more returns!
And thank you to all the people that made a positive difference in making Delphi what it is today!

Read More

FireMonkey: Extending TFloatAnimation to support maximum loops

Background In response to a QC report I wrote early last year I decided to implement a LoopCount property on the TFloatAnimation component. Report No: 105140 Status: Open Add a LoopCount property to the TAnimation class Class Definition TJSCustomLoopCountFloatAnimation = class(TFloatAnimation) public type TAnimationLoopEvent = reference to procedure (Sender: TObject; const LoopNumber: Integer; var Cancel: Boolean); private FLoopCount: Integer; FCheckingLooping: Boolean; FOnLoop: TAnimationLoopEvent; protected FLoopsComplete: Integer; procedure FirstFrame; override; procedure DoLoop(var ACancel: Boolean); virtual; procedure ProcessAnimation; override; public constructor Create(AOwner: TComponent); override; property LoopCount: Integer read FLoopCount write FLoopCount default 3; property OnLoop: TAnimationLoopEvent read FOnLoop write FOnLoop; end; Nothing that interesting in the new descendant. New property called LoopCount to control the number of loops and a new event that gets triggered each time a loop completes. The published component publishes the new property and event but also changes the default values for two existing properties. It makes sense to set Loop to true when the new class is for enhancing the looping ability and if you’re looping, generally AutoReverse will be set to true. TJSLoopCountFloatAnimation = class(TJSCustomLoopCountFloatAnimation) published property AutoReverse default True; property Loop default True; property LoopCount; property OnLoop; end; Implementation I won’t post all of the code here because you can download from the link provided below, just a couple of snippets. We need to override the FirstFrame method to initialise a couple of variables we use. Checking to see if the LoopCount property is valid (raise an exception if it isn’t) Initialise the variable to zero that counts the interactions Make sure we are going to be checking the animation process for loops Most of the work occurs in the overridden ProcessAnimation method. procedure TJSCustomLoopCountFloatAnimation.ProcessAnimation; var LCtx: TRttiContext; LType: TRttiType; LField: TRttiField; LCancel: Boolean; begin inherited; if FCheckingLooping then begin LType := LCtx.GetType(Self.ClassInfo); if Assigned(LType) then begin LField := LType.GetField('FTime'); if LField <> nil then begin if LField.GetValue(Self).AsExtended = 0 then begin Inc(FLoopsComplete); LCancel := False; if FLoopsComplete > 1 then DoLoop(LCancel); // The first time through, FTime is 0 so we need to offset this by // adding 1 when checking for completion if LCancel or (FLoopsComplete = LoopCount + 1) then begin LField := LType.GetField('FRunning'); if LField <> nil then LField.SetValue(Self, False); end; end; end; end; end; end; Thanks to extended RTTI we can access a couple of private fields that we need to determine if a loop has been completed. This occurs when the FTime variable is zero. There is one issue with using this value and that is that the first “Loop” should be ignored since the first time ProcessAnimation is called FTime is zero so by the logic used, a loop has completed. This is why the DoLoop method is only called if the FLoopsComplete variable is greater than one. Naturally it is possible to handle this one-off situation differently using a “First Time Through” variable but under the circumstances, I decided to go with the solution in place. Once the LoopsComplete value is one greater than the LoopCount (refer to the above two paragraphs if you’ve already forgotten about why) the private field FRunning is set to False. Setting FRunning to false, stops the animation immediately. Why not just call the public Stop method instead of going to the trouble of setting a private field? The answer to that is found in the ProcessTick method of the animation control (incidently, why isn’t this method virtual?). ... ProcessAnimation; // <==== We set FRunning to false here DoProcess; if not FRunning then begin if Assigned(AniThread) then TAniThread(AniThread).FAniList.Remove(Self); DoFinish; end; ... By setting FRunning to false within our ProcessAnimation override, we are avoiding another frame being processed before the animation is stopped. This is because the Stop method calls ProcessAnimation and DoProcess as well. Download You can download the component and a cheesy demo application from the link provided. There is no package for the component to install it into your IDE, this is left as an exercise for the reader :-). Loop Animation Demo (short video – 39KB) Download LoopCount Component and Demo NOTE: Before downloading the source code you must agree to the license displayed below. License Start This space intentionally left blank… License End
Read More