Actions in XE3

Posted by on in Blogs
This post is published a bit late. Beginning of this September would be the better time, but better late than never…
In XE3 release of our cross platform FireMonkey library, we, at last, have provided support for Actions. This support has enforced some changes in both the platform-independent Actions engine and in the VCL (platform-specific) implementation of Actions.

What to be changed in legacy VCL projects

Notice that in XE3 Help describing Actions was considerably changed, so it is reasonable to review at least the following sections: "FireMonkey Actions" and "Changes in Implementation of VCL Actions".

Despite most actions components like TActionList, TAction, and others are pseudo-visual components, almost all actions functionality was implemented in VCL classes. From the other hand, only some actions functionality are tightly linked to VCL (Windows) features. (First of all, platform-dependant actions features are linked with managing of images in TBitmap, TImageList classes.) However, most of actions features are not strongly linked with a specific OS, so in XE3 many actions classes were moved from the high level of VCL library into the more basic level units of RTL library. In most cases, changes are implemented as simple moving of code from VCL units to RTL units:

  • Implementing this approach, we have created the System.Actions unit. Notice, that you have to add the System.Actions unit to the uses section of your VCL legacy projects using actions

In addition, during compilation of legacy programs, some warnings can appear, indicating that some types are obsolete. For example, the TImageIndex type is now declared in the System.UITypes unit. The Vcl.ImgList unit also still contains the declaration of the same TImageIndex type (for compatibility), however, this declaration is treated obsolete and probably it will be deleted in one of the new coming releases. In order to decrease the number of warnings one needs to include System.UITypes right after Vcl.ImgList. If this is impossible, use the explicit reference to the unit, like:

FImageIndex: System.UITypes.TImageIndex;

The common ancestor classes in RTL to action engine classes in both VCL and FireMonkey frameworks (in RAD Studio we use the term frameworks to VCL and FireMonkey) are TBasicAction, TBasicActionLink, TContainedAction, TContainedActionLink, TContainedActionList, TCustomShortCutList, etc.

The most interesting is TContainedAction. In the XE2 version, this class contains only the Category property. In XE3 it contains almost all framework-independent general properties of actions. Framework-specific general ancestor of actions classes is TCustomAction. It is declared in the Vcl.ActnList and FMX.ActnList units.

Every registered action can be used only under the corresponding framework, otherwise VCL-application can link some FMX libraries and vice versa. While it is no problem to identify the framework corresponding to a form, for the TDataModule we introduce a “magic” property ClassGroup, which is written in pas-files, rather than in dfm files:

{%CLASSGROUP 'FMX.Types.TControl'}
{$R *.dfm}

The value of this property is used only by IDE to filter icons in ToolPalette to make visible only components available in the current framework. The project framework is stored in the dproj file of a project, like:

<Project xmlns="">

  • When editing legacy VCL or FireMonkey projects, one may need to add ClassGroup properties into the dproj files.

What is new

Into the TContainedAction class, we add the StatusAction property of the enumerated TStatusAction type. Creating new controls, you can use it like “validators” to indicate a state from possible variants. It can be considered as an advanced analog to the Enabled property.

An exception class EActionError is added in the System.Actions unit. It is raised when different errors with actions happen.

System.Classes, contains the following code:

TBasicAction = class(TComponent)
  FClients: TList<TBasicActionLink>;
  [Weak]FActionComponent: TComponent;

This does not have the direct relation to the current implementation of actions, but one can notice the preparation to implementation of new compilers with reference counting. Where it is possible, we avoid usage of Pointer types and type conversions, so TList is replaced by TList<T>. The word [Weak] denotes that FActionComponent do not increase the reference counter for links.

Managing actions in IDE

The common functionality is implemented in the ActionEditors unit. This unit is not added to a customer project code, it is used only by IDE. The source code of the unit is presented only for acquaintance.

