Changing a FireMonkey style at runtime

by Jul 13, 2017

There is a great post by Sarina Adding a style selector to your application showing how to have a FMX application with multiple style books, and a combo box listing the styles.  When the app is running, a user can select one of the style in the combo box and the FireMonkey app will change style dynamically.

However, the code sample is in Delphi, not C++.  How do you do this in a cross-platform C++ app?  It turns out to be pretty simple – let's have a look.

Following the original blog post, create a FMX app with some controls and two TStyleBooks, each of which have a different style loaded.

Add a combo box called StyleBox, and add the following two methods:

.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	EnumObjects([this](TFmxObject* Obj) -> TEnumProcResult {
		TStyleBook* pBook(dynamic_cast<TStyleBook*>(Obj));
		if (pBook) {
			int Index = this->StyleBox->Items->Add(pBook->Name);
			StyleBox->ListItems[Index]->Data = Obj;
		}
		return TEnumProcResult::Continue;
	});
}

void __fastcall TForm1::StyleBoxChange(TObject *Sender)
{
	if (StyleBox->ItemIndex >= 0) {
		StyleBook = (TStyleBook*)(StyleBox->ListItems[StyleBox->ItemIndex]->Data);
	}
}

 

The first scans for TStyleBook objects in the form, and adds each as an associated pointer data to an combo box item representing it.  The second is an event handler when a combo item is chosen, and sets the style.

Lambdas translating to anonymous methods

 

The first method is really interesting, because it's a method taking a Delphi anonymous procedure.  If you find the declaration, in FMX.Types.hpp, you'll see something a bit odd looking:

.
void __fastcall EnumObjects(const System::DelphiInterface<System::Sysutils::TFunc__2<TFmxObject*,TEnumProcResult> > Proc);

What's that?  Well, it's the translation of a Delphi anonymous method, and if you see that in code completion you might wonder what on earth you have to write.

The answer: just a functor or lambda.  It will be automatically translated to the anonymous method!  For more information, see:

You should use the Clang compiler.  This magic is just one of the things we do to make using two languages seamless and easy – best of both worlds!

(Next up: improving the actual header translation and code completion.)

Changing styles at runtime

Here's what the final app looks like:

  

And of course this works on all platforms – Windows, macOS, iOS, and Android.  Happy coding!