www.pudn.com > PictureEx_demo.rar > PictureEx.h


////////////////////////////////////////////////////////////////////// 
// PictureEx.cpp: implementation of the CPictureEx class. 
// 
// Picture displaying control with support for the following formats: 
// GIF (including animated GIF87a and GIF89a), JPEG, BMP, WMF, ICO, CUR 
//  
// Written by Oleg Bykov (oleg_bykoff@rsdn.ru) 
// Copyright (c) 2001 
// 
// To use CPictureEx, follow these steps: 
//   - place a static control on your dialog (either a text or a bitmap) 
//   - change its identifier to something else (e.g. IDC_MYPIC) 
//   - associate a CStatic with it using ClassWizard 
//   - in your dialog's header file replace CStatic with CPictureEx 
//     (don't forget to #include "PictureEx.h" and add  
//     PictureEx.h and PictureEx.cpp to your project) 
//   - call one of the overloaded CPictureEx::Load() functions somewhere 
//     (OnInitDialog is a good place to start) 
//   - if the preceding Load() succeeded call Draw() 
//   
// You can also add the control by defining a member variable of type  
// CPictureEx, calling CPictureEx::Create (derived from CStatic), then  
// CPictureEx::Load and CPictureEx::Draw. 
// 
// By default, the control initializes its background to COLOR_3DFACE 
// (see CPictureEx::PrepareDC()). You can change the background by 
// calling CPictureEx::SetBkColor(COLORREF) after CPictureEx::Load(). 
// 
// I decided to leave in the class the functions to write separate frames from  
// animated GIF to disk. If you want to use them, uncomment #define GIF_TRACING  
// and an appropriate section in CPictureEx::Load(HGLOBAL, DWORD). These functions  
// won't be compiled and linked to your project unless you uncomment #define GIF_TRACING, 
// so you don't have to worry. 
//  
// Warning: this code hasn't been subject to a heavy testing, so 
// use it on your own risk. The author accepts no liability for the  
// possible damage caused by this code. 
// 
// Version 1.0  7 Aug 2001 
//              Initial release 
// 
// Version 1.1  6 Sept 2001 
//              ATL version of the class 
// 
// Version 1.2  14 Oct 2001 
//              - Fixed a problem with loading GIFs from resources 
//                in MFC-version of the class for multi-modules apps. 
//                Thanks to Ruben Avila-Carretero for finding this out. 
// 
//              - Got rid of waitable timer in ThreadAnimation() 
//                Now CPictureEx[Wnd] works in Win95 too. 
//                Thanks to Alex Egiazarov and Wayne King for the idea. 
// 
//              - Fixed a visual glitch of using SetBkColor. 
//                Thanks to Kwangjin Lee for finding this out. 
// 
// Version 1.3  10 Nov 2001 
//              - Fixed a DC leak. One DC leaked per each UnLoad() 
//                (forgot to put a ReleaseDC() in the end of  
//                CPictureExWnd::PrepareDC() function). 
// 
//              - Now it is possible to set a clipping rectangle using 
//                CPictureEx[Wnd]::SetPaintRect(const LPRECT) function. 
//                The LPRECT parameter tells the class what portion of 
//                a picture should it display. If the clipping rect is  
//                not set, the whole picture is shown. 
//                Thanks to Fabrice Rodriguez for the idea. 
// 
//              - Added support for Stop/Draw. Now you can Stop() an 
//                animated GIF, then Draw() it again, it will continue 
//                animation from the frame it was stopped on. You can  
//                also know if a GIF is currently playing with the  
//                IsPlaying() function. 
//              
//              - Got rid of math.h and made m_bExitThread volatile.  
//                Thanks to Piotr Sawicki for the suggestion. 
// 
////////////////////////////////////////////////////////////////////// 
 
#if !defined(AFX_PICTUREEX_H__0EFE5DE0_7B68_4DB7_8B34_5DC634948438__INCLUDED_) 
#define AFX_PICTUREEX_H__0EFE5DE0_7B68_4DB7_8B34_5DC634948438__INCLUDED_ 
 
#if _MSC_VER > 1000 
#pragma once 
#endif // _MSC_VER > 1000 
 
#include  
 
//#define GIF_TRACING  // uncomment it if you want detailed TRACEs 
 
