Category Archives: Embarcadero Delphi

Delphi Shelf Life Reaches a New Low

I am going to try to keep this post short and to the point. I don’t want to rant (too much) or say anything I regret (too much), but something has to be said.

When it comes to iOS development, Delphi XE4, a major product released by Embarcadero five months ago, is now obsolete. If you want support for iOS 7 you must buy their new product, Delphi XE5.

Let’s take a step back and look at the facts when it comes to Delphi and Embarcadero chasing the mobile landscape:

  • Delphi XE2 – released September 2011. Claims support for iOS development but, by all reports, fails to deliver. iOS development makes use of the FreePascal compiler and cannot use traditional Delphi code.
  • Delphi XE3 – released September 2012. Support for iOS development completely removed. Anyone who built their iOS app on the foundation of XE2 was left out in the cold.
  • Delphi XE4 – released April 2013. Claims support for iOS development (again). Anyone who wants the iOS development support promised in XE2 must now buy XE4, released as a new product only seven months after XE3.

And now Delphi XE5 has been released only five months after Delphi XE4. It’s another new version and another paid upgrade.

Here’s the real rub though. iOS 7 was just released by Apple. It features a new UI and new navigation elements for apps. Anyone using Xcode (the traditional tool for iOS development which is free) could simply recompile their apps and resubmit them to support iOS 7.

What about Delphi XE4 customers? The ones who just put down their hard earned money for iOS support, again, five months ago? They are left out in the cold. Again. If a Delphi XE4 customer wants to support iOS 7 they must now purchase Delphi XE5. I confirmed this myself with a back-and-forth on Twitter with Jim McKeeth from Embarcadero:

Jim goes on to point out that, if you forgo using the bundled UI kit in your iOS app, you can still leverage the new iOS 7 elements using Delphi XE4:

However, this is basically suggesting the customer not use the same UI technology that is the very heart of Embarcadero’s marketing strategy for several releases now: FireMonkey.

To be clear, I am not upset by a six month release cycle. A lot of companies do that and it’s a smart move for some of them. However, Embarcadero is releasing Delphi like a subscription while selling it like a packaged product. While they offer “Software Assurance” this is a far cry from a subscription. This is an added fee on top of your purchase that allows you to get major upgrades that happen to be released within a year. It’s insurance. It’s the type of thing most of us pass up when checking out at Best Buy.

All-in-all this has just left a horrible taste in my mouth and the mouths of many other developers. My advice? If Delphi has turned into a subscription then charge a subscription. Stop packaging it as something that will be obsolete in 5 months without another purchase.

Improvements to Server Mode Grid in DevExpress VCL 12.2

Version 12.2 of the DevExpress VCL controls brings several improvements to the Server Mode feature of the ExpressQuantumGrid control. Both Advantage Database and PostgreSQL are now supported. There is also now support for in-place editing and banded table views when using Server Mode.

But one of the most welcome improvements, I think, is the new capability to specify custom SQL for the SELECT statement that the Server Mode data source components will use. When I last blogged about ExpressQuantumGrid Server Mode, the most vocal feedback was the need to specify custom SELECT statements. Until now this was only possible using Views within the underlying database. But starting with 12.2, DevExpress has introduced two new entries to the collection of Server Mode components to support using custom queries: TdxServerModeADOQueryDataSource and TdxServerModeDBXQueryDataSource. These are counterparts to the existing data source components that feature a SQL property for specifying the SELECT statement.

To see how easy this is to put into practice, download an open my sample from this blog post. Make sure you’ve also created a database and used the contained SQL scripts to create and populate the LotsaRows table.

Open Unit1 and select the Design tab. Delete the existing TdxServerModeADODataSource and replace it with a TdxServerModeADOQueryDataSource.

Setting up the TdxServerModeADOQueryDataSource component is very similar to setting up its non-query counterpart. For the Connection property select the existing ADOConnection1 component and for the SQLAdapter property, specify MSSQL Adapter. For the new SQL property, click the ellipsis button and enter the following SQL statement:

With the SQL statement specified, click the drop down arrow next to KeyFieldNames and select the ID column. Finally, set Active to True.

