Watch, Follow, &
Connect with Us

Embarcadero Blogs

Latest Posts

Customizing VCL Styles with RAD Studio XE7

Delphi, C++Builder and RAD Studio include various VCL styles out of the box. These can be used for your Windows applications and customized via the included Bitmap Style Designer (Tools->Bitmap Style Designer). You can also create a new style from scratch. The easiest way to get started with a brand new style is to use the VCL style template in the Bitmap Style Designer as a guide. Below is a general outline of the steps required.

  • a) File->’New style for VCL or FireMonkey’ to start with a template
  • b) File->Open to select an existing .vsf style (i.e. Carbon.vsf or Auric.vsf) for editing
  • Expand the Images node and click on ’style.png’
  • Click ‘Export’ to export the png to a folder on your hard drive
  • Open the png with the graphics program of your choice. In my case, I used Photoshop
  • After you are done editing the style/creating a new style, select the style.png in the Style Designer, click update and select the updated png to replace the existing png
  • Select each style element, and create a selection outline for each bitmap associated with a specific Bitmap property (hot, pressed etc.) in the Inspector
  • Save the vsf style and apply it to your VCL application

In my case, I wanted to customize the CharcoalDarkSlate.vsf VCL style that can be found in C:\Users\Public\Documents\RAD Studio\15.0\Styles

I opened the png in Photoshop. You can design several states for each graphic via the Bitmap property in the Inspector, i.e. Bitmap, BitmapHot, BitmapPressed, BitmapFocused etc.. In my example, I decided to change the style of the system close button from a dark circle to a blue square.

After creating the new shapes in Photoshop, I pasted them into the style.png. You can just place them over the existing circular buttons and cover them, or remove those from the graphic beforehand. We are going to select an outline for each button later on, so either approach works. Key is to keep the transparency of the style.png file.

I also update the style of the trackbar to a brown/wooden theme.

After completing the style changes, I saved my new style.png file, went back to the style in the Style Designer and clicked on Update. I then browsed to the location of my new style, selected it and clicked OK.

To make sure the new close buttons are properly mapped, expand the Objects-Form node until you have the sysButtons-btnClose node selected:

In the Inspector, select the … next to Bitmap. The Bitmap Property Editor appears. This editor allows you to select the outline of your clickable button. Click to select the left top corner of the button via a simple mouse click. Then, to select the bottom right corner (to create the entire outline), control-click onto the bottom right of the square button. Repeat this process for each of the Bitmap options in the Object Inspector for the selected style element.

When you are done, click ‘Save’ and preview your style in the VCL Style Viewer by clicking F9 in the Bitmap Style Designer.

Below is an example of what the Trackbar styling looks like.

To be able to utilize this style in your VCL applications, place the .vsf file into C:\Users\Public\Documents\RAD Studio\12.0\Styles

As my final step, I created a new VCL application in the IDE and placed the Trackbar component onto my form. Via Project->Options->Application->Appearance, I selected my custom style from the list, and also made sure it was selected as the ‘Default Style’ in the drop-down menu and clicked OK to select the style.

In order to see the style, you will need to run your application since VCL styles are shown at runtime.

posted @ Wed, 22 Oct 2014 17:34:43 +0000 by sarinadupont

Displaying Cloud Based Data with A to Z ListView Headers

With TListView and LiveBindings, it is easy to display cloud based data in a sorted manner using listview headers.

Working with sorted data

If the data is already sorted, i.e. we have two columns, one for recipe title and one for the food category, you can just bind ‘Category’ into ItemHeader.Text to display food category headers for each of the recipes. This displays each recipe under its category header.

In the Structure pane, under ListView1-LiveBindings-LinkListControlToField1, you can further customize the style of your header.

Select your ItemHeader.Text to Category binding in the LiveBindingsDesigner, and then in the Object Inspector, toggle between the three FillHeaderCustomFormat options.

The application consists of the following components:
User Interface
  • TListView, aligned to the client
  • TToolbar, aligned to the toolbar
  • TLabel, aligned to Contents and parented to TToolbar
  • TStyleBook (displaying premium EmeraldDark style)
  • TBackendQuery (for querying existing data that lives in the cloud and was added via the BaaS web interface)
  • TKinveyProvider (AppKey, AppSecret and MasterSecret have been set; you can also use TApp42Provider and TParseProvider)
  • TRestResponseDataSetAdapter
  • TFDMemTable
