Inspecting the default ‘platform’ FMX styles in XE3 (if you’re interested in that sort of thing)

One of the more obvious changes in FireMonkey between the XE2 and XE3 releases is the (much) better default styling on Windows in particular. To my eyes this makes FMX controls in XE3 look like custom drawn VCL ones that try to look native (e.g. TSpeedButton), which for me at least is ‘good enough’ in principle, notwithstanding the odd tweak that still needs to be made in practice.

The main technical reason for this improvement is the use of bitmaps rather than an all-vector approach. Going by the limited help and marketing information, you may think this involves a new FMX style format (the XE2 one was in essence just the old DFM format), but this is not true – rather, the bitmaps used by the new platform styles are just hosted in a TImage control inside the style structure. In order to avoid unnecessary duplication and the inefficient use of lots of small bitmaps, a new TSubImage component has also been added to allow each platform style to have one big bitmap that different style elements can then reference different parts of. While TSubImage itself is not registered onto the Tool Palette (perhaps an oversight?), you can find it present and correct in FMX.Objects.pas, and when you do, you’ll find there’s very little to it.

What might lead you astray in thinking there is more to things than that is the fact XE2’s VCL style editor has been renamed the ‘Bitmap Style Editor’ in XE3. However, the extra functionality behind the name change is an FMX style export facility. While this will probably prove a valuable feature, the program still cannot open even the native FMX style files (*.style) it itself has created. The (very) early market for third party FMX style editors like Mike Sutton’s MonkeyStyler is therefore still very much open!

Inspecting the XE3 platform styles

Annoyingly enough, unlike in XE2, the platform styles for FMX in XE3 are not directly distributed with the product. I say annoyingly, since the ability to easily inspect the details of a style can be very useful. For example, having used a TTreeView control with a TLabel embedded right-aligned in each node for additional text, I quickly discovered that the OS X style uses a different font colour for selected tree view items that my additional labels weren’t picking up. Wanting to identify this colour at runtime, I initially tried to use the IDE’s style editor to locate what properties I needed to look up. However, this proved a fool’s errand – quite apart from the fact the native FMX style editor seems to be missing half its proper functionality, there wasn’t the OS X style file around to load into it in the first place!

Nonetheless, on browsing the FMX source folder I quickly came across the FMX.Platform.Win.rc and FMX.Platform.Mac.rc resource scripts. While the style files these reference are not shipped, the scripts clearly identify the resource names used (win7style and win8style for the Windows platform styles, and lionstyle and lion2xstyle for the OS X ones); and on closer inspection, the style resources themselves proved to be the raw *.style files, saved in the binary DFM format, and prepended with a 13 byte header. Putting all this together, I quickly wrote the following program to extract human-readable *.style files:

program Project1;

{$R *.res}

{$R 'C:\Program Files\Embarcadero\RAD Studio\10.0\lib\win32\release\FMX.Platform.Win.res'}
{$R 'C:\Program Files\Embarcadero\RAD Studio\10.0\lib\osx32\release\FMX.Platform.Mac.res'}

uses
  System.Types, System.SysUtils, System.Classes;

procedure ExtractStyle(const ResName, DestFileName: string);
var
  Input: TResourceStream;
  Output: TFileStream;
begin
  Output := nil;
  Input := TResourceStream.Create(HInstance, ResName, RT_RCDATA);
  try
    Input.Seek(13, soCurrent);
    Output := TFileStream.Create(DestFileName, fmCreate);
    ObjectBinaryToText(Input, Output);
  finally
    Input.Free;
    Output.Free;
  end;
end;

begin
  ExtractStyle('win7style', 'C:\Users\CCR\Documents\Win7.style');
  ExtractStyle('win8style', 'C:\Users\CCR\Documents\Win8.style');
  ExtractStyle('lionstyle', 'C:\Users\CCR\Documents\Lion.style');
  ExtractStyle('lion2xstyle', 'C:\Users\CCR\Documents\Lion2x.style');
end.

Adjust the paths as appropriate, run the application, and you’re done.

Advertisements

12 thoughts on “Inspecting the default ‘platform’ FMX styles in XE3 (if you’re interested in that sort of thing)

  1. Yeah had to edit a TreeView to show selection highlite as White Text on Black ( don’t ask why 🙂 ) tried and succeed in Windows by using a small part of the CheckBox and streching that to a DarkGray except as default this DOESN’T translate across to the MAC.

    Solution was to (hand code) replace the TSubImage with an FM1 style TRectangle and Bob is your slightly queer Aunty

  2. Thanks Chris, I was looking for these style files either. Bythe way, I have started a new blog in delphiscience.wordpress.com to share my experince. I would be happy if you add it to your links widget.

  3. Pingback: Inspecting ‘platform’ styles redux | Delphi Haven

  4. How do I get this to work in XE5? I’ve opened a new VLC form and copy pasted the code but it is not working. It gives the error that the style cannot be found.

    • It changes on a release-by release basis. Use the ‘Bitmap Style Designer’ and create a new FMX style there.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s