That’s it for setting up the TdxServerModeADOQueryDataSource. Now, select the Server Mode table view on the form and bind it to the TdxServerModeADOQueryDataSource using the DataController.DataSource property.

At this point you should see that the project is working again more or less as it did in my previous blog post. A million rows of data show, quickly, within the TcxGrid control, featuring fast grouping and sorting.

To actually see the new feature in practice, add a new TcxCheckBox to the main form, adjusting the grid control and giving it a proper caption.

And handle the Click event of the TcxCheckBox with the following code:

procedure TForm1.Column3CheckBoxClick(Sender: TObject);
var
  SQL: string;
begin
  //improve performance by disabling gridview updates during data operations
  cxGrid1DBTableView1.BeginUpdate;
  try
    dxServerModeADOQueryDataSource1.Active := False;

    //build SQL statement based on checkstate
    SQL := 'SELECT * FROM LotsaRows';
    if Column3CheckBox.Checked then
      SQL := SQL + ' WHERE Column3 = 1';

    dxServerModeADOQueryDataSource1.SQL.Text := SQL;
    dxServerModeADOQueryDataSource1.Active := True;
  finally
    cxGrid1DBTableView1.EndUpdate;
  end;
end;

And that’s it! By swapping out the existing TdxServerModeADODataSource for its query-enabled counterpart, we can now specify a custom SQL SELECT statement and still benefit from “blazing fast” population, sorting, and grouping of one million rows of data.

You can download the updated Delphi sample source code here.

Open Source Solution for Migrating from ExpressScheduler to XtraScheduler

Introduction

Express2XtraScheduler is a .NET solution consisting primarily of two assemblies and a WinForms utility that simplify importing database data from the format stored by the DevExpress VCL ExpressScheduler into a format supported by the WinForms XtraScheduler control.

Contents

  • Express2XtraScheduler.Core.dll provides the functionality needed to import data from one format to another given a pair of database settings
  • Express2XtraScheduler.UI.dll provides UI controls for mapping source and destination database settings
  • Express2XtraScheduler.exe uses these assemblies to provide a simple utility for transferring data
  • ExpressSchedulerInterop.dll is a Delphi DLL used to read resource information stored as Delphi variants

Express2XtraScheduler App

The solution also contains two simple applications that allow testing both VCL and WinForms scheduler data: ExpressSchedulerApp and XtraSchedulerApp.

Resources

Below are links to blog posts that discuss some of the techniques used by this solution:

Availability

The source code for the Express2XtraScheduler solution is available immediately on this public Git repo hosted at Bitbucket.

Getting Started with the DevExpress VCL Wizard Control

Version 12.2 of the DevExpress VCL controls contains the long awaited ExpressWizard control. DevExpress released a WinForms version, their XtraWizard control, over four years ago. They have now delivered a native version of this same control for the Delphi VCL.

Features of the ExpressWizard control mirror those touted by DevExpress for their XtraWizard control:

  • You can design dialogs that conform to either the Wizard 97 or Wizard Aero standard… creating standard based UIs has never been easier.
  • Cutting-edge interfaces are only a few clicks away and developers can be certain that their wizard control will look and feel the same as all other DevExpress controls within their applications.
  • By using DevExpress fade in/fade out effects, developers can easily enhance their wizards during page transition operations.

It’s worth noting that the ExpressWizard control is a new product in the VCL subscription. This means that, when installing 12.2, you should select “Modify and Update” rather than simply “Update”. This will allow you to select ExpressWizard for installation.

DX VCL Setup

To get started with the ExpressWizard control, create a new VCL Forms Application in Delphi. Next, use the File, New, Other menu item to display the New Items dialog. Select Delphi Files on the left. On the right you’ll see a new entry: DevExpress 12.2 Wizard Form.

New Items Template

Select this item and click OK.

Using this Wizard Form template nets you three things:

  1. A new form descended from TdxWizardControlForm. This is necessary to support the Aero glass features of the TdxWizardControl (similar to the TdxRibbonForm).
  2. A TdxWizardControl parented on the new form
  3. A single TdxWizardControlPage added to the wizard control