If you wanted to alphabetically sort the recipes in the list without displaying them in a grouped fashion under category headers, you could bind both Item.Text and ItemHeader.Text into FDMemTable1 - RecipeTitle. Then set FillHeaderCustomFormat to SubString(%s, 0, 1).

posted @ Tue, 21 Oct 2014 18:33:25 +0000 by sarinadupont

Creating a Bluetooth LE cloud enabled luggage scale application

Every time I travel somewhere, I am concerned that my luggage might exceed the weight limit. With RAD Studio XE7 and the Wahoo Bluetooth Scale, I built a luggage scale application that allows me to weigh my luggage and store data about my luggage contents in the cloud.

The app UI consists of a TTabControl with 3 tabs:

  • WeightScale - for weighing my luggage and saving the weight and associated notes
  • Logged Data - for retrieving existing luggage data and displaying it in a list
  • Settings - for displaying my bluetooth data

In addition to the various UI components, the app also contains a TBluetoothLE component, a TStyleBook component (for loading and assigning my custom Jet style) and the following BaaS components:

  • TKinveyProvider (AppKey, AppSecret and MasterSecret match my credentials)
  • TBackendQuery (connected to TKinveyProvider)
  • TBackendStorage (connected to TKinveyProvider)
  • TRestResponseDataSetAdapter
  • TFDMemTable

The scale I am working with is the Wahoo Balance scale.

Here is the Object Pascal code for my application:

unit WeightScaleForm1;


  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Ani, FMX.StdCtrls, System.Bluetooth, FMX.Layouts,
  FMX.Memo, FMX.Controls.Presentation, FMX.Edit, FMX.Objects, IPPeerClient, IPPeerServer,
  System.Tether.Manager, System.Bluetooth.Components, FMX.TabControl,
  REST.Backend.ServiceTypes, REST.Backend.MetaTypes, System.JSON,
  REST.Backend.KinveyServices, REST.OpenSSL, REST.Backend.KinveyProvider,
  REST.Backend.Providers, REST.Backend.ServiceComponents, FMX.ListView.Types,
  Data.Bind.Components, Data.Bind.ObjectScope, REST.Backend.BindSource,
  FMX.ListView, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  REST.Response.Adapter, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client,
  System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.EngExt,
  Fmx.Bind.DBEngExt, Data.Bind.DBScope;


  TSensorContactStatus = (NonSupported, NonDetected, Detected);

  THRMFlags = record
    HRValue16bits: boolean;
    SensorContactStatus: TSensorContactStatus;
    EnergyExpended: boolean;
    RRInterval: boolean;

  TfrmWeightMonitor = class(TForm)
    BluetoothLE1: TBluetoothLE;
    TabControl1: TTabControl;
    WeightScale: TTabItem;
    History: TTabItem;
    Panel1: TPanel;
    Memo1: TMemo;
    Panel2: TPanel;
    btnConnect: TButton;
    lblDevice: TLabel;
    lblWeight: TLabel;
    btnDisconnect: TButton;
    Settings: TTabItem;
    ToolBar1: TToolBar;
    Label1: TLabel;
    ToolBar2: TToolBar;
    ToolBar3: TToolBar;
    Label3: TLabel;
    btnSave: TButton;
    KinveyProvider1: TKinveyProvider;
    BackendStorage1: TBackendStorage;
    AppTitle: TLabel;
    title: TLabel;
    lbs: TLabel;
    ListView1: TListView;
    BackendQuery1: TBackendQuery;
    FDMemTable1: TFDMemTable;
    RESTResponseDataSetAdapter1: TRESTResponseDataSetAdapter;
    FDMemTable1_id: TWideStringField;
    FDMemTable1Weight: TWideStringField;
    FDMemTable1_acl: TWideStringField;
    FDMemTable1_kmd: TWideStringField;
    BindSourceDB1: TBindSourceDB;
    BindingsList1: TBindingsList;
    LinkListControlToField1: TLinkListControlToField;
    FDMemTable1LuggageDetails: TWideStringField;
    ImageControl1: TImageControl;
    StyleBook1: TStyleBook;
    Image1: TImage;
    procedure btnConnectClick(Sender: TObject);
    procedure BluetoothLE1EndDiscoverDevices(const Sender: TObject; const ADeviceList: TBluetoothLEDeviceList);
    procedure BluetoothLE1CharacteristicRead(const Sender: TObject; const ACharacteristic: TBluetoothGattCharacteristic;
      AGattStatus: TBluetoothGattStatus);
    procedure btnDisconnectClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure LinkListControlToField1FilledListItem(Sender: TObject;
      const AEditor: IBindListEditorItem);
    procedure FormCreate(Sender: TObject);
    procedure HistoryClick(Sender: TObject);
    { Private declarations }
    FBLEDevice: TBluetoothLEDevice;
    FWeightGattService: TBluetoothGattService;
    FWeightMeasurementGattCharacteristic: TBluetoothGattCharacteristic;
    procedure GetServiceAndCharacteristics;
    { Public declarations }

  ScaleDeviceName = 'Wahoo Scale';
  ServiceUUID = '';
  CharactUUID = '';

  // 0x1901 is the weight service
  // 0x2B01 is the live weight characteristic readings    0x84ae0000 0001      - 38 lbs   17kg
  // 0b 10000100101011100000000000000000

  Weight_Device: TBluetoothUUID = '{00001901-0000-1000-8000-00805F9B34FB}';
  Weight_Service: TBluetoothUUID = '{00001901-0000-1000-8000-00805F9B34FB}';
  Weight_Characteristic: TBluetoothUUID  = '{00002B01-0000-1000-8000-00805F9B34FB}';

  frmWeightMonitor: TfrmWeightMonitor;