class CPictureEx : public CStatic 
{ 
public: 
 
struct TFrame    // structure that keeps a single frame info 
{ 
	IPicture *m_pPicture;  // pointer to the interface used for drawing 
	SIZE     m_frameSize; 
	SIZE     m_frameOffset; 
	UINT     m_nDelay;     // delay (in 1/100s of a second) 
	UINT     m_nDisposal;  // disposal method 
}; 
 
#pragma pack(1)   // turn byte alignment on 
 
enum GIFBlockTypes 
{ 
	BLOCK_UNKNOWN, 
	BLOCK_APPEXT, 
	BLOCK_COMMEXT, 
	BLOCK_CONTROLEXT, 
	BLOCK_PLAINTEXT, 
	BLOCK_IMAGE, 
	BLOCK_TRAILER 
}; 
 
enum ControlExtValues // graphic control extension packed field values 
{ 
	GCX_PACKED_DISPOSAL,  // disposal method 
	GCX_PACKED_USERINPUT, 
	GCX_PACKED_TRANSPCOLOR 
}; 
 
enum LSDPackedValues  // logical screen descriptor packed field values 
{ 
	LSD_PACKED_GLOBALCT, 
	LSD_PACKED_CRESOLUTION, 
	LSD_PACKED_SORT, 
	LSD_PACKED_GLOBALCTSIZE 
}; 
 
enum IDPackedValues   // image descriptor packed field values 
{ 
	ID_PACKED_LOCALCT, 
	ID_PACKED_INTERLACE, 
	ID_PACKED_SORT, 
	ID_PACKED_LOCALCTSIZE 
}; 
 
struct TGIFHeader       // GIF header   
{ 
	char m_cSignature[3]; // Signature - Identifies the GIF Data Stream 
						  // This field contains the fixed value 'GIF' 
	char m_cVersion[3];	// Version number. May be one of the following: 
						// "87a" or "89a" 
}; 
 
struct TGIFLSDescriptor // Logical Screen Descriptor 
{ 
	WORD m_wWidth;	// 2 bytes. Logical screen width 
	WORD m_wHeight; // 2 bytes. Logical screen height 
 
	unsigned char m_cPacked;      // packed field	 
 
	unsigned char m_cBkIndex;     // 1 byte. Background color index 
	unsigned char m_cPixelAspect; // 1 byte. Pixel aspect ratio 
	inline int GetPackedValue(enum LSDPackedValues Value); 
}; 
 
struct TGIFAppExtension // application extension block 
{ 
	unsigned char m_cExtIntroducer; // extension introducer (0x21) 
	unsigned char m_cExtLabel; // app. extension label (0xFF) 
	unsigned char m_cBlockSize; // fixed value of 11 
	char m_cAppIdentifier[8];   // application identifier 
	char m_cAppAuth[3];  // application authentication code 
}; 
 
struct TGIFControlExt // graphic control extension block 
{ 
	unsigned char m_cExtIntroducer; // extension introducer (0x21) 
	unsigned char m_cControlLabel;  // control extension label (0xF9) 
	unsigned char m_cBlockSize; // fixed value of 4 
	unsigned char m_cPacked;    // packed field 
	WORD m_wDelayTime;	// delay time 
	unsigned char m_cTColorIndex; // transparent color index 
	unsigned char m_cBlockTerm;   // block terminator (0x00) 
public: 
	inline int GetPackedValue(enum ControlExtValues Value); 
}; 
 
struct TGIFCommentExt  // comment extension block 
{ 
	unsigned char m_cExtIntroducer; // extension introducer (0x21) 
	unsigned char m_cCommentLabel;  // comment extension label (0xFE) 
}; 
 
struct TGIFPlainTextExt // plain text extension block 
{ 
	unsigned char m_cExtIntroducer;  // extension introducer (0x21) 
	unsigned char m_cPlainTextLabel; // text extension label (0x01) 
	unsigned char m_cBlockSize; // fixed value of 12 
	WORD m_wLeftPos;    // text grid left position 
	WORD m_wTopPos;     // text grid top position 
	WORD m_wGridWidth;  // text grid width 
	WORD m_wGridHeight; // text grid height 
	unsigned char m_cCellWidth;  // character cell width 
	unsigned char m_cCellHeight; // character cell height 
	unsigned char m_cFgColor; // text foreground color index 
	unsigned char m_cBkColor; // text background color index 
}; 
 
struct TGIFImageDescriptor // image descriptor block 
{ 
	unsigned char m_cImageSeparator; // image separator byte (0x2C) 
	WORD m_wLeftPos; // image left position 
	WORD m_wTopPos;  // image top position 
	WORD m_wWidth;   // image width 
	WORD m_wHeight;  // image height 
	unsigned char m_cPacked; // packed field 
	inline int GetPackedValue(enum IDPackedValues Value); 
}; 
 
#pragma pack() // turn byte alignment off 
 
public: 
	BOOL GetPaintRect(RECT *lpRect); 
	BOOL SetPaintRect(const RECT *lpRect); 
	CPictureEx(); 
	virtual ~CPictureEx(); 
	void Stop();   // stops animation 
	void UnLoad(); // stops animation plus releases all resources 
 
