Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Perchè Memo.lines.add e StringList.Add si comportano in modo diverso?

80 views
Skip to first unread message

Ryo GQI

unread,
Feb 26, 2005, 11:26:00 AM2/26/05
to
Ciao a tutti.

Vorrei porvi una domanda, forse banale, su TStrings e TStringList.
Avendo necessità di dividere una stringa in base ad un preciso criterio ho
utilizzato la
funzione WrapText (unit SysUtils).
Come descritto nell'oggetto, passando il risultato della funzione al metodo
Add della
TStringList viene aggiunta una sola stringa; invece passandolo al metodo Add
della property
Lines (TStrings) di un controllo Memo vengono aggiunte tante linee quante ne
risultano in
base al criterio di divisione specificato.
In base a questo ho dedotto che il metodo Add della TStringList non
riconosce i l carattere
di fine riga. Sapreste spiegarmi il perché di questa differenza di
comportamento dei due
metodi, visto che TStringList deriva da TStrings? Esiste qualche funzione
simile alla
WrapText che mi è sfuggita?
Uso il Delphi 6 Personal Edition.

Grazie a chiunque vorrà dare un chiarimento a questo novellino.

PS
Scusate se non potrò interagire tempestivamente ma, essendo uno studente,
non ho la
possibilità di connettermi con frequenza per controllare le eventuali
risposte ricevute.
--
Ryo

MassimoB

unread,
Feb 26, 2005, 1:00:44 PM2/26/05
to
"Ryo GQI" nel precedente post ha scritto:

>Ciao a tutti.

Ciao

>Vorrei porvi una domanda, forse banale, su TStrings e TStringList.

la cosa si fa meno banale poichè si entra nel concetto
di classi astratte ed ereditarietà ;)

>Avendo necessità di dividere una stringa in base ad un preciso criterio ho
>utilizzato la
>funzione WrapText (unit SysUtils).
>Come descritto nell'oggetto, passando il risultato della funzione al metodo
>Add della
>TStringList viene aggiunta una sola stringa; invece passandolo al metodo Add
>della property
>Lines (TStrings) di un controllo Memo vengono aggiunte tante linee quante ne
>risultano in
>base al criterio di divisione specificato.
>In base a questo ho dedotto che il metodo Add della TStringList non
>riconosce i l carattere
>di fine riga. Sapreste spiegarmi il perché di questa differenza di
>comportamento dei due
>metodi, visto che TStringList deriva da TStrings? Esiste qualche funzione
>simile alla
>WrapText che mi è sfuggita?

No ... c'è un perchè (e di questo ne eravamo tutti
sicuri ...spero :P ) non è semplicissimo arrivarci ma
con la magia del Ctrl+Click sul nome della classe ci
possiamo arrivare più omeno facilmente.

Allora ... iniziamo dalla TStrings (scrivi nel
code-editor la parola "TStrings" e tenendo premuto il
tasto ctrl cliccaci su), questa è una classe astratta,
cioè presenta dei metodi solo dichiarati in firma ma
che non sono implementazione. I metodi astratti sono
Insert, Get, GetCount e Delete, proprio quelli di
interazione con la lista di oggetti che la classe
rappresenta, questo perchè TStrings effettivamente
fornisce un ottima base di firma (dichiarazione di
campi, metodi e proprietà) per una classe che lavora
con una lista di stringhe ma, la lista di stringhe,
all'atto pratico, non la ha.

Qui entrano in gioco TStringList e TMemoStrings che
sono entrambi eredi diretti di TStrings e forniscono
proprio la lista di oggetti e l'implementazione dei
metodi di interazione con la lista stessa di cui
TStrings manca.

E' come se TStrings fosse l'involucro con cui il mondo
esterno vede qualcosa mentre TStringsList ed eredi vari
forniscono il contenuto.

Ecco perchè, di solito, si dovrebbe dichiarare delle
TStrings e creare dei suoi eredi come la TStringsList

-----------------------------------------------------------
[...]
var
FMiaStrings: TStrings;
begin
FMiaStrings := TStringList.Create;
[...]

------------------------------------------------------------

Infatti un'altra cosa da sapere per arrivare al tuo
perchè, è che nel TMemo la Proprietà Lines e
dichiarata come una TStrings, quindi la usi con tutti
i metodi che ti espone TStrings, ma creata come una
TMemoStrings e quindi utilizzi l'implementazione dei
metodi di TStrings fatta in TMemoStrings.

------------------------------------------------------------
constructor TCustomMemo.Create(AOwner: TComponent);
begin
[...]
FLines := TMemoStrings.Create;
TMemoStrings(FLines).Memo := Self;
end;

------------------------------------------------------------

Bè adesso dovrebbe bastare far 2+2 un pò di ctrl+click
sui vari metodi Add e poi Insert dei due eredi
TStringsList e TMemoStrings per capire che TMemoStrings
manda a capo nell'Insert mentre TStringsList no ...
TStrings poveretta non ne ha colpa :P.

Per verificare prova a scrivere una linea del genere
nel tuo form

ShowMessage(Memo1.Lines.ClassName);

io non ho provato ma stando alle classi ti dovrebbe
rispondere "MemoStrings" :)

>Grazie a chiunque vorrà dare un chiarimento a questo novellino.
>PS
>Scusate se non potrò interagire tempestivamente ma, essendo uno studente,
>non ho la
>possibilità di connettermi con frequenza per controllare le eventuali
>risposte ricevute.

