现在的位置: 首页 > 综合 > 正文

c++编写gif动画现实控件

2018年07月17日 ⁄ 综合 ⁄ 共 3713字 ⁄ 字号 评论关闭

gif.h

class CGIFImage : public CStatic
{
	// Construction
public:
	CGIFImage();
	void LoadGIF(WCHAR *);
	void Pause();
	void Resume();
	int m_state;
	// Attributes
private:
	struct _sTHPar 
	{
		Image *m_Img;
		PropertyItem *m_item;
		int m_Count;
		HWND m_hWnd;
	}sThPar;
	Image *m_Img;
	DWORD m_ThreadId;
	public:
		
		// Operations
	public:
		
		// Overrides
		// ClassWizard generated virtual function overrides
		//{{AFX_VIRTUAL(CGIFImage)
		//}}AFX_VIRTUAL
		
		// Implementation
	public:
		virtual ~CGIFImage();
		
		// Generated message map functions
	protected:
		//{{AFX_MSG(CGIFImage)
		afx_msg void OnPaint();
		//}}AFX_MSG
		static DWORD WINAPI DrawGIF(LPVOID);
		DECLARE_MESSAGE_MAP()
};

gif.cpp

CGIFImage::CGIFImage()
{
	m_ThreadId=0;
	m_Img=0;
	m_state=-1;
}

CGIFImage::~CGIFImage()
{
	if(m_ThreadId)
	{
		::PostThreadMessage(m_ThreadId,WM_GIFSTOP,0,0);
	}
}


BEGIN_MESSAGE_MAP(CGIFImage, CStatic)
//{{AFX_MSG_MAP(CGIFImage)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGIFImage message handlers

void CGIFImage::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	if(m_ThreadId && m_Img)
	{
		RECT rWin;
		GetClientRect(&rWin);
	   RectF rF(rWin.left,rWin.top,rWin.right,rWin.bottom);
		Graphics   gh(dc.m_hDC);   
		gh.DrawImage(m_Img,rF,0,0,m_Img->GetWidth(),m_Img->GetHeight(),UnitPixel);  
	}
	
	// Do not call CStatic::OnPaint() for painting messages
}
void CGIFImage::LoadGIF(WCHAR *wzFile)
{
	if(m_ThreadId)
	{
		::PostThreadMessage(m_ThreadId,WM_GIFSTOP,0,0);
	}
	m_Img=Image::FromFile(wzFile,FALSE);
	UINT count=m_Img->GetFrameDimensionsCount();
	GUID *pDimensionIDs=(GUID*)new GUID[count];  
	m_Img->GetFrameDimensionsList(pDimensionIDs, count);  
	WCHAR strGuid[39];  
	StringFromGUID2(pDimensionIDs[0], strGuid, 39);  
	UINT frameCount=m_Img->GetFrameCount(&pDimensionIDs[0]);  
    delete []pDimensionIDs; 
	UINT   FrameDelayNums=m_Img->GetPropertyItemSize(PropertyTagFrameDelay);  
	PropertyItem *  lpPropertyItem=new  PropertyItem[FrameDelayNums];  
	m_Img->GetPropertyItem(PropertyTagFrameDelay,FrameDelayNums,lpPropertyItem);  
	_sTHPar  *sP=new _sTHPar ;
	sP->m_hWnd=m_hWnd;
	sP->m_Img=m_Img;
	sP->m_Count=frameCount;
	sP->m_item=lpPropertyItem;
	CreateThread(0,0,DrawGIF,sP,0,&m_ThreadId);
	m_state=1;
}
DWORD WINAPI CGIFImage::DrawGIF(LPVOID l)
{
	_sTHPar *par=(_sTHPar*)l;
	int FrameCount=0;
	long lPause=0;
	HDC dc=::GetWindowDC(par->m_hWnd);
	RECT rWin;
	::GetClientRect(par->m_hWnd,&rWin);
	RectF rF(rWin.left,rWin.top,rWin.right,rWin.bottom);
	GUID    Guid = FrameDimensionTime;  
	par->m_Img->SelectActiveFrame(&Guid,FrameCount);  
	Graphics   gh(dc);   
	gh.DrawImage(par->m_Img,rF,0,0,par->m_Img->GetWidth(),par->m_Img->GetHeight(),UnitPixel);  
	DWORD dTick=GetTickCount();
	lPause = ((long*)par->m_item->value)[FrameCount]*10;  
	while(1)
	{
		Sleep(1);
		MSG msg;
		if(PeekMessage(&msg,0,0,0,PM_REMOVE))
		{
			if(msg.message==WM_GIFSTOP)
			{
				::ReleaseDC(par->m_hWnd,dc);
				delete par->m_Img;
				delete[] par->m_item;
				delete par;
				return 0;
			}
		}
		else
		{
			if(par->m_Count>1)
			{
				if(GetTickCount()-dTick>=lPause)
				{
					if ((FrameCount+1)==par->m_Count)  
					{   
						FrameCount=0;  
						par->m_Img->SelectActiveFrame(&Guid,0);  
					}  
					else  
					{  
						par->m_Img->SelectActiveFrame(&Guid,++FrameCount);  
					}  
					Graphics   gh(dc);   
					gh.DrawImage(par->m_Img,rF,0,0,par->m_Img->GetWidth(),par->m_Img->GetHeight(),UnitPixel);   
					lPause = ((long*)par->m_item->value)[FrameCount]*10;  
					dTick=GetTickCount();
				}
			}	
		}
	}
	return 0;
}
void CGIFImage::Pause()
{
	if(m_ThreadId)
	{
		typedef HANDLE  (WINAPI  *OPENTHREAD) (DWORD , BOOL , DWORD ); 
		OPENTHREAD lpfnOpenThread = (OPENTHREAD)GetProcAddress(LoadLibrary("kernel32.dll"),"OpenThread"); 
		HANDLE hThread = lpfnOpenThread(THREAD_ALL_ACCESS, FALSE, m_ThreadId);
		SuspendThread(hThread);
		m_state=0;
	}

}
void CGIFImage::Resume()
{
	if(m_ThreadId)
	{
		typedef HANDLE (WINAPI  *OPENTHREAD) (DWORD , BOOL , DWORD ); 
		OPENTHREAD lpfnOpenThread = (OPENTHREAD)GetProcAddress(LoadLibrary("kernel32.dll"),"OpenThread"); 
		HANDLE hThread = lpfnOpenThread(THREAD_ALL_ACCESS, FALSE, m_ThreadId);
		ResumeThread(hThread);
		m_state=1;
	}
}

转载:http://blog.csdn.net/sx1989827/article/details/8067114

抱歉!评论已关闭.