How to set the application font at design time? - delphi

I've read that the most centralized way to have font-consistency through a project is to have all controls with the ParentFont property active and set the Application.DefaultFont at runtime.
I would like to apply a different font, say 'Segoe UI', in the whole application at design time.
How can it be changed at design time?

You have a number of options, what works best for you may depend on your situation.
If you are using your own forms (not from a package or library) then you can design each to inherit from a parent to give you a starting font as suggested in the comments. However the IDE will allow this to be changed, and if the DFM file for the form records a font in the derived form, it will use that font even if the parent class font is changed.
Another approach would be to write a non-visual component that you can drop onto a form. When that component has it's Owner set (at creation) it can check if it is owned by a Form and set the font on the parent. In the same way it can set any properties you want it to, and it can also find the children of it's owner and set any properties on those controls as well.
Moving on from this you could, at runtime, look at the TScreen class which contains properties called CustomForms and Forms which allow you to access all currently active descendents of TCustomForm and TForm respectively. As you can access this you could change the fonts on all of them at runtime. So if you allow your user to select a font, using the Screen object you can change the font on all forms.
The combination of the two can allow you to easily gain control over display properties.
Be aware that changing the font face can change the size of the text rendered. (As of course will changing the font size and style). This can affect how your controls look and the alignment of them.

Related

(delphi) how to add property to child controls?

In the Delphi IDE, some components in Delphi have the ability to "add" properties to the child controls they contain in the property editor.
How can I achieve the same thing with my own TCustomPanel descendant?
Some more details:
What I want to achieve is the following: I have a very complex configuration dialog for an application with a large number of visual components.
I want to add to each of these components a "complexity index" (an integer) that will be used to show or hide the component based on a selection made by the user (a dropdown with "simple", "advanced" and "expert" options).
I understand that the property will actually belong to the parent panel but I need a way to display it, in the IDE, as if it was attached to the control it is related to.
The perfect exemples are the various "organizational" panels provided by Delphi: TGridPanel and TRelativePanel. Each of these have a ControlCollection (published) properties that is used to hold the actual states of the additional properties but I failed to locate how the property editor knows that it must attach the properties to the child controls.
Here is a screenshot of a TLabel placed inside a TRelativePanel with the relevant properties highlighted:

How to use two properties for a single property editor?

Refer to this prior question/answer combo of mine. It's describing how to create a property editor for the IDE.
I've created another property editor for a completely different purpose. In this case, it's a glyph character selector of type String (because it could contain more than one glyph character). Unlike my other one in mentioned question/answer, this one is very specific to a particular property on a particular TCollectionItem class of mine.
All is good, and I can invoke this property editor for this particular property. However, I have a dilemma. The property editor, by nature, is directly related to a font. The user may choose a character (glyph) from a particular font. My property editor has the facility to change the font, and browse the glyphs contained within that font.
This component of mine also has the facility to specify the font, in a separate TFont property. The problem arises when it comes to the combination of both my Glyph property and Font property being used in the very same property editor. When I invoke this editor for the Glyph property, it also needs to know the Font which it needs to use. On the contrary, when user chooses a font and glyph character in this editor, it also needs to update both the Glyph and Font properties.
Long story short, PropertyB depends on PropertyA. If PropertyA changes, then PropertyB will have an entirely different set of possible values. So, whatever editor I install in the IDE needs to allow the user to change both PropertyA and PropertyB at the same time.
How can I make a property editor have access to more than one property?
TPropertyEditor has a public GetComponent() method that you can use to access the object(s) whose property is currently being edited (multiple objects with the same property can be edited at the same time, if the property editor allows it). Then you will have access to all of the other properties in the same object(s).
That being said, if your editor displays a pop-up dialog for editing, it should be implemented as a component editor instead of (or in addition to) a property editor. A property editor should edit only one property at a time, though it may have read-only dependancies on other properties. For instance, a Glyph property editor that also edits the Font property, and vice versa, is not a good design. But a component editor that edits both is perfectly acceptable.
Solution 1
Instead of a property editor, implement a component editor. Such a component editor will have access to the entire component, not just a single property.
Solution 2
Wrap both of your properties inside of a dedicated TPersistent class, and then create a TClassProperty property editor for this class instead. The individual properties will not actually invoke a property editor. Instead, their parent TPersistent will invoke a combined property editor which has access to all the properties within this class. A good existing example is the TFont editor.

Removing properties from Object Inspector

I bought the TMS Component pack and want to hide some component properties from displaying in the object inspector.
I am using UnlistPublishedProperty to hide them.
It works most of the time. But for some reason e.g. Anchors or StyleSettings are still displayed.
I am calling it like this:
UnlistPublishedProperty(TAdvEdit, 'StyleElements');
The weird thing is that it works on 90% of properties and i can't figure out why it will not hide the other properties from the object inspector.
I could edit the source and comment out the line where it gets published from TCustomEdit but i am wondering why the method with UnlistPublishedProperty isn't working.
Thanks!
The properties you are trying to remove are inherited from a higher ancestor class. If you wish to use UnlistPublishedProperty to remove these particular properties, you'll have to remove them from the ancestor. However, that would apply to all controls, not just the one you're working on.
In addition to Jerry's answer; there is a solution for deleting properties from sub-components. The third part of my answer here demonstrates how to filter out properties of a sub-component of a custom component by registering a component PropertyEditor and overriding GetProperties to filter specific property names.

Override top/left when child controls are streamed in

I have a project where I try to share form files between Delphi and Lazarus. This actually works well excep with GroupBox there "top" values is caluculated against two different "tops". This menas that in Lazarus the controls are moved about 20-30 pixels too far down the TGroupBox.
Anyhow, assuming I design in Delphi, and I make a descendant TGroupBox. IO could Add a property called "fixiffromdelphi" (or something like that) and then add some code which ensures the child controls get placed correctly.
Ideally, this should happen under streamning, but I am not sure how to go about it. Is there anyway the parent (GroupBox) can access the subcontrols while the form streams in the dfm/lfm? And through that override e.g. top value?

How do I write a TDBCtrlGrid VCL Style custom class?

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.

Resources