Recent

Author Topic: casting integer to TObject for TStringList Objects array  (Read 33008 times)

ringo

  • New Member
  • *
  • Posts: 16
Re: casting integer to TObject for TStringList Objects array
« Reply #15 on: November 18, 2010, 04:37:22 am »
However, since TMemo uses TStrings instead of TStringList, the assignment to/from an integer will not work correctly.
no, memo uses TMemoStrings, simpler descendant of TStrings.  TStrings itself is never directly used by anyone as it simply can not be used (it is an abstract class). it is used only as a placeholder for objects of descendant classes.

No, the Lines is a TStrings; I don't know what a TMemoStrings is.  TMemo is derived from TCustomMemo, which defines Lines as a TStrings.  From the file "stdctrls.pp":

{ TCustomMemo }

  TCustomMemo = class(TCustomEdit)
  private
    FHorzScrollBar: TMemoScrollBar;
    FLines: TStrings;
    FScrollBars: TScrollStyle;
    FVertScrollBar: TMemoScrollBar;
    FWantReturns: Boolean;
    FWantTabs: boolean;
    FWordWrap: Boolean;
    procedure SetHorzScrollBar(const AValue: TMemoScrollBar);
    procedure SetVertScrollBar(const AValue: TMemoScrollBar);
  protected
    class procedure WSRegisterClass; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure InitializeWnd; override;
    procedure FinalizeWnd; override;
    function  RealGetText: TCaption; override;
    procedure RealSetText(const Value: TCaption); override;
    function GetCachedText(var CachedText: TCaption): boolean; override;
    function GetCaretPos: TPoint; override;
    procedure SetCaretPos(const Value: TPoint); override;
    procedure SetLines(const Value: TStrings);
    procedure SetSelText(const Val: string); override;
    procedure SetWantReturns(const AValue: Boolean);
    procedure SetWantTabs(const NewWantTabs: boolean);
    procedure SetWordWrap(const Value: boolean);
    procedure SetScrollBars(const Value: TScrollStyle);
    procedure Loaded; override;
    procedure ControlKeyDown(var Key: Word; Shift: TShiftState); override;
    procedure CNChar(var Message: TLMKeyUp); message CN_CHAR;
    class function GetControlClassDefaultSize: TSize; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Append(const Value: String);
  public
    property Lines: TStrings read FLines write SetLines;
    property HorzScrollBar: TMemoScrollBar read FHorzScrollBar write SetHorzScrollBar;
    property VertScrollBar: TMemoScrollBar read FVertScrollBar write SetVertScrollBar;
    property ScrollBars: TScrollStyle read FScrollBars write SetScrollBars default ssNone;
    property WantReturns: Boolean read FWantReturns write SetWantReturns default true;
    property WantTabs: Boolean read FWantTabs write SetWantTabs default false;
    property WordWrap: Boolean read FWordWrap write SetWordWrap default true;
  end;



Here is the entire definition of TStrings, from file "classesh.inc".  I don't see anything that makes it an abstract class.

{ TStrings class }

  TStrings = class(TPersistent)
  private
    FSpecialCharsInited : boolean;
    FQuoteChar : Char;
    FDelimiter : Char;
    FNameValueSeparator : Char;
    FUpdateCount: Integer;
    FAdapter: IStringsAdapter;
    FLBS : TTextLineBreakStyle;
    FStrictDelimiter : Boolean;
    function GetCommaText: string;
    function GetName(Index: Integer): string;
    function GetValue(const Name: string): string;
    Function GetLBS : TTextLineBreakStyle;
    Procedure SetLBS (AValue : TTextLineBreakStyle);
    procedure ReadData(Reader: TReader);
    procedure SetCommaText(const Value: string);
    procedure SetStringsAdapter(const Value: IStringsAdapter);
    procedure SetValue(const Name, Value: string);
    procedure SetDelimiter(c:Char);
    procedure SetQuoteChar(c:Char);
    procedure SetNameValueSeparator(c:Char);
    procedure WriteData(Writer: TWriter);
  protected
    procedure DefineProperties(Filer: TFiler); override;
    procedure Error(const Msg: string; Data: Integer);
    procedure Error(const Msg: pstring; Data: Integer);
    function Get(Index: Integer): string; virtual; abstract;
    function GetCapacity: Integer; virtual;
    function GetCount: Integer; virtual; abstract;
    function GetObject(Index: Integer): TObject; virtual;
    function GetTextStr: string; virtual;
    procedure Put(Index: Integer; const S: string); virtual;
    procedure PutObject(Index: Integer; AObject: TObject); virtual;
    procedure SetCapacity(NewCapacity: Integer); virtual;
    procedure SetTextStr(const Value: string); virtual;
    procedure SetUpdateState(Updating: Boolean); virtual;
    property UpdateCount: Integer read FUpdateCount;
    Function DoCompareText(const s1,s2 : string) : PtrInt; virtual;
    Function GetDelimitedText: string;
    Procedure SetDelimitedText(Const AValue: string);
    Function GetValueFromIndex(Index: Integer): string;
    Procedure SetValueFromIndex(Index: Integer; const Value: string);
    Procedure CheckSpecialChars;
  public
    destructor Destroy; override;
    function Add(const S: string): Integer; virtual;
    function AddObject(const S: string; AObject: TObject): Integer; virtual;
    procedure Append(const S: string);
    procedure AddStrings(TheStrings: TStrings); virtual;
    procedure Assign(Source: TPersistent); override;
    procedure BeginUpdate;
    procedure Clear; virtual; abstract;
    procedure Delete(Index: Integer); virtual; abstract;
    procedure EndUpdate;
    function Equals(Obj: TObject): Boolean; override; overload;
    function Equals(TheStrings: TStrings): Boolean; overload;
    procedure Exchange(Index1, Index2: Integer); virtual;
    function GetEnumerator: TStringsEnumerator;
    function GetText: PChar; virtual;
    function IndexOf(const S: string): Integer; virtual;
    function IndexOfName(const Name: string): Integer; virtual;
    function IndexOfObject(AObject: TObject): Integer; virtual;
    procedure Insert(Index: Integer; const S: string); virtual; abstract;
    procedure InsertObject(Index: Integer; const S: string;
      AObject: TObject);
    procedure LoadFromFile(const FileName: string); virtual;
    procedure LoadFromStream(Stream: TStream); virtual;
    procedure Move(CurIndex, NewIndex: Integer); virtual;
    procedure SaveToFile(const FileName: string); virtual;
    procedure SaveToStream(Stream: TStream); virtual;
    procedure SetText(TheText: PChar); virtual;
    procedure GetNameValue(Index : Integer; Out AName,AValue : String);
    function  ExtractName(Const S:String):String;
    Property TextLineBreakStyle : TTextLineBreakStyle Read GetLBS Write SetLBS;
    property Delimiter: Char read FDelimiter write SetDelimiter;
    property DelimitedText: string read GetDelimitedText write SetDelimitedText;
    Property StrictDelimiter : Boolean Read FStrictDelimiter Write FStrictDelimiter;
    property QuoteChar: Char read FQuoteChar write SetQuoteChar;
    Property NameValueSeparator : Char Read FNameValueSeparator Write SetNameValueSeparator;
    property ValueFromIndex[Index: Integer]: string read GetValueFromIndex write SetValueFromIndex;
    property Capacity: Integer read GetCapacity write SetCapacity;
    property CommaText: string read GetCommaText write SetCommaText;
    property Count: Integer read GetCount;
    property Names[Index: Integer]: string read GetName;
    property Objects[Index: Integer]: TObject read GetObject write PutObject;
    property Values[const Name: string]: string read GetValue write SetValue;
    property Strings[Index: Integer]: string read Get write Put; default;
    property Text: string read GetTextStr write SetTextStr;
    property StringsAdapter: IStringsAdapter read FAdapter write SetStringsAdapter;
  end;


