Category: Firemonkey

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

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

What does AnyDAC acquisition by Embarcadero mean for Delphi and C++Builder Developers?

Finally the day has come, Embarcadero acquired AnyDAC and there is a lot to talk about, early last year I invested a lot of time evaluating AnyDAC and know you know why – I was very impressive with the amount of features,  AnyDAC is everything dbExpress tried to be and never reached. The reason I […]

Andreano Lanusse | Technology and Software Development
Follow me on Twitter: @andreanolanusse

Read More

Read More

AnyDAC – worries with some real excitement.

When I read Marco Cantu's Post titled "Embarcadero Buys AnyDAC"  I began to worry.Where I work we spent a great deal of time converting from the BDE to dbExpress.    Granted we did it faster than we thought it would take, it's not something I am ready to do again.    Having to switch from dbExpress to another Database Layer was really not going to be an option for us.    So I spent some time really reading the documentation on AnyDAC.From what I have read this has turned from worry to exciting news, with a one thing that may need to be done.First off let me address my worry about dbExpress. AnyDAC is a library that can sit on top of dbExpress, ODBC or it's own drivers. AnyDAC can connect to dbExpress driver through a TADPhysTDBXDriverLink component.What is lacking that would need to developed.  (Maybe already done since I have no code to look at yet, and I am just reading docs)Ability to have a TSQLConnection use an existing TADConnection class or vice versa.I basically think it would be great if AnyDAC existing connection could become an dbExpress Driver.I know enough about the dbExpress framework to know this is something that would be very possible to do.   In the long run this would also allow Embarcadero to only have to support one set of drivers and not one for dbExpress and one for AnyDAC.       If Embarcadero does something stupid and don't do this and just stop maintaining dbExpress Drivers without providing a bridge then I would have to stop upgrading Delphi versions, but I really don't see that happening.    This would allow existing dbExpress applications to start using AnyDAC without having to have two connections to the database.   Then I started looking at the features of AnyDAC and found several that are really appealing.  Although I don't have a BDE application, I know several still doExisting BDE Applications have a Detailed Guide on conversion to AnyDac.  With a step by step coverage on converting BDE Applications.BDE needs to go away, this really looks like a really good option for those applications.I primarily use Oracle but we also use Sybase, SQL Server, My SQL, SQLite and DB2.    All have good support with AnyDAC with many other Databases supported.Sometimes I have to basically join results from two different databases.   It usually results in some pretty ugly code.   AnyDAC helps solve this problem by supporting Local SQL which allows you to execute SQL queries against any TDataSet descendants as  the data source.  Oracle Support includes support for more data types than the existing dbExpress Driver.  TADMemTable is faster than TClientDataSet there was old blog entry on the comparison of speed between memory based datasets and show the difference for the various operations.   Good support for low level trace/logging of what is going on at the API level.Currently has 100% of the source available I am hoping Embarcadero keeps that up.  It's a big complaint of mine when it comes to dbExpress.Live Data Window Mode, appears to be something that could really help us with some performance on some of our search screens.Array DML, appears it may help us speed up some of our batch operations such as file importing.In addition I noticed that AnyDAC really has a good cross platform story.   Which might be a huge thing for the Mobile editions of Delphi.   Granted I think that connecting directly to a remote database via a mobile application is a security risk.Overall I think this will be a good thing, depending on the decisions made by Embarcadero that have yet to be made.   
Read More

is Delphi the problem?

This post was inspired by comments I received in my last article about DataSnap. DHR has made some interesting questions and I’ll try to answer them. What framework did you eventually choose and why did you choose it? My choice is the mORMot framework, for several reasons. First of all, I do not have the […] … Read More

Read More