Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a component i.e. TBrandNewComponent, who has published property Jumbo: TJumboClass, which is:

TJumboClass = class
   P: Pointer
end;

I had overriden the GetValues procedure to show different components in a list of Jumbos's values in Object Inspector. Now list shows components of TJumboClass and components of TMassiveClass and TRotefulClass.

There is also TBrandNewComponent.JumboSelectedComponentType: integer, which I want to change due to selected component in TBrandNewComponent.Jumbo and also I want something-like cast TMassiveClass and TRotefulClass to TJumboClass saving them something like that: TJumboClass.P = Pointer(TMassiveClass(current)).

By that I mean, that I need to store to a property TBrandNewComponent.JumboClass.P a pointer of appropriate selected component, so that with a JumboSelectedComponentType I can correctly access this pointer and return the right class in further operations.

So, is there any procedure, that affects that and is that possible anyway?

Any suggestions and thoughts are appreciated!

PS: I've already discovered method SetValue. Now I need somehow to override it. What it might be?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
122 views
Welcome To Ask or Share your Answers For Others

1 Answer

What you describe makes no sense.

If you derive TMassiveClass and TRotefulClass from TJumboClass then the Object Inspector will automatically list all component instances of those class types for you, there is no need to write a custom design-time editor to override GetValues(), the default implementation is sufficient.

type
  TBrandNewComponent = class(...)
  private
    fJumbo: TJumboClass;
  published
    property Jumbo: TJumboClass read fJumbo write fJumbo;
  end;

type
  TMassiveClass = class(TJumboClass)
    ...
  end;

  TRotefulClass = class(TJumboClass)
    ...
  end;

If you do not derive TMassiveClass and TRotefulClass from TJumboClass but still want the Object Inspector to automatically list all component instances of those class types for you, you can use a custom IInterface for that purpose (yes, you can use interfaces in published properties):

type
  IJumbo = interface(IInterface)
  ['{DA51630E-2FFB-425D-A62D-F1BE414DBC6F}']
  end;

  TBrandNewComponent = class(...)
  private
    fJumbo: IJumbo;
  published
    property Jumbo: IJumbo read fJumbo write fJumbo;
  end;

type
  TJumboClass = class(..., IJumbo)
    ...
  end;

  TMassiveClass = class(..., IJumbo)
    ...
  end;

  TRotefulClass = class(..., IJumbo)
    ...
  end;

Either way, to update the value of TBrandNewComponent.JumboSelectedComponentType whenever TBrandNewComponent.Jumbo is changed, you can provide a setter method for the Jumbo property, which will be called at both run-time and design-time. Again, no custom design-time editor is needed:

type
  TBrandNewComponent = class(...)
  private
    fJumbo: TJumboClass;
    procedure SetJumbo(Value: TJumboClass);
  published
    property Jumbo: TJumboClass read fJumbo write SetJumbo;
  end;

procedure TBrandNewComponent.SetJumbo(Value: TJumboClass);
begin
  if fJumbo <> Value then
  begin
    fJumbo := Value;
    // update JumboSelectedComponentType as needed...
end;

Your description of JumboClass.P really does not make sense. Assuming current is the component object currently assigned to the Jumbo property, then you are essentially setting Jumbo.P to the Self pointer of the component object, which is basically useless.

Since your other property is named JumboSelectedComponentType, it sounds like you want to store the class type of the selected component, not the object pointer. If that is the case, then a much more robust design is to give the JumboSelectedComponentType property a getter method (or just change it into a public function instead of a property) that queries the current Jumbo object for its ClassType:

type
  TBrandNewComponent = class(...)
  private
    fJumbo: TJumboClass;
  public
    function JumboSelectedComponentType: TClass;
  published
    property Jumbo: TJumboClass read fJumbo write fJumbo;
  end;

function TBrandNewComponent.JumboSelectedComponentType: TClass;
begin
  if fJumbo <> nil then
    Result := fJumbo.ClassType
  else
    Result := nil;
end;

Alternatively:

type
  TJumboClassType = class of TJumboClass;

  TBrandNewComponent = class(...)
  private
    fJumbo: TJumboClass;
  public
    function JumboSelectedComponentType: TJumboClassType;
  published
    property Jumbo: TJumboClass read fJumbo write fJumbo;
  end;

function TBrandNewComponent.JumboSelectedComponentType: TJumboClassType;
begin
  if fJumbo <> nil then
    Result := TJumboClassType(fJumbo.ClassType)
  else
    Result := nil;
end;

If this is NOT what you are looking for, then you need to provide more details about what exactly you are really looking for, because your original description is just too vague.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...