FireMonkey Platform Services

From Appmethod Topics
Jump to: navigation, search

Go Up to FireMonkey Applications Guide


FireMonkey XE4 introduces a feature called Platform Services that is useful for returning whether the platform that will run your application truly supports a given service.

Introduction

The Platform Services feature is a registry of platform services, implemented by the TPlatformServices class in the FMX.Platform unit.

The TPlatformServices class allows individual services to be added and/or removed from the registry, via methods like AddPlatformService and RemovePlatformService, respectively.

Another useful method called SupportsPlatformService provides a way for you to query the platform services registry in order to determine whether a particular service is supported at run time. After verifying a service is supported, then use GetPlatformService to get the service and cast it appropriately.

These methods are designed to be similar to the Object Pascal RTL (run-time library) System.SysUtils.Supports function for working with Object Pascal interfaces.

A platform service is an interface that defines some functionality that might or might not be implemented on a particular run-time platform. The most important service is defined by the IFMXApplicationService interface, which defines the basic operations expected of an Application object.

Services List

The available services are listed below.

  1. IFMXAdvertisingService
  2. IFMXApplicationService
  3. IFMXCanvasService
  4. IFMXClipboardService
  5. IFMXContextService
  6. IFMXCursorService
  7. IFMXDefaultMetricsService
  8. IFMXDefaultPropertyValueService
  9. IFMXDeviceService
  10. IFMXDialogService
  11. IFMXDragDropService
  12. IFMXHideAppService
  13. IFMXImageGeneratorService
  14. IFMXInAppPurchaseService
  15. IFMXLocaleService
  16. IFMXLoggingService
  17. IFMXMouseService
  18. IFMXPickerService
  19. IFMXScreenService
  20. IFMXStyleService
  21. IFMXSystemFontService
  22. IFMXSystemInformationService
  23. IFMXTextService

Tip: Before you try to use a service, you should verify whether the service is supported on the run-time platform, using code that tests for availability of the onscreen keyboard service, such as the following code snippet.

In Object Pascal:

var
  clp: IFMXClipboardService;
begin
  if TPlatformServices.Current.SupportsPlatformService(IFMXClipboardService) then
  begin
    clp := IFMXClipboardService(TPlatformServices.Current.GetPlatformService(IFMXClipboardService));
    ShowMessage(clp.GetClipboard.AsString);
  end;
end;

In C++:

  if (TPlatformServices::Current->SupportsPlatformService(IFMXVirtualKeyboardService) {
		// do something
	}

You can also unregister a service that FireMonkey already implements, and replace it with a new implementation of the service that is tailored to fit the needs of a specialized application environment.

Usage Example

A typical use case of the TPlatformServices class for gathering information about supported services, is shown in the code block below that illustrates how to get all the available services on the run-time platform.

In Object Pascal:

type
  TPlatformServicesRecord = record
    Service: String;
    Name: String;
  end;

const
  MaxServices = 21;
  PlatformServicesArray: array[0..MaxServices-1] of TPlatformServicesRecord =
  (
    (Service: 'FMX.Platform.IFMXApplicationService'; Name: 'Application Service'),
    (Service: 'FMX.Forms.IFMXWindowService'; Name: 'Window Service'),
    (Service: 'FMX.Forms.IFMXWindowBorderService'; Name: 'Window Border Service'),
    (Service: 'FMX.Types.IFMXTimerService'; Name: 'Timer Service'),
    (Service: 'FMX.Platform.IFMXDialogService'; Name: 'Dialog Service'),
    (Service: 'FMX.Platform.IFMXCanvasService'; Name: 'Canvas Service'),
    (Service: 'FMX.Platform.IFMXContextService'; Name: 'Context Service'),
    (Service: 'FMX.Menus.IFMXMenuService'; Name: 'Menu Service'),
    (Service: 'FMX.Platform.IFMXLocaleService'; Name: 'Locale Service'),
    (Service: 'FMX.Platform.IFMXClipboardService'; Name: 'Clipboard Service'),
    (Service: 'FMX.Types.IFMXCursorService'; Name: 'Cursor Service'),
    (Service: 'FMX.Platform.IFMXDeviceService'; Name: 'Device Service'),
    (Service: 'FMX.Platform.IFMXDragDropService'; Name: 'Drag&Drop Service'),
    (Service: 'FMX.Platform.IFMXHideAppService'; Name: 'Hide App Service'),
    (Service: 'FMX.Types.IFMXMouseService'; Name: 'Mouse Service'),
    (Service: 'FMX.Pickers.IFMXPickerService'; Name: 'Picker Service'),
    (Service: 'FMX.Platform.IFMXScreenService'; Name: 'Screen Service'),
    (Service: 'FMX.Platform.IFMXStyleService'; Name: 'Style Service'),
    (Service: 'FMX.Platform.IFMXSystemFontsService'; Name: 'System Fonts Service'),
    (Service: 'FMX.Platform.IFMXTextService'; Name: 'Text Service'),
    (Service: 'FMX.Platform.IFMXVirtualKeyboardService'; Name: 'Virtual Keyboard Service')
  );


procedure TForm27.Button1Click(Sender: TObject);
const
  LFormatString: String = '[%s] %s (Name: %s)';
  ServiceAvailable: array[Boolean] of String = ('Not Available', 'Available');

var
  LService: TPlatformServicesRecord;
  LRttiContext: TRttiContext;
  LRttiType: TRttiType;

begin
  LRttiContext := TRttiContext.Create;
  for LService in PlatformServicesArray do
  begin
    LRttiType := LRttiContext.FindType(LService.Service);
    if Assigned(LRttiType) then
      Memo1.Lines.Add(Format(LFormatString,
       [ServiceAvailable[TPlatformServices.Current.SupportsPlatformService(TRttiInterfaceType(LRttiType).GUID)],
        LService.Service, LService.Name]))
    else
      Memo1.Lines.Add(Format(LFormatString,
       [ServiceAvailable[False], LService.Service, LService.Name]));
  end;
  LRttiContext.Free;
  LRttiType.Free;
end;

In C++:

//header file
struct TPlatformServicesRecord {
	String Service;
	String Name;
};

//source file
const int MaxServices = 21;

struct TPlatformServicesRecord PlatformServicesArray[MaxServices] = { {
		"FMX.Platform.IFMXApplicationService", "Application Service"
	}, {
		"FMX.Forms.IFMXWindowService", "Window Service"
	}, {
		"FMX.Forms.IFMXWindowBorderService", "Window Border Service"
	}, {
		"FMX.Types.IFMXTimerService", "Timer Service"
	}, {
		"FMX.Platform.IFMXDialogService", "Dialog Service"
	}, {
		"FMX.Platform.IFMXCanvasService", "Canvas Service"
	}, {
		"FMX.Platform.IFMXContextService", "Context Service"
	}, {
		"FMX.Menus.IFMXMenuService", "Menu Service"
	}, {
		"FMX.Platform.IFMXLocaleService", "Locale Service"
	}, {
		"FMX.Platform.IFMXClipboardService", "Clipboard Service"
	}, {
		"FMX.Types.IFMXCursorService", "Cursor Service"
	}, {
		"FMX.Platform.IFMXDeviceService", "Device Service"
	}, {
		"FMX.Platform.IFMXDragDropService", "Drag&Drop Service"
	}, {
		"FMX.Platform.IFMXHideAppService", "Hide App Service"
	}, {
		"FMX.Types.IFMXMouseService", "Mouse Service"
	}, {
		"FMX.Pickers.IFMXPickerService", "Picker Service"
	}, {
		"FMX.Platform.IFMXScreenService", "Screen Service"
	}, {
		"FMX.Platform.IFMXStyleService", "Style Service"
	}, {
		"FMX.Platform.IFMXSystemFontService", "System Fonts Service"
	}, {
		"FMX.Platform.IFMXTextService", "Text Service"
	}, {
		"FMX.Platform.IFMXVirtualKeyboardService", "Virtual Keyboard Service"
	}

};

// ---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent * Owner) : TForm(Owner) {
}