The TdxWizardControl is also found on the component palette and can be dropped on any form. However, if you want to use the Aero style wizard, you’ll need to change your form’s ancestor. Starting in this manner (versus the template) will also give you an empty wizard control with no pages.

To check out the basic features of the wizard control, I’d like a total of three pages: a Welcome page, an Agreement page, and a Finished page. For the Agreement page, I’d like the Next button disabled until the user checks a checkbox. I’d also like the wizard to use the Aero style rather than the Wizard 97 style.

Pages can be added to the wizard control in two ways, both available from the TdxWizardControl and TdxWizardControlPage context menus.

Wizard Context Menu

You can either click New Page directly, or click Page Collection Editor to display a dialog for managing the wizard pages.

Page Collection Editor

Using one of these two methods, add two new pages to the TdxWizardControl. As with the rest of the DevExpress VCL controls, the designtime editors and experience are top notch. You can actually click on the Next and Back buttons at designtime to switch through the wizard pages.

Use the Next and Back buttons to select each wizard page. Then, adjust the Header.Title property so that the pages read Welcome, Agreement, and Finish. You can also adjust the Header.Description property, but this line of text will not be visible when using the Aero style wizard.

Next, add a TcxCheckBox to the Agreement page in the wizard and adjust its Caption property to indicate accepting the agreement.

Added Checkbox

In order to show the wizard we’ll need some code on our main form. Open up Unit1 and click the Design tab. Add a TcxButton to the form. While we’re here, let’s take a very quick look at a new feature of the TcxButton in 12.2. Set the Kind to cxbkCommandLink. Assign values to both the Caption and CommandLinkHint properties. Bump the Font.Size property up to 12 and resize the control to fit its contents. Finally, assign a OnClick event handler with the following code:

uses Unit2;

{$R *.dfm}

procedure TForm1.cxButton1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(Self);
  try
    Form2.ShowModal;
  finally
    Form2.Free;
  end;
end;

Click Run (or press F9) to check out the new button style.

TcxButton Runtime

Pretty nice huh?

Click the TcxButton to show the wizard dialog. You’ll see that, with no code, you can click Back and Next to navigate through the pages. In addition, the Back button automatically disables when you are on the first page. Also, the Next button caption automatically changes to Finish when you are on the last page of the wizard. However, clicking Finish and Cancel do not currently do anything. In addition, we need some code for our “agreement” and the wizard is still not the Aero style.

Close the app and return to Unit2. Select the TdxWizardControl and set the ViewStyle property to wcvsAero in the Object Inspector. Handle the OnCreate event of the TdxWizardForm itself with the following code to initialize the wizard:

procedure TForm2.FormCreate(Sender: TObject);
begin
  dxWizardControl1.ActivePageIndex := 0;
end;

Next, handle the OnClick event of the TcxCheckBox with the following code:

procedure TForm2.cxCheckBox1Click(Sender: TObject);
begin
  dxWizardControl1.Buttons.Next.Enabled := cxCheckBox1.Checked;
end;

Select the TdxWizardControl and handle its OnPageChanged event with the same logic:

procedure TForm2.dxWizardControl1PageChanged(Sender: TObject);
begin
  dxWizardControl1.Buttons.Next.Enabled := (dxWizardControl1.ActivePageIndex <> 1) or cxCheckBox1.Checked;
end;

Finally, handle the TdxWizardControl’s OnButtonClick event with the following code:

procedure TForm2.dxWizardControl1ButtonClick(Sender: TObject; AKind: TdxWizardControlButtonKind; var AHandled: Boolean);
begin
  if AKind = wcbkCancel then
    ModalResult := mrCancel
  else if AKind = wcbkFinish then
    ModalResult := mrOk;
end;

If you run the application again you’ll see the wizard is now functional. It starts on the Welcome page, and the Next button is disabled for the Agreement page unless the checkbox is checked. Finally, clicking Cancel or Finish dismisses the dialog.

Wizard Animated

Also, notice that each screen of the wizard fades in and out smoothly. Very nice!