Without going into details I can only recommend to read comments in the file, if you want to build up your own framework. Please, remember, the IDE still works only under Windows and VCL. In order to support the interaction with platform-independent part (rare case when VCL works together with FM) the class TIDEActions is added. Each framework must declare its own class descending to TIDEActions and register it using the RegisterActionsInFramework procedure. For additional information, see Help.

In Fire Monkey

Let us describe briefly describe some not obvious new features.

The Action property was added to the base TfmxObject class, however it is not public in all the controls. Nevertheless all descendants of TCustomEdit support it, and you can assign to it at run time.

Text — this property was added to class TAction, because all Fire Monkey controls have this property. Actually, it is the same as Caption.

UnsupportedArchitectures and UnsupportedPlatforms. You can define architectures and OSs, which do not support particular actions; that is, an action is unavailable, invisible, and cannot be updated. In the first UnsupportedArchitectures property you can define unsupported architectures (32/64-bit), in the second UnsupportedPlatforms property one can set unsupported OS (Windows/Mac OS). By default these properties are empty, so an action is supported in all the cases.

Virtual function IsSupportedInterface. Often an action can invoke some interface. The function returns False, if the interface is not implemented. For example, the on-screen keyboard is available only under Windows.

HideIfUnsupportedInterface. This property indicates, whether the action should be hidden, if the interface is not implemented (see IsSupportedInterface). For example, it is possible, that the user does not need to know that some interfaces are not implemented, but in other times, it is possible, that a error should be generated to notify the user.

Supported — the read-only property, it can be set in the UpdateSupported method according the values of the described above HideIfUnsupportedInterface, IsSupportedInterface, UnsupportedArchitectures, and UnsupportedPlatforms properties.

ShortCutPressed — is the property, indicating whether the onExecute event was fired by pressing some combination of keys. Sometimes, it is handy to know the pressed key confirmation. For example, to check whether the user has accidently pressed an unknown key combination. If the user selects a menu item, he has definitely read the item text.

ShortCut — the meaning of the property is the same as in VCL, however in FireMonkey you can change the list of possible key combination in IDE (see functions RegisterShortCut and UnrigesterShorCut). In addition, one can pass some number in brackets. For example, '(32787)' for 'Alt+Pause'. This is a two-byte value; the lower byte stores a virtual key (vkXXX constants defined in System.UITypes), and the higher byte stores a mask corresponding to key modifier key (scXXX constants defined in System.Classes). scXXX constants are:

scCommand = $1000;
scShift = $2000;
scCtrl = $4000;
scAlt = $8000;

Virtual key constants vkXXX have different numeric values for Mac OS and Windows. For all platforms the virtual key numbers will be transformed to the corresponding constant value under Windows, it is possible.

Planning shortcut key combinations one should note, that the exact mapping is not possible. For example, in Mac OS the combination Alt+<letter> means the input of special symbols. The same can happens under Windows, for example, for German keyboard layout if one press right 'Alt+E', the "Euro" symbol appears. In addition, some combinations are reserved by the system and are not sent to the application.

Among standard actions let us describe TViewAction and TValueRangeAction. The others correspond to VCL analogs.

TViewAction allows managing visibility of controls and forms, letting a developer to skip typing trivial code. The action has the FmxObject property. The method ExecuteTarget set the property FmxObject.Visible as True. If FmxObject is not defined, the event handler OnCreateComponent will be called, where one can create a new object. If one set the property Visible of FxmObject to False, this property of TViewAction doe not change in contract to other actions.

TValueRangeAction allows to set some value in a specific range (see property ValueRange) and is used in TTrackBar, TProgressBar, TNumberBox, TComboTrackBar and so on. The ActionsDemo example is available.


  • Guest
    roschinspb Thursday, 4 October 2012

    Thank Vsevolod Leonov for the transfer.

  • Please login first in order for you to submit comments
  • Page :
  • 1

Check out more tips and tricks in this development video: