0

How can I merge two VCL components together so I can access both of their properties?

For example, I want to merge a TImage and a TPanel into one, I require that the TPanel is the base component, so the TImage will be child to the TPanel.

Is it possible to do this?

I've been trying to do this in Delphi 2010 via Component > New VCL Component but it creates non-visual components when I require a visual component.

What can I do to change this?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
ple103
  • 2,080
  • 6
  • 35
  • 50
  • 1
    well, that's because you need to first write the code, and if everything turns out OK, then you need to register the component inside the IDE. In order to access both properties, you need to define "proxy" properties for both components, i.e. setters and getters –  May 20 '12 at 12:54
  • 1
    Are you trying to do this with a class that derives from TComponent? Because that would be why it's "Non visual". TComponent is the base class for Non-Visual components. – Warren P May 20 '12 at 12:57

3 Answers3

5

If I understand correctly I think you want to merge two components together and expose the properties for both?

If this is what you are looking for, I asked a similar question for joining a TImage and TScrollBox together which can be found here:

Component Creation - Joining Components Together?

SetSubComponent was the key to achieving this, it may be worth while reading the comments and answers from the link above to understand more.

Community
  • 1
  • 1
3

The Delphi language does not support multiple inheritance of implementation, only multiple inheritance of interface. Thus you cannot simply merge together two classes in the way you hope.

What you are proposing sounds a bit odd anyway. Both TPanel and TImage have their own visual surfaces. The only plausible thing I can imagine is that you could make the TImage a child of the TPanel. Derive a new component from TPanel. That component would create and own a TImage. Make the parent of the TImage sub control be the panel. Any properties and events of the TImage control that you want to surface in your control would have to be done manually. This is composition rather than inheritance.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    In other words, you could inherit from a TPanel, and that TPanel can contain a TImage. But that is not "MERGED", it is "COMBINED". Composite controls are not very difficult. Once your TPanel-that-contains a TImage is installed as a designtime package, it could be dropped onto your form as a single item. But how useful is that? Not very. – Warren P May 20 '12 at 12:56
  • I can understand why you say that its not very useful, but what I'm trying to do is reduce coding. I am adding visual features that rely on `OnMouseEnter`. If the user hovers the mouse over the `TPanel` its bevel will change but if the mouse cursor moves into the `TImage` (which is a child of the `TPanel`) the bevel is removed. Which would mean that I would have to add code for both the `TPanel` and the `TImage` for the "visual feature" to work. – ple103 May 20 '12 at 13:01
  • 1
    @petersmileyface: that suggests that you only need a specific TImage descendant which wouldn't "mess" with the borders of the panel by not taking "charge of the mouse". Sort of make the image transparent for mouse actions and have everything handled by the panel (if the image sits on one). No idea how to accomplish this though, but I am sure Warren, LU RD or one of the other VCL adepts here would be able to help you on that. – Marjan Venema May 20 '12 at 13:14
1

You might use a TFrame to create a component that exists of other visual components at design time, e.g. a TPanel with a TImage upon it. This is probably not exactly what you want: the properties are not 'merged' together, you must design your own properties and methods to make this newly created component behave as you want it to. The functionality you desire (changing visual features depending on the spot of the mouse) needs to be built only once into the frame.

Arnold
  • 4,578
  • 6
  • 52
  • 91