You can download the Delphi source code for this example here.

Releasing the Source of VCL Controls based on DevExpress Look & Feel

The “cx-tras” package is a set of components I created nearly ten years ago and have been maintaining since. It is a set of visual components for Delphi that support DevExpress’s Look & Feel technology. This means that they automatically adjust their look based on the appearance and skin settings used in DevExpress VCL applications. The components were originally distributed by myself on request, then by DevExpress Support for a time, and now I’m giving them a home where anyone can access the source.

Various configurations for the Office Gizmo control

Demonstration of the Text Flow Panel control

Examples of the Close Button, Expand Button, and Size Grip

You can now access the source for the cx-tras package on Bitbucket here.

Emitting XtraScheduler Resource ID XML


I’ve recently been spending a bit of time directly accessing and manipulating the data that the DevExpress XtraScheduler emits when persisting its changes. You can read a bit about the structure of the data tables here and view the MSSQL schema here.

Most of the columns are relatively straight-forward, containing either strings or ordinal representations of enum values. However, the resource ID, reminder info, and recurrence info columns all contain specifically formatted XML strings. Luckily the DevExpress.XtraScheduler.XML namespace contains several helpful classes to assist in reading and writing these values.

In a previous blog post I discussed reading the resource ID’s stored by the VCL ExpressScheduler, returning them as a comma-delimited string. Given such a string called resources, in order to emit the proper XML you could do the following:

                string[] resourceArray = resources.Split(',');

                ResourceIdCollection idCollection = new ResourceIdCollection();
                foreach (string resourceID in resourceArray)
                {
                    idCollection.Add(int.Parse(resourceID));
                }

                AppointmentResourceIdCollectionContextElement element = new AppointmentResourceIdCollectionContextElement(idCollection);
                string xmlString = element.ValueToString();

With these few lines of code we have the necessary XML to access and store within the DB:

<ResourceIds>
  <ResourceId Type="System.Int32" Value="1"/>
  <ResourceId Type="System.Int32" Value="4"/>
</ResourceIds>

In a future post I’ll discuss emitting the XML representations of reminder and recurrence info as well.

UPDATE: There’s a real-world example of this technique you can find here. It is an open source project for transferring data from ExpressScheduler to XtraScheduler.

Accessing ExpressScheduler Resource Information from .NET

In a previous blog post I discussed how to access the recurrence information that the VCL ExpressScheduler stores in its DB from a .NET application. Reading and writing the recurrence information is possible from .NET given a knowledge of the struct layout that the Delphi control uses.

However, if you want to read the resource information that ExpressScheduler stores in its DB from .NET, this requires using a Delphi DLL. This is because the Delphi scheduler control stores the resource ID’s for appointments in a single field but in multiple formats depending on the appointment. For instance, if the appointment has only one associated resource, its resource ID will be stored as a Delphi variant. However, the value will be stored as a Delphi variant array of variants if the appointment is associated with multiple resources.

Luckily, both Delphi and .NET make it straight-forward to interoperate between them and DevExpress has a simple utility method we can use to simplify things as well.

Start off with a new Delphi DLL project by clicking File>New>Other in Delphi XE2. On the New Items dialob, select Delphi Projects followed by Dynamic-link Library.


Start by adding both Variants and cxSchedulerStorage to the uses clause of the DPR. Then, add the following exported method to the DPR:

procedure ResourceIDBlobToString(const AResourceID: PByteArray; out AResult: PByteArray); export; stdcall;

var
  ResourceIDVar: Variant;
begin
  ResourceIDVar := cxFieldValueToVariant(AnsiString(AResourceID));
  if VarIsArray(ResourceIDVar) then
    AResult := PByteArray(VarArrayToArrayStr(ResourceIDVar))
  else
    //the cast to AnsiString below is necessary or a Unicode string will sneak in and gum up the works
    AResult := PByteArray(AnsiString(VarToStr(ResourceIDVar)));
end;

exports ResourceIDBlobToString;

