Introduction
The code provided here will allow animated GIF files to be displayed on Windows within your projects. It does not rely on any library to do this but rather manually scans the GIF to determine its contents, decompresses the image data, and displays it on the window of your choice. By doing this manually, the code has some degree of portability on Win32 systems, allowing the same code to work in both desktop and Pocket PC applications.
Background
Often while coding a project, I have had the need to show some kind of animation, either as a status message to the user or to spice up an attribution dialog. After doing this manually several times using timers and and icons to switch images, I needed a better, more flexible way. The popularity of the GIF image format and its ability to display animations made it a prime candidate to store the animations for my code.
Using the Code
The class that you will interact with is gifDisplayer
; it has four methods to interact with the desired GIF file.
BOOL loadGif(CString filePath,
HDC hDCin,
BOOL animate,
HWND hWnd,
int multiplySizeBy,
int Xoffset,
int Yoffset);
BOOL loadGif(unsigned char* bufferIn,
unsigned long lengthIn,
HDC hDCin,
BOOL animate,
HWND hWnd,
int multiplySizeBy,
int Xoffset,
int Yoffset);
BOOL displayGif();
void unloadGif();
Multiple objects of this class can be used simultaneously. Multiple animations can be drawn to the same window simultaneously. What is not supported are multiple animations being stacked in the same place. If that is done, the transparency will be lost.
To use the class, some static members will need to be set up:
#include "stdafx.h"
#include "gifDisplayer.h"
HANDLE gifDisplayer::hAccessMutex=0;
HANDLE gifDisplayer::hTimingThread=0;
int gifDisplayer::countOfObjects=0;
gifDisplayer* gifDisplayer::gifDisplayerObjectArray[MAX_SURFACES];
This is done from the main .cpp file or is included in a file from there.
You can instantiate objects from the class after that, as normally would be done:
gifDisplayer* gr=new gifDisplayer(100000);
gifDisplayer* gr2=new gifDisplayer(100000);
gifDisplayer* gr3=new gifDisplayer(100000);
It is important to be sure your window has been drawn properly before calling loadGif(...)
or displayGif()
. This is because in order to allow the GIF to seem transparent on your window, the contents of the window will be copied to form the base over which the GIF will show. To do this, I post a message to the window after the window has been created, allowing a delay for the initial drawing to occur.
switch (message)
{
case SETUP_MESSAGE:
{
SetCursor(LoadCursor (NULL,IDC_WAIT));
gr->loadGif(gifPath, surfaceDC, TRUE, hSurfaceWindow, 1, 50, 100);
gr->displayGif();
gr2->loadGif(gifPath2,
surfaceDC,
TRUE,
hSurfaceWindow,1,150,200);
gr2->displayGif();
gr3->loadGif(gifPath3,
surfaceDC,
TRUE,
hSurfaceWindow,2,0,0);
gr3->displayGif();
SetCursor(0);
}
break;
Remember to call unloadGif()
on each object before ending your program.
The gifDisplayer
class inherits from a number of other classes I wrote. You only need to include them in your project as shown in the demos. I split the functionality up this way because the scanning, decompressing, and displaying are distinctly different parts that are better suited to being independent. Note that I use MFC CString
s and CObjectArray
s in my code. The projects themselves are Win32, and not MFC projects. Some changes need to be made in the project settings and included files to let this work in Win32 code. It would be easy enough to replace these classes with your own if you want to get rid of MFC all together.
Points of Interest
All the code in this project is based on the document "LZWand GIF explained" by Steve Blackstock and on the CompuServe GIF standard. Although these documents do not contain any C++ code, they are an accurate description of what a GIF is.
History
- Submitted: 24 March 2008.