{$R *.fmx}
{$R *.iPhone4in.fmx IOS}

procedure TfrmWeightMonitor.btnConnectClick(Sender: TObject);
  lblWeight.Text := '0';
  lblDevice.Text := '';
  BluetoothLE1.DiscoverDevices(3500, [Weight_Device]);

procedure TfrmWeightMonitor.btnDisconnectClick(Sender: TObject);
If FBLEDevice <> nil then
  BluetoothLE1.UnSubscribeToCharacteristic(FBLEDevice, FWeightMeasurementGattCharacteristic);
  btnDisconnect.Enabled := false;  // disable disconnect from subscribe scale button
  btnConnect.Enabled := true;  // enable connect to scale button

//store luggage notes in the cloud
procedure TfrmWeightMonitor.btnSaveClick(Sender: TObject);
  LJSON : TJSONObject;
  ACreatedObject: TBackendEntityValue;
  luggagedetails	: string;
    LJSON := TJSONObject.Create;
if InputQuery('Luggage BaaS Cloud Store', 'Enter Notes about your Luggage', luggagedetails)
     LJSON.AddPair('Weight', lblWeight.Text);
     LJSON.AddPair('LuggageDetails', luggagedetails);
     BackendStorage1.Storage.CreateObject('luggagecloud', LJSON, ACreatedObject);
     ShowMessage('Luggage weight and notes stored');

procedure TfrmWeightMonitor.FormCreate(Sender: TObject);

procedure TfrmWeightMonitor.BluetoothLE1EndDiscoverDevices(const Sender: TObject;
  const ADeviceList: TBluetoothLEDeviceList);
  I: Integer;
  // log
  Memo1.Lines.Add(ADeviceList.Count.ToString +  ' devices discovered:');
  for I := 0 to ADeviceList.Count - 1 do Memo1.Lines.Add(ADeviceList[I].DeviceName);

  if BluetoothLE1.DiscoveredDevices.Count > 0 then
    FBLEDevice := BluetoothLE1.DiscoveredDevices.First;
    ShowMessage('Connected to Wahoo Scale');
    if BluetoothLE1.GetServices(FBLEDevice).Count = 0 then
      Memo1.Lines.Add('No Weight services found!');
      lblWeight.Text := 'No Weight services found!';
    else begin
      Memo1.Lines.Add('Wahoo Services Found: '+ IntToStr(BluetoothLE1.GetServices(FBLEDevice).Count));
      btnDisconnect.Enabled := true;  // enable disconnect from subscribe scale button
      btnConnect.Enabled := false;  //disable connect to scale button
      // get Weight Service and Characteristic
    lblDevice.Text := 'Weight Device not found';