I think the lack of an Objects array in TStrings is a bug.  TStrings defines Objects with a type and with access methods, but not with storage (not even an abstract type).  This seems to me like somebody started to write the code for TStrings, then got side-tracked with some other issue, and never came back to finish the code.

Ringo




Zoran

  • Hero Member
  • *****
  • Posts: 1763
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: casting integer to TObject for TStringList Objects array
« Reply #16 on: November 18, 2010, 09:54:00 am »
No, the Lines is a TStrings; I don't know what a TMemoStrings is.  TMemo is derived from TCustomMemo, which defines Lines as a TStrings.  From the file "stdctrls.pp":

The property is declared as TStrings, but in the constructor you can see how it is constructed:
Code: [Select]
constructor TCustomMemo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fCompStyle := csMemo;
  FWantReturns := True;
  FWantTabs := False;
  FWordWrap := True;
  FLines := TTextStrings.Create;
  FVertScrollbar := TMemoScrollBar.Create(Self, sbVertical);
  FHorzScrollbar := TMemoScrollBar.Create(Self, sbHorizontal);
  AutoSelect := False;
  AutoSize := False;
end;

So you see:
Code: [Select]
FLines := TTextStrings.Create;TTextStrings is the type.



Here is the entire definition of TStrings, from file "classesh.inc".  I don't see anything that makes it an abstract class.

{ TStrings class }

  TStrings = class(TPersistent)
...
    function Get(Index: Integer): string; virtual; abstract;
...
    function GetCount: Integer; virtual; abstract;
...
    procedure Clear; virtual; abstract;
    procedure Delete(Index: Integer); virtual; abstract;
...
    procedure Insert(Index: Integer; const S: string); virtual; abstract;
...    



Now you do, don't you? ;)


This is from the bottom of this page:
Quote
An instance of TStrings is never created directly, instead a descendent class such as TStringList should be created. This is because TStrings is an abstract class which does not implement all methods; TStrings also doesn't store any strings, this is the functionality introduced in descendents such as TStringList.

And this is from Delphi 7 help:
Quote
Derive a class from TStrings to store and manipulate a list of strings. TStrings contains abstract methods and should not be directly instantiated.

And from Emarcadero's site:
Quote
Derive a class from TStrings to store and manipulate a list of strings. TStrings contains abstract or, in C++ terminology, pure virtual methods and should not be directly instantiated.
« Last Edit: November 18, 2010, 10:04:10 am by Zoran »

ivan17

  • Full Member
  • ***
  • Posts: 173
Re: casting integer to TObject for TStringList Objects array
« Reply #17 on: November 18, 2010, 10:01:33 am »
let's leave the theory to rest.
@ringo  don't quote half the lcl/rtl in somebody else's thread

ringo

  • New Member
  • *
  • Posts: 16
Re: casting integer to TObject for TStringList Objects array
« Reply #18 on: November 18, 2010, 12:49:17 pm »
let's leave the theory to rest.
@ringo  don't quote half the lcl/rtl in somebody else's thread

Sorry, I got carried away.

I still don't think it is working correctly, but this is probably a subject for a different thread.

Ringo

ringo

  • New Member
  • *
  • Posts: 16
Re: casting integer to TObject for TStringList Objects array
« Reply #19 on: November 19, 2010, 05:27:50 am »
Just a clean-up note:

This issue was found and reported to the bug-tracker back in 2007:

0009366: TStrings implementation in combo objects - TObject not working

It's severity was changed from "major", then to "minor", then to "feature request".

Ringo

 

TinyPortal © 2005-2018