TRichView, array of TGIFImage and errors on closing the form

General TRichView support forum. Please post your questions here
Post Reply
Antinoka
Posts: 5
Joined: Sun Sep 30, 2012 6:10 pm

TRichView, array of TGIFImage and errors on closing the form

Post by Antinoka »

Hi!
I use TRichView and TGIFImage for smiles in a chat. Smilies are written in Dynamic arrays. Everything works fine until smilies are not repeated. Otherwise, when you close the form see the error. Help me, please. :(
Screenshot of the error:

Image

Source: http://kkepit.if.ua/img/Smiles.rar

Code: Select all

var
  Form1: TForm1;
  GifList: array of TGIFImage;
  i: integer;

procedure TForm1.Button1Click(Sender: TObject);
begin
  with RichView1 do
  begin
    for i:=0 to 2 do
        AddPictureExTag('Smile', GifList[i], 0, rvvaAbsMiddle, IntToStr(i));
    ReFormat;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  for i:=0 to 2 do
    begin
      SetLength(GifList, i+1);
      GifList[i]:=TGIFImage.Create;
      try
        GifList[i].LoadFromFile(IntToStr(i+1)+'.gif');
      except
      end;
    end;
  RichView1.StartAnimation;
end;

initialization
  RegisterClass(TGIFImage);
end.
Antinoka
Posts: 5
Joined: Sun Sep 30, 2012 6:10 pm

Post by Antinoka »

The error appears when you close the form when the button Button1 worked more than once.
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

By default, TRichView frees all inserted images.
So if you insert the same gif multiple times, the same object is freed multiple times.

There are two solution:
1) creating a new TGifImage, assigning it from the array, and inserting it in TRichView, or
2) using shared images:

Code: Select all

 with RichView1 do 
  begin 
    for i:=0 to 2 do 
    begin
        AddPictureExTag('Smile', GifList[i], 0, rvvaAbsMiddle, IntToStr(i)); 
        SetItemExtraIntProperty(ItemCount-1, rvepShared, 1);
    end;
    Format; 
  end; 
PS: after adding or deletion of items, Format must be used instead of Reformat.
Antinoka
Posts: 5
Joined: Sun Sep 30, 2012 6:10 pm

Post by Antinoka »

Many thanks. The second solution I was perfectly fine. If anyone will read this, you need to add 'RVItem' in uses, if will give an error on undeclared variable 'rvepShared'.
In the beginning I did the first one, which had seen many times on the Internet, but it used a lot of memory.

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
var
  Gif: TGIFImage;
begin
  with RichView1 do
  begin
    for i:=0 to 2 do
      begin
        Gif:=TGIFImage.Create;
        Gif.Assign(GifList[i]); // It used a lot of memory.
        AddPictureExTag('Smile', Gif, 0, rvvaAbsMiddle, IntToStr(i));
      end;
    Format;
  end;
end;
Thank you again. :)
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Actually, copying using Assign should not use a lot of memory. Delphi graphic classes use copy-on-write mechanism, so the new gif must share the image data with the images from GifList[].
But of course, using shared images in TRichView is more efficient.
Post Reply