	BOOL IsGIF() const; 
	BOOL IsPlaying() const; 
	BOOL IsAnimatedGIF() const; 
	SIZE GetSize() const; 
	int GetFrameCount() const; 
	COLORREF GetBkColor() const; 
	void SetBkColor(COLORREF clr); 
 
	// draws the picture (starts an animation thread if needed) 
	// if an animation was previously stopped by Stop(), 
	// continues it from the last displayed frame 
	BOOL Draw(); 
 
	// loads a picture from a file 
	// i.e. Load(_T("mypic.gif")); 
	BOOL Load(LPCTSTR szFileName); 
 
	// loads a picture from a global memory block (allocated by GlobalAlloc) 
	// Warning: this function DOES NOT free the global memory, pointed to by hGlobal 
	BOOL Load(HGLOBAL hGlobal, DWORD dwSize); 
 
	// loads a picture from a program resource 
	// i.e. Load(MAKEINTRESOURCE(IDR_MYPIC),_T("GIFTYPE")); 
	BOOL Load(LPCTSTR szResourceName,LPCTSTR szResourceType); 
 
protected: 
 
#ifdef GIF_TRACING 
	void EnumGIFBlocks(); 
	void WriteDataOnDisk(CString szFileName, HGLOBAL hData, DWORD dwSize); 
#endif // GIF_TRACING 
 
	RECT m_PaintRect; 
	SIZE m_PictureSize; 
	COLORREF m_clrBackground; 
	UINT m_nCurrFrame; 
	UINT m_nDataSize; 
	UINT m_nCurrOffset; 
	UINT m_nGlobalCTSize; 
	BOOL m_bIsGIF; 
	BOOL m_bIsPlaying; 
	volatile BOOL m_bExitThread; 
	BOOL m_bIsInitialized; 
	HDC m_hMemDC; 
 
	HDC m_hDispMemDC; 
	HBITMAP m_hDispMemBM; 
	HBITMAP m_hDispOldBM; 
 
	HBITMAP m_hBitmap; 
	HBITMAP m_hOldBitmap; 
	HANDLE m_hThread; 
	HANDLE m_hExitEvent; 
	IPicture * m_pPicture; 
	TGIFHeader * m_pGIFHeader; 
	unsigned char * m_pRawData; 
	TGIFLSDescriptor * m_pGIFLSDescriptor; 
	std::vector m_arrFrames; 
 
	void ThreadAnimation(); 
	static UINT WINAPI _ThreadAnimation(LPVOID pParam); 
 
	int GetNextBlockLen() const; 
	BOOL SkipNextBlock(); 
	BOOL SkipNextGraphicBlock(); 
	BOOL PrepareDC(int nWidth, int nHeight); 
	void ResetDataPointer(); 
	enum GIFBlockTypes GetNextBlock() const; 
	UINT GetSubBlocksLen(UINT nStartingOffset) const; 
	HGLOBAL GetNextGraphicBlock(UINT *pBlockLen, UINT *pDelay,  
		SIZE *pBlockSize, SIZE *pBlockOffset, UINT *pDisposal); 
 
	// Generated message map functions 
	//{{AFX_MSG(CPictureEx) 
	afx_msg void OnDestroy(); 
	afx_msg void OnPaint(); 
	//}}AFX_MSG 
	 
	DECLARE_MESSAGE_MAP() 
}; 
 
#endif // !defined(AFX_PICTUREEX_H__0EFE5DE0_7B68_4DB7_8B34_5DC634948438__INCLUDED_)