itamar
asked on
TMemoryStream basics
Hi all !
Why this piece of code doesn´t work:
procedure TForm1.SpeedButton1Click(S ender: TObject);
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
ListBox2.Items.SaveToStrea m(Stream);
ListBox1.Items.LoadFromStr eam(Stream );
Stream.Free;
//Please ! Don´t tell me I could make ListBox1.Items := ListBox2.Items
end;
As I never used TMemoryStream, I guess I am really missing smth...
Bye,
Itamar
Why this piece of code doesn´t work:
procedure TForm1.SpeedButton1Click(S
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
ListBox2.Items.SaveToStrea
ListBox1.Items.LoadFromStr
Stream.Free;
//Please ! Don´t tell me I could make ListBox1.Items := ListBox2.Items
end;
As I never used TMemoryStream, I guess I am really missing smth...
Bye,
Itamar
Hi,
Raymond's solution is a very good one.
The reason your code doesn't work is that when you load from the stream the stream's data offset is set to the end of it's data, since that's where it goes after saving to the stream. That means you are trying to read data from the end of the stream. And there is exactly zero bytes available in that position, at that time.
The solution, using your code, would be:
procedure TForm1.SpeedButton1Click(S ender: TObject);
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
ListBox2.Items.SaveToStrea m( Stream );
Stream.Position := 0; // << HERE'S WHERE YOU RESET THE STREAM OFFSET
ListBox1.Items.LoadFromStr eam( Stream );
Stream.Free;
end;
This code, however, is the exact equivalent of:
ListBox1.Items.Text := ListBox2.Items.Text;
Otherwise, the streams are excellent. I use them very frequently, but that, of course, is a totally other history...
/// John
Raymond's solution is a very good one.
The reason your code doesn't work is that when you load from the stream the stream's data offset is set to the end of it's data, since that's where it goes after saving to the stream. That means you are trying to read data from the end of the stream. And there is exactly zero bytes available in that position, at that time.
The solution, using your code, would be:
procedure TForm1.SpeedButton1Click(S
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
ListBox2.Items.SaveToStrea
Stream.Position := 0; // << HERE'S WHERE YOU RESET THE STREAM OFFSET
ListBox1.Items.LoadFromStr
Stream.Free;
end;
This code, however, is the exact equivalent of:
ListBox1.Items.Text := ListBox2.Items.Text;
Otherwise, the streams are excellent. I use them very frequently, but that, of course, is a totally other history...
/// John
Yes, John is absolutely right...
Always...! ;-)
/// John
/// John
Well - I guess I'd better submit this as the answer...
Nope, ListBox1.Items := ListBox2.Items is wrong as you say, though you can do
ListBox1.Items.assign(List Box2.Items ).
erajoj pointed out the problem with not setting position so if that was the better answer reject this one and erjoj will submit it as the answer.
Cheers,
Raymond.
Nope, ListBox1.Items := ListBox2.Items is wrong as you say, though you can do
ListBox1.Items.assign(List
erajoj pointed out the problem with not setting position so if that was the better answer reject this one and erjoj will submit it as the answer.
Cheers,
Raymond.
ASKER
Hi all,
In fact this code is just a dummy to show an example of my doubt.
What I am trying to do is to transfer the contents of a TStringList to the lines of a combo.
I thought the best way was using streams, but I didn´t know about Stream.Position.
So, erajoj (John) solved my problem. Post your comment as an answer, so I can grade it.
BTW, there is a better way to transfer a TStringList contents to a Combo ?
Thanks to all !
Itamar
In fact this code is just a dummy to show an example of my doubt.
What I am trying to do is to transfer the contents of a TStringList to the lines of a combo.
I thought the best way was using streams, but I didn´t know about Stream.Position.
So, erajoj (John) solved my problem. Post your comment as an answer, so I can grade it.
BTW, there is a better way to transfer a TStringList contents to a Combo ?
Thanks to all !
Itamar
Hi Itamar,
I still think Raymonds answer is the best. It gives you the least overhead.
The best ways to move strings from one TStringList/TStrings to another:
List1.BeginUpdate; { prevent repaints until done }
List1.Clear; { empty the list of any old values }
List1.AddStrings( List2 ); { add all strings from list2 }
List1.EndUpdate; { reenable painting }
List1.BeginUpdate;
List1.Assign( List2 ); { add all strings from list2 }
List1.EndUpdate;
Raymond, re-answer the question, and Itamar, give the man back his rightfully earned points.
/// John
I still think Raymonds answer is the best. It gives you the least overhead.
The best ways to move strings from one TStringList/TStrings to another:
List1.BeginUpdate; { prevent repaints until done }
List1.Clear; { empty the list of any old values }
List1.AddStrings( List2 ); { add all strings from list2 }
List1.EndUpdate; { reenable painting }
List1.BeginUpdate;
List1.Assign( List2 ); { add all strings from list2 }
List1.EndUpdate;
Raymond, re-answer the question, and Itamar, give the man back his rightfully earned points.
/// John
Here we go again! :-)
ASKER
Hey people,
I think I´m having problems to make me being understood !!
I need to transfer the contents of a TStringList to a TStrings !!!
When I found out TStream I couldn´t use it because my code was missing the Position := 0;
My example is just a DUMMY code !!!!!
I think I have to make an English course ;(((
I think I´m having problems to make me being understood !!
I need to transfer the contents of a TStringList to a TStrings !!!
When I found out TStream I couldn´t use it because my code was missing the Position := 0;
My example is just a DUMMY code !!!!!
I think I have to make an English course ;(((
Hi Itamar,
You cannot transfer anything to a TStrings object. Only through it, since is not a container but an interface.
What is the problem? Explain further! Send the code you're working on.
/// John
You cannot transfer anything to a TStrings object. Only through it, since is not a container but an interface.
What is the problem? Explain further! Send the code you're working on.
/// John
ASKER
I will try to explain:
1. Create a TStringList instance
2. Fill this TStringList with some strings
3. Now I need to show those strings in a Memo or ListView
How to ?
1. Create a TStringList instance
2. Fill this TStringList with some strings
3. Now I need to show those strings in a Memo or ListView
How to ?
Hi,
the memo is easy, the listview less easy:
var
MyList: TStringList;
iIndex: Integer;
begin
MyList := TStringList.Create;
with MyList do
begin
Add( 'string 1' );
Add( 'string 2' );
Add( 'string 3' );
end;
MyMemo.Lines.Assign( MyList ); // load to memo
with MyListView.Items do // load to listview
begin
Clear;
for iIndex := 0 to MyList.Count - 1 do
Add.Caption := MyList[ iIndex ];
end;
MyList.Free;
end;
This code is not tested, so there might be some typos.
/// John
the memo is easy, the listview less easy:
var
MyList: TStringList;
iIndex: Integer;
begin
MyList := TStringList.Create;
with MyList do
begin
Add( 'string 1' );
Add( 'string 2' );
Add( 'string 3' );
end;
MyMemo.Lines.Assign( MyList ); // load to memo
with MyListView.Items do // load to listview
begin
Clear;
for iIndex := 0 to MyList.Count - 1 do
Add.Caption := MyList[ iIndex ];
end;
MyList.Free;
end;
This code is not tested, so there might be some typos.
/// John
ASKER
Hi John,
the Assign method is the answer to my question.
Post your comment as a question, so I can grade it.
Thanks,
Itamar
the Assign method is the answer to my question.
Post your comment as a question, so I can grade it.
Thanks,
Itamar
So which one of us do you want to answer it. We both said use assign...
Cheers,
Raymond.
Cheers,
Raymond.
How many times do I have to say this; the points are yours, Raymond! :-)
My latest comment was just a note on your answer, since Itamar didn't seem to
understand the memo/listbox architecture. Not a correction.
Itamar, give the points to Raymond, I don't seem to get my Tshirts anyway. ;-(
/// John
My latest comment was just a note on your answer, since Itamar didn't seem to
understand the memo/listbox architecture. Not a correction.
Itamar, give the points to Raymond, I don't seem to get my Tshirts anyway. ;-(
/// John
ASKER
Ok !
Raymond, be my guest !
Raymond, be my guest !
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Apart from perhaps setting the sizxe of the TMemoryStream I am not sure what might be causing that to fail (perhaps you could tell us what does go wrong...)
Cheers,
Raymond.