EVC编程点滴-GIF动画显示类
Posted 91program
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EVC编程点滴-GIF动画显示类相关的知识,希望对你有一定的参考价值。
此功能在我这个项目中,主要是显示让用户等待的提示。如开机过程、待机界面调用一个系统应用的过程、还有就是操作大尺寸图片的过程。 刚开始是用自定义的一个窗体来提示用户的,功能也可以实现,但美观度不够。所以才花了一定时间,对网上这个类进行研究。最终成功应用于项目中。 这个类的实现,主要是参考网上一个名为CGif89a类的实现。 此类在EVC4工程中可以正常使用。 索引: 1) GIF显示类头文件 2) GIF显示类的实现 3) 调用CGIFShow类示例 (1) 定义全局变量 (2) 在窗体的WM_CREATE消息处理中初始化CGIFShow类的实例 (3) GIF动画显示 (4) 最后记得清理内存 =======================================
1 1) GIF显示类头文件 2 //////GIFShow.h//////// 3 #ifndef GIFSHOW_H 4 #define GIFSHOW_H 5 #define DISPOSAL_NO 0 6 #define DISPOSAL_NOT 4 7 #define DISPOSAL_RESTBACK 8 8 #define DISPOSAL_RESTORE 12 9 typedef struct 10 { 11 BYTE bit; 12 WORD previouscode; 13 WORD nextcode; 14 }GIFTABLE; 15 16 class CGIFShow 17 { 18 private: 19 HDC m_hWndHDC; 20 bool m_bPause; 21 BOOL m_bAutoStart; 22 BOOL m_bEmbed; 23 BYTE m_cCurentByte,m_cPackedField; 24 UINT m_uBitSize,m_uPrimaryBitSize; 25 UINT m_uRemain,m_uReadByte,m_uBlockSize; 26 int m_iWidth,m_iHeight; 27 int m_iTop,m_iLeft; 28 int m_iFinishCode,m_iResetCode; 29 int m_iPass,m_iRow; 30 int m_iWidth1; 31 int m_iBackgroundColor; 32 int m_iGifSize; 33 int m_x,m_y; 34 int m_iGlobalColorSize; 35 int m_iDisposalMethod; 36 BOOL m_bTransparentIndex; 37 int m_iTransparentIndex; 38 int m_iDelayTime; 39 int m_iTotalReadByte; 40 int m_iMaxByte; 41 DWORD m_dwSpeed; 42 COLORREF m_TransparentColor; 43 HDC m_hDC; 44 BYTE* m_pcGlobalColorTable; 45 BYTE* m_pcBitmap; 46 BYTE* m_pcGif; 47 BYTE* m_pcGifTrack; 48 BOOL m_bGlass; 49 volatile int m_EndRun; 50 HBITMAP m_hRedrawBitmap; 51 int m_iGifWidth,m_iGifHeight; 52 volatile BOOL m_bLockBitmap; 53 TCHAR filename[_MAX_PATH]; 54 int flag; 55 BOOL m_bRunMode; 56 BOOL m_bAutoSize1; 57 int m_nPosX; 58 int m_nPosY; 59 public: 60 CGIFShow(HDC pWnd); 61 ~CGIFShow(); 62 void Play(); 63 void Pause(bool status);///暂停运行 64 void Stop(); 65 void SetPosition(int x,int y); 66 BOOL Play1(void); 67 BOOL Load(LPCTSTR filename); 68 HBITMAP FirstImage(void); 69 HBITMAP NextImage(void); 70 HBITMAP TakeIt(void); 71 HBITMAP DIBTohBitmap(HDC hDC,LPSTR lpSrcDIB); 72 void Output(BYTE bit) 73 { 74 int tmp; 75 if(m_cPackedField&0x40) 76 { 77 if(m_x==m_iWidth) 78 { 79 m_x=0; 80 if(m_iPass==1)m_iRow+=8; 81 if(m_iPass==2)m_iRow+=8; 82 if(m_iPass==3)m_iRow+=4; 83 if(m_iPass==4)m_iRow+=2; 84 if(m_iRow>=m_iHeight){m_iPass+=1;m_iRow=16>>m_iPass;} 85 } 86 tmp=m_iRow*m_iWidth1+m_x; 87 m_pcBitmap[tmp]=bit; 88 m_x++; 89 } 90 else 91 { 92 if(m_x==m_iWidth){m_x=0;m_y++;} 93 tmp=m_y*m_iWidth1+m_x; 94 m_x++; 95 } 96 if(tmp>m_iMaxByte)return; 97 m_pcBitmap[tmp]=bit; 98 } 99 BYTE GetByte(void) 100 { 101 if(m_uReadByte>=m_uBlockSize) 102 { 103 m_uBlockSize=*m_pcGifTrack++; 104 m_uReadByte=0; 105 m_iTotalReadByte+=m_uBlockSize+1; 106 if(m_iTotalReadByte>m_iGifSize){m_iTotalReadByte-=m_uBlockSize+1;return 0xFF;} 107 if(m_uBlockSize==0){m_pcGifTrack--;m_iTotalReadByte--;return 0xFF;} 108 } 109 m_uReadByte++; 110 return *m_pcGifTrack++; 111 } 112 WORD GetCode(void) 113 { 114 UINT tmp1; 115 BYTE tmp; 116 tmp=1; 117 if(m_uRemain>=m_uBitSize) 118 { 119 tmp<<=m_uBitSize; 120 tmp--; 121 tmp1=m_cCurentByte&tmp; 122 m_cCurentByte>>=m_uBitSize; 123 m_uRemain-=m_uBitSize; 124 } 125 else 126 { 127 tmp<<=m_uRemain; 128 tmp--; 129 tmp1=m_cCurentByte; 130 m_cCurentByte=GetByte(); 131 tmp=1; 132 if(8>=(m_uBitSize-m_uRemain)) 133 { 134 tmp<<=(m_uBitSize-m_uRemain); 135 tmp--; 136 tmp1=(((UINT)(m_cCurentByte&tmp))<<m_uRemain)+tmp1; 137 m_cCurentByte>>=(m_uBitSize-m_uRemain); 138 m_uRemain=8-(m_uBitSize-m_uRemain); 139 } 140 else 141 { 142 tmp1=(((UINT)(m_cCurentByte))<<m_uRemain)+tmp1; 143 m_cCurentByte=GetByte(); 144 tmp<<=m_uBitSize-m_uRemain-8; 145 tmp--; 146 tmp1=(((UINT)(m_cCurentByte&tmp))<<(m_uRemain+8))+tmp1; 147 m_cCurentByte>>=m_uBitSize-m_uRemain-8; 148 m_uRemain=8-(m_uBitSize-m_uRemain-8); 149 } 150 } 151 return tmp1; 152 } 153 }; 154 #endif 155 ======================================= 156 157 #include "stdafx.h" 158 #include "GifShow.h" 159 DWORD WINAPI ThreadFunc(CGIFShow* ptr) 160 { 161 ptr->Play1(); 162 return 0; 163 } 164 void CGIFShow::Play() 165 { 166 HANDLE hThread; 167 DWORD ThreadId; 168 if(m_hWndHDC==0)return ; 169 if(m_pcGif==0)return; 170 if(m_EndRun==5)return; 171 m_pcGifTrack=m_pcGif; 172 m_iTotalReadByte=0; 173 m_EndRun=5; 174 hThread=CreateThread(NULL,0,(unsigned long(_stdcall*)(void*))ThreadFunc,this,0,&ThreadId); 175 CloseHandle(hThread); 176 return; 177 } 178 BOOL CGIFShow::Play1(void) 179 { 180 HDC hDC,hMemDC,hMemDC1,hPauseMemDC; 181 HBITMAP hOldBitmap,hOldBitmap1,hBitmap,hPreviousBitmap,hPauseBitmap; 182 DWORD systimer1,systimer2,speed; 183 BOOL PauseShow = FALSE; 184 hDC = m_hWndHDC; 185 hMemDC = ::CreateCompatibleDC(hDC); 186 hMemDC1 = ::CreateCompatibleDC(hDC); 187 hPauseMemDC = ::CreateCompatibleDC(hDC); 188 m_hDC = hDC; 189 hPreviousBitmap = 0; 190 while(m_bLockBitmap) 191 { 192 } 193 m_bLockBitmap = TRUE; 194 if(m_hRedrawBitmap != 0) 195 { 196 DeleteObject(m_hRedrawBitmap); 197 } 198 m_hRedrawBitmap = ::CreateCompatibleBitmap(hDC,m_iGifWidth,m_iGifHeight); 199 hOldBitmap1 = (HBITMAP)SelectObject(hMemDC1,m_hRedrawBitmap); 200 hPauseBitmap = ::CreateCompatibleBitmap(hDC,m_iGifWidth,m_iGifHeight); 201 SelectObject(hPauseMemDC,hPauseBitmap); 202 203 ::BitBlt(hMemDC1,0,0,m_iGifWidth,m_iGifHeight,hDC,m_nPosX,m_nPosY,SRCCOPY); 204 SelectObject(hMemDC1,hOldBitmap1); 205 m_bLockBitmap = FALSE; 206 m_iDisposalMethod = DISPOSAL_NOT; 207 while(1 != m_EndRun) 208 { 209 systimer2=systimer1 = GetTickCount(); 210 while(m_bLockBitmap) 211 { 212 } 213 m_bLockBitmap = TRUE; 214 hOldBitmap1 = (HBITMAP)SelectObject(hMemDC1,m_hRedrawBitmap); 215 216 switch(m_iDisposalMethod) 217 { 218 case DISPOSAL_NO: 219 break; 220 case DISPOSAL_NOT: 221 break; 222 case DISPOSAL_RESTBACK: 223 case DISPOSAL_RESTORE: 224 hOldBitmap = (HBITMAP)SelectObject(hMemDC,hPreviousBitmap); 225 ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hMemDC,0,0,SRCCOPY); 226 SelectObject(hMemDC,hOldBitmap); 227 DeleteObject(hPreviousBitmap); 228 hPreviousBitmap = 0; 229 break; 230 } 231 m_iDisposalMethod = DISPOSAL_NO; 232 233 if(!PauseShow) 234 { 235 hBitmap=NextImage(); 236 switch(m_iDisposalMethod) 237 { 238 case DISPOSAL_NO: 239 break; 240 case DISPOSAL_NOT: 241 break; 242 case DISPOSAL_RESTBACK: 243 case DISPOSAL_RESTORE: 244 hPreviousBitmap = ::CreateCompatibleBitmap(hDC,m_iWidth,m_iHeight); 245 hOldBitmap = (HBITMAP)SelectObject(hMemDC,hPreviousBitmap); 246 ::BitBlt(hMemDC,0,0,m_iWidth,m_iHeight,hMemDC1,m_iLeft,m_iTop,SRCCOPY); 247 SelectObject(hMemDC,hOldBitmap); 248 break; 249 } 250 hOldBitmap = (HBITMAP)SelectObject(hMemDC,hBitmap); 251 if(m_bTransparentIndex) 252 { 253 HBITMAP bmAndBack, bmAndObject; 254 HBITMAP bmBackOld, bmObjectOld; 255 HDC hdcBack, hdcObject; 256 COLORREF cColor; 257 hdcBack = ::CreateCompatibleDC(hDC); 258 hdcObject = ::CreateCompatibleDC(hDC); 259 bmAndBack = CreateBitmap(m_iWidth,m_iHeight,1,1,NULL); 260 bmAndObject = CreateBitmap(m_iWidth,m_iHeight,1,1,NULL); 261 bmBackOld = (HBITMAP)SelectObject(hdcBack,bmAndBack); 262 bmObjectOld = (HBITMAP)SelectObject(hdcObject,bmAndObject); 263 cColor = SetBkColor(hMemDC,m_TransparentColor); 264 ::BitBlt(hdcObject,0,0,m_iWidth,m_iHeight,hMemDC,0,0,SRCCOPY); 265 SetBkColor(hMemDC,cColor); 266 ::BitBlt(hdcBack,0,0,m_iWidth,m_iHeight,hdcObject,0,0,NOTSRCCOPY); 267 ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hdcObject,0,0,SRCAND); 268 ::BitBlt(hMemDC,0,0,m_iWidth,m_iHeight,hdcBack,0,0,SRCAND); 269 ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hMemDC,0,0,SRCPAINT); 270 DeleteObject(SelectObject(hdcBack,bmBackOld)); 271 DeleteObject(SelectObject(hdcObject,bmObjectOld)); 272 DeleteDC(hdcBack); 273 DeleteDC(hdcObject); 274 } 275 else 276 { 277 ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hMemDC,0,0,SRCCOPY); 278 } 279 SelectObject(hMemDC,hOldBitmap); 280 DeleteObject(hBitmap); 281 ::BitBlt(hDC,m_nPosX,m_nPosY,m_iGifWidth,m_iGifHeight,hMemDC1,0,0,SRCCOPY); 282 ::BitBlt(hPauseMemDC,0,0,m_iGifWidth,m_iGifHeight,hMemDC1,0,0,SRCCOPY); 283 } 284 else 285 { 286 ::BitBlt(hDC,m_nPosX,m_nPosY,m_iGifWidth,m_iGifHeight,hPauseMemDC,0,0,SRCCOPY); 287 } 288 SelectObject(hMemDC1,hOldBitmap1); 289 m_bLockBitmap = FALSE; 290 if(0 != m_iDelayTime) 291 speed = m_iDelayTime * 10; 292 else 293 speed=m_dwSpeed; 294 while((1 != m_EndRun)&&(speed > systimer2 - systimer1)) 295 { 296 Sleep(10); 297 systimer2 = GetTickCount(); 298 } 299 PauseShow = m_bPause; 300 } 301 if(hPreviousBitmap != 0) 302 DeleteObject(hPreviousBitmap); 303 DeleteDC(hMemDC); 304 DeleteDC(hMemDC1); 305 //::ReleaseDC(hDC); 306 m_EndRun = 2; 307 return TRUE; 308 } 309 310 void CGIFShow::Stop() 311 { 312 if(m_EndRun != 5) 313 return; 314 m_EndRun = 1; 315 while(m_EndRun != 2) 316 { 317 } 318 return; 319 } 320 CGIFShow::CGIFShow(HDC pWnd) 321 { 322 m_hWndHDC=pWnd; 323 m_bPause=FALSE; 324 m_bAutoStart=TRUE; 325 m_bAutoSize1=TRUE; 326 m_bEmbed=FALSE; 327 m_pcGlobalColorTable=0; 328 m_pcGif=0; 329 m_iGifSize=0; 330 m_iGlobalColorSize=0; 331 m_bTransparentIndex=FALSE; 332 m_iDelayTime=0; 333 m_EndRun=0; 334 m_dwSpeed=50; 335 m_hRedrawBitmap=0; 336 m_bLockBitmap=FALSE; 337 flag=0; 338 m_nPosX=0; 339 m_nPosY=0; 340 wcscpy(filename,_T("")); 341 m_bRunMode=1; 342 m_bGlass=FALSE; 343 } 344 CGIFShow::~CGIFShow(void) 345 { 346 Stop(); 347 if(m_hRedrawBitmap!=0) 348 DeleteObject(m_hRedrawBitmap); 349 if(m_pcGlobalColorTable!=NULL) 350 delete[] m_pcGlobalColorTable; 351 if(m_pcGif!=NULL) 352 delete[] m_pcGif; 353 } 354 BOOL CGIFShow::Load(LPCTSTR filename) 355 { 356 HANDLE hFile; 357 DWORD size,size1,readbyte; 358 BYTE temp[13]; 359 if(m_bEmbed) 360 return FALSE; 361 362 Stop(); 363 if(m_pcGlobalColorTable!=NULL) 364 delete[] m_pcGlobalColorTable; 365 if(m_pcGif!=NULL) 366 delete[] m_pcGif; 367 if(m_hRedrawBitmap!=0) 368 { 369 DeleteObject(m_hRedrawBitmap); 370 m_hRedrawBitmap=0; 371 } 372 m_pcGlobalColorTable=m_pcGif=0; 373 m_iTotalReadByte=0; 374 m_iGifSize=m_iGlobalColorSize=0; 375 376 hFile = CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 377 if(INVALID_HANDLE_VALUE==hFile) 378 return FALSE; 379 size=GetFileSize(hFile,&size1); 380 if(size==0xFFFFFFFF) 381 { 382 CloseHandle(hFile); 383 return FALSE; 384 } 385 ReadFile(hFile,temp,13,&readbyte,NULL); 386 if((readbyte!=13)||((temp[0]!=‘G‘)||(temp[1]!=‘I‘)|| 387 (temp[2]!=‘F‘)||(temp[3]!=‘8‘)||((temp[4]!=‘7‘)&& 388 (temp[4]!=‘9‘))||(temp[5]!=‘a‘))) 389 { 390 CloseHandle(hFile); 391 return FALSE; 392 } 393 394 m_iGifWidth=*(temp+6); 395 m_iGifHeight=*(temp+8); 396 m_iBackgroundColor=temp[11]; 397 if(temp[10]&0x80) 398 { 399 m_iGlobalColorSize=0x01<<((temp[10]&0x07)+1); 400 m_pcGlobalColorTable=new BYTE[3*m_iGlobalColorSize]; 401 ReadFile(hFile,m_pcGlobalColorTable,3*m_iGlobalColorSize,&readbyte,NULL); 402 if(readbyte!=(DWORD)3*m_iGlobalColorSize) 403 { 404 delete[] m_pcGlobalColorTable; 405 m_pcGlobalColorTable=0; 406 m_iGlobalColorSize=0; 407 CloseHandle(hFile); 408 return FALSE; 409 } 410 } 411 m_iGifSize=size-3*m_iGlobalColorSize-12; 412 m_pcGifTrack=m_pcGif=new BYTE[m_iGifSize]; 413 ReadFile(hFile,m_pcGif,m_iGifSize,&readbyte,NULL); 414 CloseHandle(hFile); 415 return TRUE; 416 } 417 HBITMAP CGIFShow::NextImage(void) 418 { 419 if(m_pcGif==NULL)return 0; 420 421 label2: if(m_iTotalReadByte>m_iGifSize) 422 { 423 m_pcGifTrack=m_pcGif; 424 m_iTotalReadByte=0;return 0; 425 } 426 m_iTotalReadByte++; 427 switch(*m_pcGifTrack++) 428 { 429 case 0x2C: 430 return TakeIt(); 431 break; 432 case 0x21: 433 BYTE cSize; 434 m_iTotalReadByte++; 435 switch(*m_pcGifTrack++) 436 { 437 case 0xF9: 438 m_pcGifTrack++;//block size 439 m_iDisposalMethod=(*m_pcGifTrack)&28; 440 m_bTransparentIndex=(*m_pcGifTrack++)&1; 441 m_iDelayTime=*m_pcGifTrack; 442 m_pcGifTrack+=2; 443 m_iTransparentIndex=*m_pcGifTrack++; 444 m_iTotalReadByte+=5; 445 break; 446 case 0xFE: 447 while((cSize=*m_pcGifTrack)!=0) 448 { 449 m_pcGifTrack+=cSize+1; 450 m_iTotalReadByte+=cSize+1; 451 if(m_iTotalReadByte>m_iGifSize) 452 return 0; 453 } 454 break; 455 case 0x01: 456 m_pcGifTrack+=13; 457 m_iTotalReadByte+=13; 458 while((cSize=*m_pcGifTrack)!=0) 459 { 460 m_pcGifTrack+=cSize+1; 461 m_iTotalReadByte+=cSize+1; 462 if(m_iTotalReadByte>m_iGifSize) 463 return 0; 464 } 465 break; 466 case 0xFF: 467 m_pcGifTrack+=12; 468 m_iTotalReadByte+=12; 469 while((cSize=*m_pcGifTrack)!=0) 470 { 471 m_pcGifTrack+=cSize+1; 472 m_iTotalReadByte+=cSize+1; 473 if(m_iTotalReadByte>m_iGifSize) 474 return 0; 475 } 476 break; 477 default: 478 return FALSE; 479 } 480 m_pcGifTrack++; 481 m_iTotalReadByte++; 482 if(m_iTotalReadByte>m_iGifSize) 483 return 以上是关于EVC编程点滴-GIF动画显示类的主要内容,如果未能解决你的问题,请参考以下文章自己定义View时,用到Paint Canvas的一些温故,简单的帧动画(动画一 ,"掏粪男孩Gif"顺便再提提onWindowFocusChanged)(代码片段