0

I have tried each of the following in Delphi 2010 to display an animated gif on my form. All result in an access violation. (Two of the three variations were commented out on each attempt.) Thanks much.

uses ... GIFImg,... Image1: TImage; procedure TForm1.FormCreate(Sender: TObject); begin // A valid animated gif was loaded into Image1 at design time TGIFImage(image1).Animate := true; TGIFImage(image1.Picture).Animate := true; TGIFImage(image1.Picture.Graphic).Animate := true; end; 

I attempted to follow the answer in the question linked above, but the solution did not work for me (and with that question being tagged explicitly as Delphi-7, I didn't know if something had changed). Rewriting to "(image1.Picture.Graphic as TGIFImage).Animate := true;" results in "... exception class EInvalidCast with message 'Invalid class typecast'." It's not clear to me why the typecast is invalid since I'm positive that an animated gif has already been loaded at design time.

Edit to clarify the issue, here's the revised code. The showmessage tells me that the image is a TdxSmartImage. No idea why it thinks this. (I did at one point try to load the image into a devExpress control to see if that would work, but I subsequently removed all dexExpress elements from the form/project and regenerated the gif file.

procedure TForm1.FormCreate(Sender: TObject); begin image1.Picture.LoadFromFile('C:\ChronSource\ChronDialogs\11.0 job menu.gif'); ShowMessage(image1.Picture.Graphic.ClassName); // this says "TdxSmartImage" (image1.Picture.Graphic as TGIFImage).Animate := true; end; 
9
  • 3
    Only the 3rd variation is valid, but only after a GIF has been loaded into the TImage. If you are getting an AV on the 3rd variation, you need to debug to find out why. The 1st variation is invalid because a TImage is not a TGIFImage. The 2nd variation is invalid because a TPicture is not a TGIFImage. Those are invalid casts, but you are not using the as operator to perform the casts, so the compiler doesn't generate any code to check if the casts succeed at runtime Commented Apr 3, 2018 at 22:34
  • 1
    What does ShowMessage(image1.Picture.Graphic.ClassName); tell you? Commented Apr 4, 2018 at 0:11
  • It may mean that I don't understand enough about what I'm doing on this. (do very little with images). It's telling me that it's a TdxSmartImage. No idea why it thinks that this is some sort of DevExpress(?) image since there are no remaining devExpress controls in this project, and I recreated the gif with Camtasia and then switched to loading it at runtime. Commented Apr 4, 2018 at 1:15
  • @Rudy: I don't think I knew enough to ask the question well, but I think the comments here are reflecting that there is something different going on here than in the previous question. Commented Apr 4, 2018 at 1:17
  • 2
    @Eric clearly you have another library in your project that is overwriting registration of the .gif file extension in TPicture so TdxSmartImage gets priority over TGIFImage. So, either remove that library, or create your own TGIFImage object at runtime and Assign() it to image1.Picture instead of calling image1.Picture.LoadFromFile(). Commented Apr 4, 2018 at 4:32

2 Answers 2

4

Using the various responses above, I was able to come up with this approach that worked;

procedure TForm1.FormCreate(Sender: TObject); var aGIF:TGIFImage; sFile: string; begin try ... aGIF := TGIFImage.Create; aGIF.LoadFromFile(sfile); aGIF.Animate := true; image1.Picture.Graphic := aGIF; except ... 
Sign up to request clarification or add additional context in comments.

1 Comment

You should wrap the aGIF object in a try..finally block, as you need to Free it regardless of whether an exception is thrown or not. The Graphic property setter will create its own TGIFImage object that has a copy of aGIF's data, so you have to call aGIF.Free afterwards to avoid a memory leak.
3

You have a third party library that has replaced the TPicture property editor. The editor is creating the library's own gif implementation class but apparently it does not support animated images.

If you want to restore default design time behavior, you have to uninstall the property editor. For a one time override, after loading your picture, editing the dfm file to change the picture's class name and editing the pas file to change the required unit name might also work (which I'm not sure).

At runtime it's easier to use the class you want. If the unit responsible for gif images in the third party library is linked, unregister that first.

TPicture.UnRegisterGraphicClass(TdxSmartImage); Image1.Picture.LoadFromFile('...'); (Image1.Picture.Graphic as TGIFImage).Animate := True; 

If not, you should be able to load the image as a TGifImage without any problems.

4 Comments

thanks much. Your various comments helped me figure out the solution below that ended up working.
@Eric - You're welcome. I wonder if you tried the solution in the answer. I'm curious if it worked for you or not.
I didn't try it as written because the bit that I was writing in this test app is going into a much larger library. I was leery of UnRegisterGraphicClass because I wasn't sure how this might affect other devExpress controls in the library. You turned me on to the need to explictly cast the loaded image as a gif, butthe approach I took below struck me as being less risky to other controls.
Fair enough, thanks for explaining. There's nothing wrong with accepting your own answer, it's a fine solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.