The following are a series of notes regarding owner drawn elements in the new RAD Studio 10.2.2 with theming enabled (more specifically, the Dark theme).

Do NOT use Themes.StyleServices to get theme styling information, instead get the IDE’s instance of it’s theming service through the IOTAIDEThemingServices interface as shown below (I’m not sure why the IDE doesn’t use the global Themes.StylesServices interface but don’t try and change it else horrible things will happen).

Var ITS : IOTAIDEThemingServices ; Begin ... FStyleServices := Nil ; If Supports ( BorlandIDEServices , IOTAIDEThemingServices , ITS ) Then If ITS . IDEThemingEnabled Then FStyleServices := ITS . StyleServices ; ... End ;

FStyleServices in the above is a private class field. You may want to put the above in your frame’s / form’s constructor but you may need to refresh this if a theme changes later on. For IDE Option frames this is okay as the theme will not change during the display process but for dockable forms and frames you will need to handle this differently (see further down).

So the way I’m handling the style services is as follows:

If Assigned ( FStyleServices ) And FStyleServices . Enabled Then Begin ... End ;

The next part is to get the correct colours for the rendering as follows:

Begin TargetCanvas . Font . Style := [ ] ; TargetCanvas . Font . Color := clWindowText ; {$IFDEF DXE102} If Assigned ( FStyleServices ) And FStyleServices . Enabled Then TargetCanvas . Font . Color := FStyleServices . GetSystemColor ( clWindowText ) ; {$ENDIF} Case TBADIMetricColumns ( Column ) Of mcLength .. mcToxicity : TargetCanvas . Font . Color := clBlack ; End ; NodeData := FVSTMetrics . GetNodeData ( Node ) ; If Not ( NodeData . FNodeType In [ ntMethod ] ) Then Begin If Column = 0 Then TargetCanvas . Font . Style := [ fsBold ] ; End ; ... End ;

The above presets the canvas colour I need using standard Windows System colours (for non-themed earlier IDEs) and then inside an IFDEF , as this is only available in RAD Studio 10.2, I ask the style services for the alternate system colour and set it.

Depending upon the amount of owner drawing you are doing you may wish to cache the colours and only change them on a theme change.

Talking about theme changes, if you want to dynamically handle changes then you will probably need to install a style services notifier. This is a simple notifier with two methods that are fired before a theme change and after. I’ve defined mine as follows:

TBADIStyleServicesNotifier = Class ( TInterfacedObject , IOTANotifier , INTAIDEThemingServicesNotifier ) Strict Private FUpdateProc : TUpdateProc ; Strict Protected Procedure AfterSave ; Procedure BeforeSave ; Procedure Destroyed ; Procedure Modified ; Procedure ChangedTheme ; Procedure ChangingTheme ; Public Constructor Create ( Const UpdateProc : TUpdateProc ) ; End ;

The constructor takes a simple method reference which is called when a theme is changed and its there you need to updated anything you are caching including a new reference to the current style service from the IDE.

To install the notifier use the following code:

Begin Inherited Create ( AOwner ) ; ... ; {$IFDEF DXE102} FStyleServicesNotifier := - 1 ; If Supports ( BorlandIDEServices , IOTAIDEThemingServices , ITS ) Then FStyleServicesNotifier := ITS . AddNotifier ( TBADIStyleServicesNotifier . Create ( UpdateTreeViewColours ) ) ; {$ENDIF} ... End ;

And to remove it use the following:

Begin ... {$IFDEF DXE102} If Supports ( BorlandIDEServices , IOTAIDEThemingServices , ITS ) Then ITS . RemoveNotifier ( FStyleServicesNotifier ) ; {$ENDIF} ... Inherited Destroy ; End ;

Hope this short article helps get people up and running with Open Tools API solutions in the new Themed IDE.

Regards

Dave.