Having access to a robust component framework that provides start-of-the-art components, classes and interfaces that do the work for you, greatly improves your ability to build applications for a wider arrange of systems. C++Builder XE4 allows you to query for services, devices and sensors to know what your application can use. FM, the component framework from Embarcadero Technologies, provides everything a C++ developer needs to query devices, count the number of sensors, and know which services are available for application use. FM itself uses the same sensor, device and platform services to know how to initialize itself on each of the target platforms. What sensors, device and services are supported for C++ application development? Let's take a look at each of the three in more detail.
Sensors
FM's support for sensors is organized into sensor categories:
- Location
- Environmental
- Motion
- Orientation
- Mechanical
- Electrical
- Biometric
- Light
- Scanner
The sensor category definition in System.Sensors.hpp is:
TSensorCategory : unsigned char { Location, Environmental, Motion, Orientation, Mechanical, Electrical, Biometric, Light, Scanner }
For each sensor category there are many possible sensor types including:
- TLocationSensorType : unsigned char { GPS, Static, Lookup, Triangulation, Broadcast, DeadReckoning, Other };
- TEnvironmentalSensorType : unsigned char { Temperature, AtmosphericPressure, Humidity, WindSpeed, WindDirection };
- TMotionSensorType : unsigned char { Accelerometer1D, Accelerometer2D, Accelerometer3D, MotionDetector, Gyrometer1D, Gyrometer2D, Gyrometer3D, Speedometer };
- TOrientationSensorType : unsigned char { Compass1D, Compass2D, Compass3D, Inclinometer1D, Inclinometer2D, Inclinometer3D, Distance1D, Distance2D, Distance3D };
- TElectricalSensorType : unsigned char { Voltage, Current, Capacitance, Resistance, Inductance, ElectricalPower, Potentiometer };
- TMechanicalSensorType : unsigned char { BooleanSwitch, BooleanSwitchArray, MultiValueSwitch, Force, Scale, Pressure, Strain };
- TBiometricSensorType : unsigned char { HumanPresence, HumanProximity, Touch };
- TLightSensorType : unsigned char { AmbientLight };
- TScannerSensorType : unsigned char { RFID, Barcode };
In your C++ code you can get a count of the identified sensors, sensor name, sensor category and type, sensor state and more.
// get list of found sensors - if any
TSensorManager::Current->Active = true;
int NumberOfSensors = TSensorManager::Current->Count;
Label2->Text = "Sensors: "+IntToStr(NumberOfSensors);
Memo2->Lines->Clear();
for (int i = 0; i < NumberOfSensors;i++) {
Memo2->Lines->Add(IntToStr(i)+ ": "
+ TSensorManager::Current->Sensors[i]->Name
+ ". Category: "
+ System::Typinfo::GetEnumName(
__delphirtti(TSensorCategory),TSensorManager::Current->Sensors[i]->Category)
+ ". State: "
+ System::Typinfo::GetEnumName(__delphirtti(TSensorState),
TSensorManager::Current->Sensors[i]->State)
);
}
TSensorManager::Current->Active = false;
Once you know which sensors are available in your application you can chose to use the FM components and classes directly in your applications. You can also query to ensure that a specific sensor is available for your application to use. When you build your applications for Windows and Mac in C++Builder XE4 you'll have easy access to all of the sensors available on each of your target systems.
Devices
How many cameras do your PCs, Smartphones and Tablets have? How many audio inputs does you application have access to? You use use FM's support for device managers to be able to use them in your applications. Each FM based application includes a default device manager. The Device Manager interfaces will give you the device name, media type of the device (audio/video), the device state and other information about specific devices. You can query and filter for specific device media types or iterate through the collection of devices to find the ones your application is looking for.
TMediaType : unsigned char { Audio, Video };
TCaptureDeviceState : unsigned char { Capturing, Stopped };
TDevicePosition : unsigned char { dpUnspecified, dpFront, dpBack };
TFlashMode : unsigned char { fmAutoFlash, fmFlashOff, fmFlashOn };
TFocusMode : unsigned char { fmAutoFocus, fmContinuousAutoFocus, fmLocked };
TTorchMode : unsigned char { tmModeOff, tmModeOn, tmModeAuto };
TVideoCaptureQuality : unsigned char { vcPhotoQuality, vcHighQuality, vcMediumQuality, vcLowQuality };
The following C++ code snippet lists the audio and video capture devices available to your application.
// get list of found devices - if any
int NumberOfDevices = TCaptureDeviceManager::Current->Count;
Label1->Text = "Devices: "+IntToStr(NumberOfDevices);
Memo1->Lines->Clear();
for (int i = 0; i < NumberOfDevices; i++) {
Memo1->Lines->Add(IntToStr(i)+ ": "
+ TCaptureDeviceManager::Current->Devices[i]->Name
+ ". MediaType: "
+ System::Typinfo::GetEnumName(
__delphirtti(TMediaType),
TCaptureDeviceManager::Current->Devices[i]->MediaType)
+ ". State: "
+ System::Typinfo::GetEnumName(
__delphirtti(TCaptureDeviceState),
TCaptureDeviceManager::Current->Devices[i]->State)
);
}
The following C++ code snippet shows you how to support a system with one or two video cameras (like my Samsung Slate Series 7).
// get count of number of video cameras devices - if any
int NumberOfDevices = TCaptureDeviceManager::Current->Count;
int NumberOfVideoDevices = 0;
for (int i = 0; i Devices[i]->MediaType == TMediaType::Video) {
NumberOfVideoDevices++;
}
CameraCountLabel->Text = "Cameras: "+IntToStr(NumberOfVideoDevices);
if (NumberOfVideoDevices > 0) {
VideoCamera1 = dynamic_cast(TCaptureDeviceManager::Current->GetDevicesByMediaType(TMediaType::Video)->Items[0]);
if (VideoCamera1 != NULL) {
VideoCamera1->OnSampleBufferReady = Camera1SampleBufferReady;
}
}
if (NumberOfVideoDevices > 1) {
VideoCamera2 = dynamic_cast(TCaptureDeviceManager::Current->GetDevicesByMediaType(TMediaType::Video)->Items[1]);
if (VideoCamera2 != NULL) {
VideoCamera2->OnSampleBufferReady = Camera2SampleBufferReady;
}
}
Platform Services
Each target platform comes with its support for different application and user interface paradigms. These platform services can include, but are not limited to, the following types of services:
- Application Service
- Dialog Service
- Canvas Service
- Context Service
- Locale Service
- Clipboard Service
- Cursor Service
- Device Service
- Drag and Drop Service
- Hide App Service
- Mouse Service
- Screen Service
- Style Service
- Style HiRes Service
- System Font Service
- Text Service
- Virtual Keyboard Service
- Menu Service
- Window Service
- Window Border Service
- Timer Service
In your C++ applications you can query whether a service is available on a target platform. If the service is available, use the native platform service or provide your own or a third party alternative. For Windows and Mac development it is safe to assume that there is a mouse, menu, dialog and clipboard. As your C++ applications move beyond the desktop, you may not have a dialog or menu service, but you can probably assume that there will be a virtual keyboard service.
Using the SupportsPlatformService method will return true or false if the service is available to your application. The second method will return the service so that you can use it in your code.
bool __fastcall SupportsPlatformService(const GUID &AServiceGUID);
bool __fastcall SupportsPlatformService(const GUID &AServiceGUID, System::_di_IInterface &AService);
Here is a FM based C++ code snippet that lets you test to see if there is a virtual keyboard service available to your application and uses it:
_di_IFMXVirtualKeyboardService KBDService;
// if the platform supports the virtual keyboard
if ((TPlatformServices::Current->SupportsPlatformService(
__uuidof(IFMXVirtualKeyboardService)) &&
(KBDService = TPlatformServices::Current->GetPlatformService(
__uuidof(IFMXVirtualKeyboardService))))) {
// Show the virtual keyboard
KBDService->ShowVirtualKeyboard(Form4);
}
else {
Edit1->Text = "No Virtual Keyboard Service Found!";
}
Using Devices, Sensors and Platform Services in your Applications
I've written blog posts and created videos that show C++ developers how to work with sensors, devices and platform services. Take a look at the following links for additional information.
- 31 C++ videos in January 2013 – http://www.embarcadero.com/products/cbuilder/how-to-create-software-applications
- Working with C++ Devices and Sensors – http://blogs.embarcadero.com/davidi/2013/01/04/42299
- Using Platform Services and OS info in your C++ Windows and Mac apps – http://blogs.embarcadero.com/davidi/2013/01/16/42349
- Playing HD Video and Capturing Video bitmaps on Windows and Mac using C++ – http://blogs.embarcadero.com/davidi/2013/01/09/42329
- Playing and Capturing Audio on Windows and Mac using C++ – http://blogs.embarcadero.com/davidi/2013/01/15/42339
- Capturing bitmaps from two video cameras on Windows and Mac using C++ –http://blogs.embarcadero.com/davidi/2013/01/15/42344
- Using the Motion and Location Sensor components with C++ – http://blogs.embarcadero.com/davidi/2013/01/16/42353
- Platform Abstraction – http://docwiki.embarcadero.com/Libraries/XE3/en/FMX.Platform
- TOSVersion Platform – http://docwiki.embarcadero.com/Libraries/XE3/en/System.SysUtils.TOSVersion.TPlatform
As C++ developers move beyond the desktop, the same component framework will take you and your code to new platforms, devices, embedded applications and beyond.