This method uses the cxFieldValueToVariant utility method found in cxSchedulerStorage to translate the string representation of the field value to a Delphi variant. We then use VarIsArray to test if the variant is an array. If it is not, we simply return the variant as a string. If the variant is a variant array, we will use the following method to parse it:

//input is a variant array of strings
//output is a comma delimited string composed of the members of the input array
function VarArrayToArrayStr(const ResourceIDArray: Variant): AnsiString;
var
  I: Integer;
begin
  Result := '';
  for I := VarArrayLowBound(ResourceIDArray, 1) to VarArrayHighBound(ResourceIDArray, 1) do
  begin
    if Result <> '' then
      Result := Result + ',';
    Result := Result + VarToStr(ResourceIDArray[I]);
  end;
end;

This simple function iterates through the variant array using VarArrayLowBound and VarArrayHighBound, building up a comma-delimited list of the resource ID’s.

And that’s it for the Delphi DLL.

Next we’ll create a new C# WinForms solution to test out our DLL. Click File>New>Project and select a Windows Forms Application.


I’ll skip the data access code as it’s straight-forward. The interesting bit here is the DllImport attribute we’ll use to call our Delphi DLL:

[DllImport("ExpressSchedulerInterop.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
static extern void ResourceIDBlobToString([MarshalAs(UnmanagedType.AnsiBStr)] string resourceID, [Out, MarshalAs(UnmanagedType.AnsiBStr)] out string result);

With this method defined properly, the following code can be used to read the resource data from the DB in C#:

string result = null;
ResourceIDBlobToString((string)reader["ResourceID"], out result);

You can download a Delphi scheduler app here, the Delphi scheduler interop project here, and the C# example data reader here.

UPDATE: I updated the code in this Blog post, along with the interop Delphi project source, to address a bug when using Unicode versions of Delphi. A cast to AnsiString is necessary or only the first character in the resource ID will be returned.

UPDATE #2: There’s a real-world example of this technique you can find here. It is an open source project for transferring data from ExpressScheduler to XtraScheduler.

Adding Some Style to the VCL TileControl

In my previous post in the DevExpress VCL TileControl I laid out the basics of getting a Metro-inspired application functional. However, while the result definitely had function, it was a little short on “form”.

When using the VCL TileControl, odds are you will also want a Metro-inspired skin for your application. While the ExpressSkins Library does not currently ship with any Metro-inspired skins, the RealtorWorld demo that ships with the DevExpress VCL TileControl includes two such skins: MetroBlack and MetroWhite.

Making use of these skins in your own Metro-inspired VCL application is a cinch.

To get started, copy the two SKINRES files from the following path to your own application’s working directory:

C:Program FilesDeveloper Express.VCLExpressTile ControlDemosData

Next, locate the TdxSkinController component on the Tool Palette and add it to Form1 of the TileControlSample project created in my previous post. You can download the source to that project here.


Add a FormCreate handler to Form1 with the following code:

procedure TForm1.FormCreate(Sender: TObject);
begin
  dxTileControl1.LookAndFeel.NativeStyle := False; //so skins take affect
  dxSkinController1.SkinName := 'UserSkin'; //so we can load a .skinres
  dxSkinsUserSkinLoadFromFile('MetroBlack.skinres');
end;

And that’s all it takes to give our sample a dark, Metro-inspired skin.


Replace the reference to MetroBlack.skinres with MetroWhite.skinres in order to use the lighter Metro-inspired skin.

You can download the updated Delphi sample here.

Getting Started with the DevExpress VCL TileControl

In my previous posts I discussed the new “Server Mode” feature for the VCL grid from DevExpress found in version 12.1 of their VCL controls. Another great new feature found in version 12.1 is the new TileControl. This control lets any VCL developer start creating Metro-inspired UI’s in very little time with little-or-no code. Let’s see how!

Start off by creating a new VCL Forms Application. Afterward, create two new VCL forms by clicking File > New > VCL Form. Ensure all three forms will be automatically created by clicking Project>Options>Forms.


Switch to the Form2 and Form3 designers, setting their BorderStyle property to bsNone and Visible property to True. I also added a TShape to Form2 and Form3 with unique colors to make them easier to discern.

After customizing Form2 and Form3, switch back to the main form of the example, Form1. Under the “Dev Express” section of the Tool Palette, location the TdxTileControl and add it to the Form1 designer.


Right-click the TdxTileControl to display its context menu and use the Add Item menu item to add three tiles.


Select the first item in the TdxTileControl and inspect its properties. Expand the DetailOptions node. For DetailControl, select Form2. Note that you may need to add Unit2 and Unit3 to the uses clause of Unit1. Also, add a value for DetailOptions.Caption. Finally, set ShowTab to True.


Configure the second tile item in nearly the same way, only using Form3 instead of Form2.

For the third tile item, I’ll illustrate how to use a TFrame. Add a new TFrame to the project by clicking File>New>Other and selecting VCL Frame.


Switch to the designer for Frame1 and add another TShape with a unique color. Set the Align property on the TShape to alClient.


With the frame configured, switch back to the designer for Form1 and select the third tile item. Expand DetailOptions in the Object Inspector. This time leave DetailControl blank and set ShowTab to False. In the compiled example you’ll see the affect that the ShowTab property has.


Finally, click on the Events tab in the Object Inspector and add an event handler for OnClick.


In the event handler, use this small bit of code to check to see if DetailControl is assigned and, if not, create and assign an instance of TFrame4.

procedure TForm1.dxTileControl1dxTileControlItem3Click(
  Sender: TdxTileControlItem);
begin
  if Sender.DetailOptions.DetailControl = nil then
    Sender.DetailOptions.DetailControl := TFrame4.Create(Self);
end;

You’ll also need to add Unit4 to the uses clause of Unit1.

And that’s it! Run the sample and you’ll see your three tiles. You can rearrange them using drag-and-drop. Clicking any of the three tiles will animate in either Form2, Form3, or Frame4, depending on the tile. You’ll also see a nice set of tabs in the upper right. Here you’ll see that the third tile item did not get a tab due to setting ShowTab to false.


You can download the Delphi source code for this example here.

Getting Started with Server Mode for ExpressQuantumGrid

In my previous blog post I went over some of the performance benefits of the new “Server Mode” feature for the VCL grid from DevExpress. In this brief post, I’ll go over the steps needed to get started using this new feature. In this example I’ll be targeting Microsoft SQL Server using ADO.

You’ll want to start off by creating a new VCL Forms Application. Add a TcxGrid control to the form. Right-click the default grid level to invoke the level’s context menu. From there, create a new Server Mode grid view.


Next, drop a TADOConnection component on the form. It can be found in the dbGo section of the Tool Palette, or by using he Search box.


With the TADOConnection component selected, configure it by setting LoginPrompt to False and clicking the elipsis next to ConnectionString to configure the underlying connection.


As I mentioned, in this example I’m targeting Microsoft SQL Server. The project source linked at the end of the blog post contains SQL scripts for creating a sample table and filling it with data. Use the Data Link Properties dialog to configure the connection.


With the connection configured, locate the TdxServerModeADODataSource on the tool palette and drop it on the form. The “Server Mode” datasource is responsible for taking the needs of the TcxGrid view and creating SQL queries that return only the data necessary to render the results on-screen.


The data source only has a few properties. Start off by setting Options.SQLAdapter to “MSSQL Adapter”. If you don’t set the Options.SQLAdapter, trying to configure other properties will let you know you’ll need to assign that property first. Next, set the Connection, after which you can use the drop down lists to select your TableName and KeyFieldNames.


With the datasource setup, we’re in the home stretch. Select the “Server Mode” view by clicking the “cxGrid1ServerModeTableView1″ UI element on the TcxGrid control. With the view selected, expand the DataController node in the Object Inspector and assign the DataSource property.


Right-click the “cxGrid1ServerModeTableView1″ UI element on the TcxGrid control and click “Create Missing Columns” to have the grid automatically create the columns found in the underlying data.


And that’s it! Running the application will leave you with a “blazing-fast” grid capable of loading, sorting, grouping, and filtering millions of rows of data.


You can download the Delphi source code and SQL scripts here.