1

I have always written non-visual components; their creation is pretty easy and they work equally well under VCL and FMX. So far so good, but now I'm facing a problem.

I used to inherit from TComponent but now I cannot anymore because my component called TRedistPreview really needs a procedure like this:

procedure drawPreview(area: TCanvas);

This procedure has to draw something (shapes, lines and colours) somewhere, for example in a TRectangle. I have seen online that TComponent doesn't have the ability to draw, so I should inherit from something else. I have found TWinControl (but that is VCL-only) and TCustomControl (VCL only, too).

Could you please tell me what I should inherit from to get a canvas? I mean, I want to replace:

TRedistPreview = class(TComponent)
end;

With:

TRedistPreview = class(TSomeClassThatHasCanvas)
end;

Where I can call procedure drawPreview(area: TCanvas); and draw on a surface (like a TRectangle).

I am looking for the lowest possible class in the hierarchy with a Canvas.


Since this component is very useful to me under Windows and Android, I am looking for a Firemonkey implementation. From my research, I have seen that I could inherit from TRectangle, which is inside FMX.Objects, but I don't know if this is the right choice.

What should I do?

Also, if I needed this component to be in VCL, do I have to write another component that inherits from another class?

As I've said, this is my first time with visual component writing, so I'd like someone to show me the right way!

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Emma Rossignoli
  • 935
  • 7
  • 25
  • Absolutely fine to drive from TComponent. No reason at all that you can't implement a method to draw your component on a canvas. Of course, that design might be wrong. Maybe you need a visual control. Perhaps you are asking for the wrong thing. – David Heffernan Sep 25 '17 at 16:23
  • 1
    Yes, VCL and FMX are not in any way compatible with each other - not in the sense of writing a single control which works on both. It's essentially like trying to install a diesel engine from a semi truck into mini cooper. – Jerry Dodge Sep 25 '17 at 16:24
  • As a jump start, you can take a look at something pre-written, such as my code in this question: https://stackoverflow.com/questions/31767346/capturing-signature-very-sketchy-on-touch-screen Study it and implement your own thing. – Jerry Dodge Sep 26 '17 at 00:36
  • Actually, that control of mine inherited from a `TShape`. – Jerry Dodge Sep 26 '17 at 00:45

1 Answers1

2

In VCL the first class that supports canvas is TCustomcontrol which is descendant from TWinControl. http://docwiki.embarcadero.com/Libraries/Seattle/en/Vcl.Controls.TCustomControl

In FMX the base class that does allow painting routines is TControl.

But bare in mind that rendering of visual components in FireMonkey is a lot different than in VCL. So if you think about reusing VCL code in FMX or vice versa I'm afraid it probably won't be possible.

SilverWarior
  • 7,372
  • 2
  • 16
  • 22
  • This didn't work actually! I have added TControl as father class instead of TComponent but I still cannot access the TCanvas using the procedure you can see above... If inherited from TControl and then I added FMX.Graphics (which has TCanvas) would it be enough? – Emma Rossignoli Sep 25 '17 at 19:40
  • You don't need to derive from any class in particular to implement a function that accepts a canvas as an argument. – David Heffernan Sep 25 '17 at 21:26
  • @DavidHeffernan I just got it. I have decided to derive from TComponent as usual and then add in the uses clauses what I need, for example FMX.Graphics (for TCanvas). It is working so far, I guess I've understood what to do! – Emma Rossignoli Sep 25 '17 at 21:35
  • 1
    What you would have then is a non visual component that can draw itself to a canvas on demand. Whether or not that is useful I cannot tell. – David Heffernan Sep 25 '17 at 21:36
  • @Emma What David is saying is that you *could* create a `TComponent` with code which draws to a canvas. But it highly depends on what you're actually trying to do. Such a component is not very common. What you *might* be actually looking for is creating a *custom control* which draws by itself in the UI on its own visual canvas. In such a case, you cannot do so simply from a `TComponent` decendent - you will need to inherit a `TControl` at minimum. – Jerry Dodge Sep 26 '17 at 00:35