How can I add the glyph property to my custom component? - delphi

How can I add a glyph property to my custom component?
Vcl.Buttons has declared class TButtonGlyph but I cannot use it (Delphi is not seeing it with Vcl.Buttons in uses list).

TButtonGlyph is an internal helper class used by the VCL. It's not what you need. I suspect that all you need to do is to declare a published property of type TPicture. The VCL will automatically provide a design time editor and can stream the image to the .dfm file. You can use any TGraphic descendent, including TPNGImage.

Related

Hide properties and events in new component

I created in Lazarus a new component based on TPaintBox. Now in Object Inspector I have all Properties and Events which belong to this base component (TPaintBox).
My question is: can I hide chosen Properties and Events for my component?
For example I would like to leave visible only Width and Height properties.
Can you help me?
Once a property/event has been published, it cannot be un-published.
However, it can be hidden from the Object Inspector, at least (it is still accessible to code).
After your design-time code has registered the component with the IDE, it can then:
in Delphi, call UnlistPublishedProperty() from the DesignIntf unit.
in Lazarus, call RegisterPropertyEditor() from the PropEdits unit to register the THiddenPropertyEditor class for the property/event (see Hide Properties (UnlistPublishedProperty) in the Lazarus forum).
Not sure about Lazarus, but in Delphi TPaintBox is a lightweight descendant of TGraphicControl. The majority of its declaration is just publishing properties. I don't know what your component is doing, but it might be easier to derive it directly from TGraphicControl and duplicate the TPaintBox code wherever it actually is needed. Then you can publish only the properties you want. Note that you still have those properties declared published in TControl and TComponent.
No, you can't hide (unpublish) published properties.
In Delphi most objects are based on a parent classes with all the same properties, but mostly hidden.
So while you can't hide exposed properties you can usually achieve what you want by basing your class on the TCustomxxx instead.
Sadly, TPaintbox is an exception. It is descended from TGraphicControl, but that in turn is descended from TControl which already has a number of published properties, including AlignWithMargins, CustomHint and several others, and that in turn is descended from TComponent which has Name and Tag published. To be fair, you need name for sure, and Tag is not a problem I would think.
If you just had to go back to TGraphicControl, that is not too bad. Just one member and a couple of routines to copy. But to go back to TComponent, which is what you would need to do to hide a number of properties is not really viable.

How to prevent modifying a design time component in derived form

I have defined a base VCL form class with a (non-visual) designtime component on it that contains a collection of styles.
I want to prevent developers (and myself) to change those styles in the forms that are derived from my base form. To speak in C# terms, I would like the component to be sealed in the base VCL form.
How can I achieve that?
On a side note: I never did understand the declaration of designtime components on a form in Delphi.. kinda public but not placed in the public section of the class declaration. Can anybody explain the reason for this?
Well, short answer you can't. In case you really need it I would suggest to create the component in run-time and make it private. If you are using GExpert (click here) you may use "Components to Code" command to get the required code. If you need more details, please share your DFM file and I will post the corresponding code here.
As for your side note, the components are declared as published. See Visibility of Class Members quote
If a member's declaration appears without its own visibility
specifier, the member has the same visibility as the one that precedes
it. Members at the beginning of a class declaration that do not have a
specified visibility are by default published, provided the class is
compiled in the {$M+} state or is derived from a class compiled in the
{$M+} state; otherwise, such members are public
NB TForm is a descendant of TPersistent which is compiled with {$M+} directive
PS the published declaration is required for TComponent.SetName (actually TComponent.SetReference) which should assign the component reference to the corresponding field when you modifying the component Name property.

Delphi LiveBindings: binding a component property to a TEdit

In want to use LiveBindings in Delphi XE5. I am new to this.
I have a VCL TForm with a TEdit.
I have a component in a seperate unit:
TMyComponent=class(TComponent)
private
FMyProperty: Integer;
public
property MyProperty: Integer read FMyProperty write FMyProperty;
end;
Now I want to bind MyProperty to the TEdit.
I tried this with right clicking on the TEdit and select "Bind visually" as well as with the LiveBindings wizard. The problem is that the MyComponent is not listed in the components list there.
The unit which contains MyComponent is in the uses clause of the form.
What am I doing wrong?
Thanks!
The IDE only knows about component classes that have been registered with it. To make this work at design-time, you need to build a package that registers the component class. Otherwise, you'll need to create the bindings programmatically. I'm not particularly familiar with the LiveBindings system, but there are several questions in the livebindings tag that show how it's done.

Using classes in dwsunit

1- Why is it necessary to name the methods of a class in a dwsunit this way?
dwsUnitClasses'ClassName''MethodName'Eval(Info: TProgramInfo;
var ExtObject: TObject)
2- Is there a link that must be done between the method defined in a dwsunit and its code?
coz it is not working with me. I took the demo attached with the DWscript (Custom Classes) and made something that looks like it but it is just not functioning.
No it's not necessary, that's just the format the IDE uses for auto-generated event names.
Usually you define script classes, their methods in the structure view, then you double-click their OnEval (or other) event in the properties editor, the IDE will create a method with a name like the above and you can implement there.
If you declare the methods manually, then you also have to attach their events manually, but it's not different than what you end up doing for a button click event (and where you end up with a Button1Click method).
Apart from the implementation code itself, most of the declarations in DWScript can happen at design-time, and are stored in the DFM. The Structure View is convenient for that, but you can also use the property editor only (it was even more convenient in older Delphi versions, when the structure view was sticking to design-time structures, rather than being reused for source structure).

Class Reference as Property

Google is useless for these sorts of searches, because you get hundreds of millions of results absolutely none of which relate to the specific question.
The question is simply this:
Is it possible to have a Class Reference Property in Delphi?
If so, how?
Here's what I've tried...
type
TMyObject = class
// ...
end;
TMyObjectClass = class of TMyObject
TMyObjectA = class(TMyObject)
// specifics here
end;
TMyObjectB =class(TMyObject)
// specifics here
end;
TMyComponent = class(TComponent)
private
FObjectType: TMyObjectClass;
published
property ObjectType: TMyObjectClass read FObjectType write FObjectType;
end;
The above code compiles fine, however the Object Inspector does not show the ObjectType property at all.
My objective here (if you haven't already guessed) is to make it so that I can select a class descendant from a specific base class, to make the same component behave in a different way.
I want to do it this way so that the component doesn't need to know about the sub-classes directly (it needs to be fully modular).
Let me just make this bit clear: I cannot use an Enum to choose between the sub-class types as the component cannot directly link to the sub-class types (It's simply not possible in this particular case)
Anyway... thanks in advance!
You can find all classes that descend from a particular base class: Delphi: At runtime find classes that descend from a given base class? and make this a special property with list of values using TPropertyEditor.
If you were going to do this then you would need to provide a property editor. The IDE does not come with property editors for class type properties. You would also need to handle .dfm persistence. You would write the class type out to the .dfm file as a string and when the .dfm file is read, you would need to fixup the reference. New style RTTI could do that.
However, I don't think any of this is actually viable for the following reason. Your design time code runs in a package inside the IDE and does not have access to the class types in the active project in the IDE. Those class types only exist when that project runs. So the ObjectType property in the code in your question cannot be assigned to anything meaningful in the design time package. Well, you could use it for classes defined in the VCL and any other packages installed in your IDE but I rather imagine you'd want to use it on classes defined in the active project.
I think all this means that you should instead use a simple string property and fixup the class type references only at runtime.

Resources