How do I write a TDBCtrlGrid VCL Style custom class? - delphi

There are lots of questions here about XE2 VCL Styles and custom colors for Buttons, Panels, edits, etc, and VCL Styles. As much as I wish the existing questions covered it, they don't... So DB Control Grids appear to be Yet Another Special Case.
In the DB Control Grid VCL sources, it registers a style hook thusly: TCustomStyleEngine.RegisterStyleHook( TDBCtrlGrid, TScrollingStyleHook);
However, that's not what you would descend from if you want to write your own DB Control Grid VCL style hook. If you do, you get the whole control painted like a very large scrollbar.
So how do you custom-theme a DB Control grid? When you disable the themes completely, it seems to still not allow the active row to be custom painted. So I think that one must have to write a custom subclass and override the Paint method, plus write a VCL style hook class, for this purpose.
It appears that one should probably mostly just customizing using the regular owner draw events OnPaintPanel, and that adding that event, if you didn't, fixes the biggest VCL Styles glitch that I see for TDBCtrlGrid, which is that it doesn't ever use the SelectedColor and just paints everything in flat gray or whatever else is the base color. If anyone can confirm that, or tell me otherwise, it would be appreciated.

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.

Make FireMonkey TListBox in XE5 transparent

I have done some FireMonkey stuff in XE2, in this case I'm having troubles with a customized TListBox.
In XE2 I built this customized TListBox by removing it's background and surrounding rectangle (basically I only need the 'grouping of child items' functionality provided by TListBox. This was simple, drop a TListBox, hit 'edit custom style', select the background rectangle, edit the fill and the stroke and you're golden.
Now we're moving to XE5 and I cannot reproduce the same behavior. Using the style book editor I can see the background (which is now TStyleObject and not TRectangle), but I cannot make the changes I could make before. I see tutorials on how to add stuff to a TListBox, but not on how to take default behavior away.
Can someone explain how to achieve this specific behavior, or point me towards a good tutorial?
Try changing the StyleLookup property of the list box to transparentlistboxstyle

Add shortcut to a TForm or Panel.Transparent?

To thwart the nit-pickers, let me start with, I searched here with this and could not find an answer, and yes, also I did scroll through the "Similar questions."...
Adding shortcuts to a TForm
I want to drag and drop some shortcuts from the Desktop to a TForm in my application. I am using Anders Melander's brilliant Drag Drop Suite (DDS).
I tried putting a TImage on the form but the DDS does not drop to an Image so I added a TPanel with a TImage on it. I could then drop on the panel and assign the image to the TImage.Picture. Problem was the Panel has no Transparent Property so the shortcut on the form looks clunky with the visible Panel behind it.
I need to be able to drop to the TImage or make the underlying TPanel transparent.
Can anyone help with code-snippets for either of those options, or better yet, a method of dropping a Shortcut directly on to my Form.
Thanks
Coincidentally I needed to make a TWinControl (the base for every visible control with a window handle, including TPanel) transparent. I found numerous results and applied them to this answer.
It's been a while since I implemented drag and drop, but I assume you call some API and pass it the handle of the panel? That answers the question why you can't use TImage. TImage is a graphic control, a control without a handle, that relies on its parent for recieving messages and drawing itself.
It should be possible to use the form, though, since that has a handle too.
If the TImage is directly on the TForm, then let the TForm handle the drop, no TPanel needed. OLE Drag&Drop operations (which Ander's components implement) provide coordinates where dragging and dropping occurs. The TForm should be able to detect when a drag is over the area occupied by the TImage and what type of data is being dragged, and only allow dropping of supported types within that area, extracting the dropped data and updating the TImageas needed, and denying anything else that does not match that criteria.

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