procedure TfrmWeightMonitor.GetServiceAndCharacteristics;
  FWeightGattService := nil;
  FWeightMeasurementGattCharacteristic := nil;
  // get Weight Service by UUID
  FWeightGattService := BluetoothLE1.GetService(FBLEDevice, Weight_SERVICE);

  if FWeightGattService <> nil then begin
    memo1.Lines.Add('Service: '+FWeightGattService.UUID.ToString);
    // get Weight Characteristic
    Memo1.Lines.Add('Looking Char: '+Weight_CHARACTERISTIC.ToString);
    FWeightMeasurementGattCharacteristic := BluetoothLE1.GetCharacteristic(FWeightGattService,Weight_CHARACTERISTIC);

    if FWeightMeasurementGattCharacteristic <> nil then begin
      Memo1.Lines.Add('Char: '+FWeightMeasurementGattCharacteristic.UUID.ToString);
      // subscribe to the weight service
      BluetoothLE1.SubscribeToCharacteristic(FBLEDevice, FWeightMeasurementGattCharacteristic);
      Memo1.Lines.Add('Subscribed to Weight Measurement Characteristic');
    else begin
      Memo1.Lines.Add('Weight Char not found');
      lblWeight.Text := 'Weight Char not found';
  else begin
    Memo1.Lines.Add('Weight Service not found');
    lblWeight.Text := 'Weight Service not found';

//query BaaS provider for existing luggage data
procedure TfrmWeightMonitor.HistoryClick(Sender: TObject);

//display weight icon next to each row in TListview
procedure TfrmWeightMonitor.LinkListControlToField1FilledListItem(
  Sender: TObject; const AEditor: IBindListEditorItem);
  LItem: TListViewItem;
  LItem := AEditor.CurrentObject As TListViewItem;
  LItem.BitmapRef := ImageControl1.Bitmap;

procedure TfrmWeightMonitor.BluetoothLE1CharacteristicRead(const Sender: TObject;
  const ACharacteristic: TBluetoothGattCharacteristic; AGattStatus: TBluetoothGattStatus);
  LSValue: string;
  HexValue: string;
  WeightPounds : double;
  if AGattStatus <> TBluetoothGattStatus.Success then
    Memo1.Lines.Add('Error reading Characteristic ' + ACharacteristic.UUIDName + ': ' + Ord(AGattStatus).ToString)
    LSValue := IntToStr(ACharacteristic.GetValueAsInteger);
    Memo1.Lines.Add(ACharacteristic.UUID.ToString + ' String: ' + LSValue);
    // calculate weight - characteristic is in hectograms
    WeightPounds := (ACharacteristic.GetValueAsInteger shr 8) * 0.2205;
    Memo1.Lines.Add('Weight (pounds): '+Format('%8.2f',[WeightPounds]));
    lblWeight.Text := Format('%8.2f',[WeightPounds]);


posted @ Mon, 20 Oct 2014 23:49:14 +0000 by sarinadupont

Reserve your space: CodeRage 9 - the Delphi developer event of the year

CodeRage 9 - The totally technical online conference for Delphi, C++Builder and RAD Studio dedvelopers is just around the corner. The free online conference will be taking place October 28-30.

Join us for CodeRage® 9, the totally free, totally technical online conference for software developers. This year's conference brings you top industry speakers and technologists presenting on a wide variety of topics, all geared toward maximizing your software development productivity. 
The theme for this year's CodeRage conference is "You are the Developers of Things, Everything!" The conference will cover development topics for the Object Pascal and C++ programming languages with Delphi, C++Builder, RAD Studio and Appmethod. The conference will have two live stream tracks – one for Object Pascal and one for C++.

posted @ Fri, 17 Oct 2014 16:50:00 +0000 by Tim Del Chiaro

Mac OS X Yosemite Style Pack for RAD Studio XE7

Yesterday, Apple released Mac OS X Yosemite.

We have a new Yosemite style pack available for RAD Studio XE7 users that includes both a blue and a dark style. The blue style is the default Yosemite style, and the dark style is designed for Yosemite’s dark (graphite) mode.

You can get both styles and the sample project by going to:

Here are the steps to add Yosemite styling support to your project:

1. Place TStyleBook onto the Master view
2. Set TStyleBook.Name = "YosemiteStyleBook"
3. Load Yosemite.fsf or YosemiteDark.fsf to YosemiteStyleBook
4. Use the TForm.OnCreate event and add this code:

procedure TForm1.FormCreate(Sender: TObject);
  if (TOSVersion.Major = 10) and (TOSVersion.Minor = 10) then
     Form1.StyleBook := YosemiteStyleBook;

