读书人

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

发布时间: 2012-10-23 12:12:22 作者: rapoo

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

gif.h

class CGIFImage : public CStatic{// Constructionpublic:CGIFImage();void LoadGIF(WCHAR *);void Pause();void Resume();int m_state;// Attributesprivate:struct _sTHPar {Image *m_Img;PropertyItem *m_item;int m_Count;HWND m_hWnd;}sThPar;Image *m_Img;DWORD m_ThreadId;public:// Operationspublic:// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CGIFImage)//}}AFX_VIRTUAL// Implementationpublic:virtual ~CGIFImage();// Generated message map functionsprotected://{{AFX_MSG(CGIFImage)afx_msg void OnPaint();//}}AFX_MSGstatic 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_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CGIFImage message handlersvoid CGIFImage::OnPaint() {CPaintDC dc(this); // device context for painting// TODO: Add your message handler code hereif(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;}}


该控件继承cstatic,用gdi+和多线程实现,在多线程里实现gif动画的绘制,这样不闪不卡,实时高效。

文章有不足之处,还望大家多多指正。

读书人网 >C++

热点推荐