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
>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/
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
[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
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...
>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