posted @ Fri, 17 Oct 2014 19:50:26 +0000 by sarinadupont

iOS 8 App Store Hotfix


A couple of days ago we released a hotfix for submitting iOS 8 applications to the Apple App Store.

This RAD Studio hotfix enables deployment of Delphi and C++ iOS applications to the Apple App Store.

It applies to RAD Studio XE5, XE6 and XE7.

You can get the hofix by going to:



posted @ Fri, 17 Oct 2014 17:40:36 +0000 by sarinadupont

Mobile User Interface Design: Home Screen Navigation

Written by Sarina D.

When it comes to mobile UI design, there are several key design paradigms. I covered the different mobile UI design patterns in my recent C++ Mobile Day session.

App Home Screen Navigation Key Features
• Images arranged in a grid like layout
• Images can be annotated with text
• May span over multiple screens (you can use a TTabControl for that)
To create the user interface shown in the screenshot above, you will first need to create a new mobile application. Add a TToolbar, align it to the Top, and parent a TLabel to it. Next, drop a TGridPanelLayout component onto your form and align it to the client. By default, two columns (0,1) and two rows (0,1) are set up.
Note: Since you are going to set up event handlers for each graphic on the home screen, I would recommend adding a TTabControl (aligned to Client) with 11 invisible tabs (TabPosition = tpNone). Then add the Toolbar and GridPanelLayout components to Tab1, and link to each of the tabs when the user taps on one of the 10 home screen graphics by setting up on-click events for each graphic.

Define the width of each column, i.e. 50% to have even spacing across both columns.
For this sample application, we want to have a total of two columns with five rows. To add a row, right click on ‘RowCollection’ and add an item.
Each of the five rows should have a value of 20% to ensure even spacing across our grid.
Next, drop a total of 10 TImageControls onto your form. You could also use TImage if you want to load different images for different device resolutions (i.e. 1x resolution image, 2x resolution image etc.).Multi-select (shift select) all TImageControls in the Structure pane and change the width and height to 75 px. This ensures spacing between each of the graphics.
Select each TImageControl and select the row and column you want it to be displayed.

Last step is to add the images you want to display and setup on-click events for each graphic to navigate the user to the related content.

posted @ Mon, 13 Oct 2014 23:43:04 +0000 by J T

Creating a Navigation Drawer for your Mobile Application

Written by Sarina D.

Recently, I covered key menu styles that are used in mobile applications today. Drawer menus are very popular, as they allow you to take advantage of more screen real estate when building your app. The main application menu is hidden by default, and invoked by tapping on a menu item or swiping left/right. This type of UI can be seen in many popular mobile applications, including Facebook, Youtube and Gmail.

In this tutorial, I will cover the steps needed to create a navigation drawer for your Appmethod mobile apps.

Many thanks to Malcolm Groves who created the drawer sample that I am using and expanding for this blog post. You can download the project source from his Github repository.

This application consists of 2 layouts. One layout containing the drawer content, and one containing the main application content.

In this case, my left menu, the drawer menu, includes a top aligned toolbar with a parented label, and a client aligned Listbox with several menu items in it. The idea here is that the drawer menu contains all the main application navigation, including quick links to my account profile, app settings etc.

For demo purposes, I dropped a TListView component onto my form, parented it to lytMain and set its alignment property to alClient. I also placed a TPrototypeBindsource component onto my form to fill my TListview with some sample data. Right-clicking on the PrototypeBindSource component provides you with sample data that you can then easily bind into your Listview using the LiveBindings Designer. I also parented a TLine to lytMain to make the division between the main layout and navigation drawer more visible. You could also apply a style or use a separate background color.

If you double click on the Actionlist component on the form, you can see that we setup a custom action. We are leveraging that action for opening/closing the drawer when the user clicks on the drawer menu (three line) button or when they swipe across the main menu layout.

procedure TfrmMain.actOpenDrawerExecute(Sender: TObject);
  DrawerVisible := not DrawerVisible;

procedure TfrmMain.actOpenDrawerUpdate(Sender: TObject);
  actOpenDrawer.Visible := not (IsPad and IsLandscape);