// ---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject * Sender) {
	int i;
	TVarRec args[3];
	String LFormatString = "[%s] %s (Name : %s)";
	String ServiceAvailable[2] = {"Not Available", "Available"};
	TPlatformServicesRecord LService;

	TRttiContext LRttiContext = TRttiContext::Create();
	TRttiType *LRttiType;
	for (i = 0; i < MaxServices - 1; i++) {
		LService = PlatformServicesArray[i];
		LRttiType = LRttiContext.FindType(LService.Service);
		if (TPlatformServices::Current->SupportsPlatformService
			(dynamic_cast<TRttiInterfaceType*>(LRttiType)->GUID)) {
			args[0] = ServiceAvailable[1];
		}
		else {
			args[0] = ServiceAvailable[0];
		}
		args[1] = LService.Service;
		args[2] = LService.Name;
		Memo1->Lines->Add(Format(LFormatString, args, 2));
	}
}

An example output of this code snippet might be:

[Available] FMX.Platform.IFMXApplicationService (Name: Application Service)
[Available] FMX.Forms.IFMXWindowService (Name: Window Service)
[Available] FMX.Forms.IFMXWindowBorderService (Name: Window Border Service)
[Available] FMX.Types.IFMXTimerService (Name: Timer Service)
[Available] FMX.Platform.IFMXDialogService (Name: Dialog Service)
[Available] FMX.Platform.IFMXCanvasService (Name: Canvas Service)
[Available] FMX.Platform.IFMXContextService (Name: Context Service)
[Available] FMX.Menus.IFMXMenuService (Name: Menu Service)
[Available] FMX.Platform.IFMXLocaleService (Name: Locale Service)
[Available] FMX.Platform.IFMXClipboardService (Name: Clipboard Service)
[Available] FMX.Types.IFMXCursorService (Name: Cursor Service)
[Not Available] FMX.Platform.IFMXDeviceService (Name: Device Service)
[Available] FMX.Platform.IFMXDragDropService (Name: Drag&Drop Service)
[Not Available] FMX.Platform.IFMXHideAppService (Name: Hide App Service)
[Available] FMX.Types.IFMXMouseService (Name: Mouse Service)
[Available] FMX.Pickers.IFMXPickerService (Name: Picker Service)
[Available] FMX.Platform.IFMXScreenService (Name: Screen Service)
[Available] FMX.Platform.IFMXStyleService (Name: Style Service)
[Not Available] FMX.Platform.IFMXSystemFontsService (Name: System Fonts Service)
[Available] FMX.Platform.IFMXTextService (Name: Text Service)
[Not Available] FMX.Platform.IFMXVirtualKeyboardService (Name: Virtual Keyboard Service)

See Also