non ti preoccupare ... siamo sempre qui :P (nei
momentidi pausa lavorativa o festivi)

>Ryo

Ciao
MassimoB

---------------------------
http://www.massimobeschi.it/

guastatore

unread,
Feb 26, 2005, 1:06:05 PM2/26/05
to
> TStringList viene aggiunta una sola stringa; invece passandolo al
> metodo Add della property
> Lines (TStrings) di un controllo Memo vengono aggiunte tante linee
> quante ne risultano in
> base al criterio di divisione specificato.
> In base a questo ho dedotto che il metodo Add della TStringList non
> riconosce i l carattere
> di fine riga. Sapreste spiegarmi il perché di questa differenza di
> comportamento dei due
> metodi, visto che TStringList deriva da TStrings? Esiste qualche
> funzione simile alla
> WrapText che mi è sfuggita?

Non è il metodo Add che si comporta diversamente ma il metodo Insert
che è dichiarato virtual abstract in TStrings. Non ho avuto modo di
analizzare il codice della vcl per capire questa differenza di
comportamento, ma puoi partire da qui come spunto.

guastatore

Ryo GQI

unread,
Feb 27, 2005, 9:37:33 AM2/27/05
to

MassimoB ha scritto nel messaggio
news:WM2Ud.69577$2h5....@tornado.fastwebnet.it...

[cut]

> con la magia del Ctrl+Click sul nome della classe ci
> possiamo arrivare più omeno facilmente.

Non so perche' ma il Ctrl+Click non mi funziona, :-(
comunque se ho capito a che serve basta un click
col tasto destro e vai con "Find Declaration" ma
ahime' ecco spuntare il messaggio: Unable to locate
file "StdCtrls.pas". Mancano i sorgenti della VCL
d'altronde ho preso il D6 dal cd di una rivista, in piu'
e' Personal: non si puo' pretendere molto. :-)

[cut]

> ------------------------------------------------------------
> constructor TCustomMemo.Create(AOwner: TComponent);
> begin
> [...]
> FLines := TMemoStrings.Create;
> TMemoStrings(FLines).Memo := Self;
> end;
>
> ------------------------------------------------------------
>
> Bè adesso dovrebbe bastare far 2+2 un pò di ctrl+click

Se non ho sbagliato a fare il 2+2 in base alla porzione di codice di
esempio che hai postato, dovrei creare una nuova classe che
implementi una proprietà di tipo TStrings che erediti i metodi da
TMemoStrings. Sto sbagliando o sono riuscito a centrare il problema?
O forse e' meglio, vista la mia scarsa dimestichezza con classi ed
ereditarita', utilizzare una variabile di tipo TMemo?

Ho verificato e la classe di appartenenza e' proprio TMemoStrings.
Ma nella guida non c'e' traccia di questa classe, puoi indicarmi qualche
link in cui viene trattata questa classe?

Grazie per la risposta alquanto chiara ed esauriente,
almeno per la mia scarsa conoscenza della materia. :)

Ciao

PS
Spero di aver quotato bene.

--
Ryo


Giorgio Padoan

unread,
Feb 27, 2005, 12:34:34 PM2/27/05
to
Per quanto ne so la TStringList accetta anche stringhe contenenti i
caratteri di nuova riga: #13#10, per cui se esegui l'add di una stringa
formata da 2 o piu stringhe separate da questi caratteri non crea 2 o piu'
Item ma sempre uno.
Se pero' poi questo item lo inserisci in una Tmemo ti compaiono le 2 o piu'
stringe in linee separate.
Per verificarlo puoi provare cosi':

StringList1.Clear;
StringList1.Add('Prima'+#13#10+'Seconda'); // viene aggiunto un solo item
Memo1.lines.Add(StringList1[0]); // aggiunge 2 linee interpretando
correttamente i caratteri di nuova riga

non so qual'era il tuo obiettivo ma se desideri che ognuna delle 2 o piu'
stringhe componenti vengano aggiunte nella TStringList in separati Items
potresti ad esempio usare il Copy nella stringa intera per spezzarla nelle
sottostringhe, nell'esempio sopra farei:
st: String;

st:='PrimaSeconda'; // Stringa Intera
StringList1.Add( Copy(st,1,5)); // inserisci 'Prima'
StringList1.Add( Copy(st,6,7); // inserisci 'Seconda'


Ciao, giorgio

"Ryo GQI" <shingoUNDER...@libero.it> ha scritto nel messaggio
news:sq1Ud.593929$b5.27...@news3.tin.it...

Ryo GQI

unread,
Mar 5, 2005, 7:14:46 AM3/5/05
to
Mi rispondo da solo alla domanda:

>Esiste qualche funzione simile alla WrapText che mi è sfuggita?

Si, ExtractStrings. Dall'help:

"Fills a string list with substrings parsed from a delimited list.

Unit

Classes

Category

string handling routines (null-terminated)

Delphi syntax:

function ExtractStrings(Separators, WhiteSpace: TSysCharSet;
Content: PChar; Strings: TStrings): Integer;
[...]
Description

Use ExtractStrings to fill a string list with the substrings of the
null-terminated string specified by Content.
[...]
ExtractStrings returns the number of strings added to the Strings parameter.

Note: ExtractStrings does not add empty strings to the list."

Mi bastava solo cercare un po' meglio dall'inizio. Pero' questo mi ha
'costretto' ad iniziare a guardare le classi con annessi e connessi. :-)

Ciao.

---
Ryo

0 new messages