How Do I Merge Two Existing Components Together? - delphi

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?

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.

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.

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.

Related

What is the ideal way to modify sub control styles in a custom firemonkey control?

I am attempting to develop my first proper custom control for the Firemonkey framework and have ran into what may possibly be an obvious (or not) solution.
Inside my Firemonkey control I have declared FPanel: TPanel; which is then created in the constructor and freed in the destructor. The panel is created along with my control when I add it to a new Multi-Device Form without any problems.
By default the TPanel has borders around the sides of the control which I do not need in my control.
So my question is, what is the ideal way to remove the borders of a TPanel which is child to my custom control? I could not see an obvious property to change, unless I am mistaking I believe we must modify the style of the panel which I assume would be done via a TStyleBook.
Am I right then in thinking that I need to add a TStyleBook to my control, and from there add the panel to the Style book and modify it this way? Unless I am missing something this seems like a lot of extra work for what should be a very quick and simple change.
Assuming this is the correct way, is there an example of modifying a TStyleBook through code?
Thanks.
Because all Firemonkey controls can be parents, one way is to not use TPanel at all and instead replace it with another Firemonkey control such as the TRectangle shape.
The TRectangle shape can then be customised directly through its properties to remove the border which can be achieved by setting the Corners and Sides to False.
Additionally if you don't require any borders whatsoever then the TLayout control behaves just like a TPanel but without the borders.

Delphi - TVirtualtreeview encapsulation

I need a very fast treeview able to list and scroll hundreds of thousands of items also with nesting of subitems etc. The standard Windows tree view control (wrapped with Delphi's TTreeView) is not up to the task. It's too slow.
Now I have checked TVirtualTreeView which is as fast as I need, but there is a problem, it does not work at all like the standard treeview but in a completely different way.
I am wondering if some expert using this component can tell me whether it is feasible to encapsulate it in a new component so that it will have properties and methods of a normal treeview but keeping the speed advantage?
If my question is not clear, I will try to elaborate it further.
My solutions for you is:
Add a new frame to your project
Drop a VirtualTreeView on it and align it as alClient
Add methods and properties in order to make the frame to mimic the TTreeView interface
Implement those methods and properties to deal with the internal TVirtualTreeView
Implement TVirtualTreeView events to mimic the TListView behavior
Replace your current TTreeView by the new frame
I guess this will get you close to what you want, balancing complexity and functionality.

Making an editable designtime component for Delphi

I've been searching the whole internet for an answer but I cant find one.
What I want to do is to create a component that I, in design time, can add components to, move them around, right click on them to pop up a menu, change their properties, etc etc.
Like, for instance, I drop my component "A" (which is based on TImage32 from the Graphics32 library), and then I want to be able to drop a component "B" (which is based on TBitmap32) in to A, but since B is not inherited from a standard VCL like TPanel I dont know how to make a design time component.
What you are searching for is the ability to create a parent/child relationship. The parent acts as a container and the child is contained within the bounds of the container. A TPanel is a classic example of a container. Any visual component can be a child.
In terms of ancestry the parent must be derived from TWinControl and the child must be derived from TControl. In practice you seldom derive from these classes directly, rather from one of their descendents. The other factor, if I recall correctly, is that the parent control must include csAcceptsControls in its ControlStyle.
Now, TImage32 does indeed derive from TWinControl and so it can act as a container. However, I am not sure whether or not csAcceptsControls is included in the ControlStyle for TImage32.
I'm really not familiar with TImage32 and don't know whether or not it can act as a parent. I have a suspicion that it is not designed to act as a container. If that is the case then you can add csAcceptsControls to the ControlStyle in the constructor of your derived class and have the control act as a parent.
I suspect that if TImage32 does not include csAcceptsControls then this is by design and the image control is not expected to act as a parent.
Apparently TImage32, unlike the VCL TImage, is indeed capable of acting as a parent to other controls.
As for the other control in your question, TBitmap32 is not derived from TControl and cannot be a child control.

Firemonkey: Styling the tGrid or alternative Grid/List components (Virtual)

I'm trying to create my first app based on FireMonkey, and I hit a wall.
The only virtual list control I can find is tGrid.
This component is pretty good, but I can not figure out how to extend or customize it.
I get that there is tCheckbox column, tImage column etc, but what if I need a ButtonColumn or something like this?
Also I would like to style a row, based on the state of the data it represents.
An Example: if the data that is represented in the row has "Error=True" it should be displayed in red.
Has anyone got a similar problem? Or found alternate virtual list/grid components? Or even just some tips on use of the tGrid component.
These components are pretty essential in all database apps so it should be a pretty common request.
Also just as a note, I don't think the TGrid supports Drag & Drop of rows?
I have looked at
Firemonkey version of VirtualTreeView
and
Firemonkey and large amounts of data
If you look at the sources, TCheckColumn is only 15 code lines. If you need to create your own column descendant class it's quite straightforward.
This is one solution, otherwise you can dynamically create some components in your cells and then cast the children when checking the props (TColumn.CellControlByRow() return a TControl and the children would be what you have put in there).
As you want to 'style' your row I would suggest you to write your own TColumn class, even if you can do painting in the OnPaint Event.

Delphi control that could mimic "Add-ons|Extension list" of Firefox?

My aim is to update the look of the GUI in my app. Currently my GUI contains a lot of listboxes which are used to edit some objects in an old fashioned way, that is, user double-clicks an item and a dialog is shown to modify the corresponding object.
I think a good modern approach is how Firefox displays the extensions installed (a snapshot below).
My question is about how to build such a GUI in Delphi(win32) easily? Are there any components you use mimicing such behaviour or will I just need to code this from stratch using panels? (IMO a very cumbersome job I'd like to avoid - the selection logic, resizings, etc...)
You can do something similar (not exactly) with standard components; TDBCtrlGrid, TSpeedButton,...
alt text http://img8.imageshack.us/img8/9585/imagen29ox3.png
If you're using Delphi 2007 or Delphi 2009, you might be able to do something similar using TCategoryButtons (from the 'Additional' component palette page). Drop it on a form and right click to display the popup menu, and then click "Categories Editor...". Add a category with the resulting dialog, set it's caption, and optionally set up Items it contains. Not exactly the same, but it might do what you need.
You could also use a dialog with a TTreeView (if you have categories of objects) or TListView to emulate the Delphi 2007 Projects->Options dialog. Clicking an item in the TreeView or ListView displays the proper page of a TPageControl to configure the object.
I mostly agree with Lars, but I would use a frame for each item instead of a panel. That would separate into its own file, and you would get easy designtime support for it.
Using a TFrame for each list item and put them all Aligned Top on a TScrollBox might work. Also see TDBCtrlGrid which does something like that in combination with datasets.
It can be done with existing Delphi controls.
For instance in the TCustomListBox control you can create your own OnDrawItem event to draw your own list item. You also need to create your own OnMeasureItem to change the item height.
In some cases it is very limited, so if you want more freedom you will need to do it from scratch.

Resources