On the form, we also placed the Gesture Manager component since we want the user to be able to swipe across the screen to show/hide the navigation drawer. In the project source, you will see that the touch gestures are setup for the toolbar parented to lytMain. In my demo, I removed the gesture that was setup on the toolbar and instead assigned the touch gesture to lytMain.

You can find the source code for this project in Malcolm Groves’ Github repository. Below is a quick video that shows my running application.

posted @ Mon, 13 Oct 2014 23:42:32 +0000 by J T

Pull to Refresh on iOS

Written by Sarina D.

Today, I thought I would show you a simple example of how to implement pull to refresh for TListView. This example doesn’t use a data source, but instead just adds 20 items to my list every time I try to refresh it. I am currently using one timer with this sample, but you could add another one for when the data is done loading to hide the animation at that time.

This sample uses the following 3 components:


For Timer1, I set the Interval design time property to 30. ListView1 is aligned to the client. AniIndicator1 is positioned at the top and centered on my form.


Below is the entire code of my application:

    unit PullToRefresh;


    System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
    FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
    FMX.ListView.Types, Data.Bind.GenData, Fmx.Bind.GenData, System.Rtti,
    System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.EngExt,
    Fmx.Bind.DBEngExt, FMX.StdCtrls, Data.Bind.Components, Data.Bind.ObjectScope,

    TForm36 = class(TForm)
    ListView1: TListView;
    Timer1: TTimer;
    AniIndicator1: TAniIndicator;
    procedure ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
    Y: Single);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    { Private declarations }
    Myposition : Integer;
    Updating : Boolean;
    { Public declarations }

    Form36: TForm36;


    {$R *.fmx}
    LItem: TListViewItem;
    LList : TListView;
    I: Integer;

    procedure TForm36.FormCreate(Sender: TObject);
    Timer1.Enabled := true;
    LItem := ListView1.Items.Add;
    LItem.Text := ‘Pull to refresh list & add 20 items’;

    procedure TForm36.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
    Y: Single);
    if not Updating and (ListView1.ScrollViewPos < -40) then
    Updating := true;
    AniIndicator1.Visible := True;
    AniIndicator1.Enabled := true;
    I := Myposition + 1 to Myposition +20 do
    LItem := ListView1.Items.Add;
    LItem.Text := Format(’Text %d’, [I]);
    inc(myposition, 20);

    procedure TForm36.Timer1Timer(Sender: TObject);
    if ListView1.ScrollViewPos >-40 then
    AniIndicator1.Visible := false;
    Updating := false;

posted @ Mon, 13 Oct 2014 23:41:51 +0000 by J T

Deploying and accessing local files on iOS and Android

Written by David I.

This tutorial shows you how to deploy and access files and/or folders containing files in your iOS and Android apps. To accomplish this, you create a new mobile app, a few lines of Object Pascal code, use the Project | Deployment menu item and use the System.IOUtils unit’s TPath.GetDocumentsPath method and PathDelim in your code.

The steps to create the mobile app

1) use the File->New ->Mobile Application main menu item and select the "Blank Application" project template.

2) On the form, add 1 TButton, 2 TLabel and 1 TImage components.

3) Double click on the TButton component to create the Button’s OnClick event handler.

4) Add a "uses System.IOUtils;" just below the {$R *.fmx} in the implementation section.

5) Add the following Object Pascal code in the event handler to display the documents path and to load the bitmap from the documents folder:

procedure TForm1.Button1Click(Sender: TObject);
  DocPathLabel.Text := TPath.GetDocumentsPath;
  Image1.Bitmap.LoadFromFile(TPath.GetDocumentsPath + PathDelim + 'davidi_tiedye.jpg');

6) In the Project Manager, select each of the Android and iOS Target Platforms to active each one to build an application for each one.

7) Use the Project | Deployment menu item and select the Android and the iOS Device platforms and for each one click the "Add Files" button in the local toolbar to select the bitmap file to deploy with the app and set the Remote Path column value for each platform.

  • For Android, set the Remote Path to .\assets\internal
  • For iOS, set the Remote Path to StartUp\Documents

Here are screen shots of each of the resulting Deployment settings:

8) Compile, Deploy and Run the app for Android (I used my Samsung Galaxy S4) and iOS (I used my iPhone 4s)

You can read additional information about mobile application development and deployment on the Appmethod DocWiki using the following URLs:

posted @ Mon, 13 Oct 2014 23:40:11 +0000 by J T

Server Response from: BLOGS1