tags:

views:

209

answers:

2

I am sure that I got a good answer to my previous question because I have previously had a great deal of help on other questions from the guys who posted there.

But I am obviously doing something wrong, because when I copy the example code what the object inspector shows me for the MyProp property is a single text input field. I was expecting to see something that looks like the Font property, with Pitch, font family, etc i.e I expect to see a tree structure but I don't see the Color, Height or Width properties of the MyProp property.

Any ideas? Again, I copied that code exactly.


Edit: I forgot to mention (in this question) that I am using TMS scripter pro, which allows users to design forms at run time and provides its own object inspector, but that is probably derived from standard Delphi stuff, I guess.

Anyway, it appears that I am too dumb to code Delphi as I simply can't get this to work.


Edit: TMS assure me that if the class with "sub-properties) is descended from TPresistent then it will appear in the object inspector with sub-properties, just like Font, Anchors, etc

When I use this code, the "Warning" property appears as a text field in the object inspector and has no sub-properties

unit IntegerEditBox;
  // An edit box which only accepts integer values and warns if the value is not in a certain range

interface

uses
  SysUtils, Classes, Controls, StdCtrls,
  EditBox_BaseClass;

type

  TWarning = Class(TPersistent)
    private
      FWarningBelowValue   : Integer;
      FWarningAboveValue   : Integer;
      FWarningEmailTo : String;
      FWarningSmsTo   : String;
    published
      property WarningBelowValue   : Integer read FWarningBelowValue   write FWarningBelowValue;
      property WarningAboveValue   : Integer read FWarningAboveValue   write FWarningAboveValue;
      property WarningEmailTo      : String  read FWarningEmailTo      write FWarningEmailTo;
      property WarningSmsTo        : string  read FWarningSmsTo        write FWarningSmsTo;
  end;


  TIntegerEditBox = class(TEditBox_BaseClass)
    private
      FWarning : TWarning;
      procedure WriteValue(const newValue : Integer);


    protected
      // The new property which w/e introduce in this class
      FValue : Integer;   

    public { Public declarations }
      Constructor Create(AOwner: TComponent); override;   // This constructor uses defaults
      property Text;

    published  { Published declarations - available in the Object Inspector at design-time }
      property Hint;

      // Now our own properties, which we are adding in this class
      property Value : Integer read FValue write WriteValue;
      property Warning  : TWarning read FWarning write FWarning ;
  end;  // of class TIntegerEditBox()

procedure Register;

implementation

uses
  Dialogs;

  procedure Register;
  begin
    RegisterComponents('Standard', [TIntegerEditBox]);
  end;

  Constructor TIntegerEditBox.Create(AOwner: TComponent);
  begin
    inherited;  // Call the parent Create method
    Hint := 'Only accepts a number|Only accepts a number'; // Tooltip | status bar text
    Mandatory := True;
    Value := 0;
    Text := IntToStr(Value);
  end;

  procedure TIntegerEditBox.WriteValue(const newValue : Integer);
  begin
    Text := IntToStr(newValue);
  end;

end.
+1  A: 

Read this article it explains clearly about creating sub properties.

Bharat
This seems like an answer to the previous question, not this one, which asks what's wrong with the previous code.
Rob Kennedy
still a good answer, though :-)
Mawg
+2  A: 

The original version of the demo code neglected to create an instance of the property object.

constructor TMyControl.Create(AOwner: TComponent)
begin
  inherited;
  FMyProp := TCustomType.Create;
end;

Don't forget to free it in the destructor.

Remy's comment on that answer points out that the property needs to be assigned differently. The property's write accessor shouldn't write directly to the field. Instead, it should have a setter method that works like this:

procedure TMyControl.SetMyProp(const Value: TCustomType);
begin
  FMyProp.Assign(Value);
end;

That also highlights the requirement that the property class's Assign method be implemented, or else you'll get strange error messages like "Cannot assign a TCustomType to a TCustomType." A simple implementation could go like this:

procedure TCustomType.Assign(Source: TPersistent);
begin
  if Source is TCustomType then begin
    Color := TCustomType(Source).Color;
    Height := TCustomType(Source).Height;
    Width := TCustomType(Source).Width;
  end else
    inherited;
end;
Rob Kennedy
These details have been added to the code in the other discussion now.
Remy Lebeau - TeamB