Thanks for Ray Konopka, who shared excellently with CodeRage and put me on the right track to answer these questions.
Question 1. Is it possible to embed the default style in a component?
Yes, you insert the default style that you want to distribute with the component into a resource of type RT_RCDATA. Then just include this resource in the source:
{$R *.res}
Note: you need to delete the external object (TLayout) if you created it in the layout editor before placing it in res.
Then override the GetStyleObject method to load the style from the resource.
function TLFButton.GetStyleObject: TControl; var S: TResourceStream; obj: TLayout; const Style = 'LFButtonStyle'; begin result := inherited GetStyleObject; if FStyleLookup = 'cornerbuttonstyle' then begin if FindResource(HInstance, PChar(Style), RT_RCDATA) <> 0 then begin S := TResourceStream.Create(HInstance, Style, RT_RCDATA); try obj := TLayout(TStyleManager.LoadFromResource(HInstance, Style, RT_RCDATA)); //obj := TLayout( CreateObjectFromStream(nil, S) ); << XE2 version Result.AddObject(obj); Exit; finally S.Free; end; end; end; end;
Question 2: How to combine it with the default style.
In my case, the base of my component was TCornerButton. I truncated my .style file so that it just had the code for the extra bits that I wanted. In this case, a small triangle to indicate the drop-down list button and a line to separate the button:
object TLayout Align = alRight Position.Point = '(76,0)' Locked = True Width = 15.000000000000000000 Height = 24.000000000000000000 object TPath StyleName = 'dropdownbutton' Align = alCenter Position.Point = '(4,9)' Width = 8.000000000000000000 Height = 5.000000000000000000 HitTest = False Fill.Color = claBlack Stroke.Kind = bkNone Data.Path = { 04000000000000000000000000000000010000000000803F0000000001000000 0000003F0000803F030000000000000000000000} end object TLine StyleName = 'dropdownsplit' Align = alLeft Width = 1.000000000000000000 Height = 24.000000000000000000 HitTest = False LineType = ltLeft end end
And I put it in the resource in exactly the same way.
In my constructor, I set StyleLookup as the "cornerbutton style"
constructor TLFButton.Create(AOwner: TComponent); begin FStyleLookup := 'cornerbuttonstyle'; FDropDownButton := false; inherited; end;
Then I modify GetStyleObject so that it loads new material and adds it to the existing style.
function TLFButton.GetStyleObject: TControl; var S: TResourceStream; obj: TLayout; const Style = 'LFButtonStyle'; begin result := inherited GetStyleObject; if FStyleLookup = 'cornerbuttonstyle' then begin if FindRCData(HInstance, Style) then begin S := TResourceStream.Create(HInstance, Style, RT_RCDATA); try obj := TLayout( CreateObjectFromStream(nil, S) ); Result.AddObject(obj); Exit; finally S.Free; end; end; end; end;
I hope this helps someone else, and I found it all very difficult to get information.
Martin