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 0; 484 goto label2; 485 break; 486 case 0x3B: 487 m_pcGifTrack=m_pcGif; 488 m_iTotalReadByte=0; 489 goto label2; 490 case 0: 491 goto label2; 492 default: 493 return FALSE; 494 } 495 } 496 HBITMAP CGIFShow::TakeIt(void) 497 { 498 UINT uLocalColorTableSize; 499 WORD code,oldcode,code1; 500 int iFinishCode,iResetCode; 501 int iPrimaryTableSize,iTableSize; 502 BITMAPINFOHEADER *bitmapheader; 503 BYTE *pcColorTable; 504 BYTE *pcInfo; 505 GIFTABLE *pcGifTable; 506 HBITMAP hBitmap; 507 m_iLeft=*m_pcGifTrack; 508 m_pcGifTrack+=2; 509 m_iTop=*m_pcGifTrack; 510 m_pcGifTrack+=2; 511 m_iWidth=*m_pcGifTrack; 512 m_pcGifTrack+=2; 513 m_iWidth1=((m_iWidth-1)|0x3)+1; 514 m_iHeight=*m_pcGifTrack; 515 m_pcGifTrack+=2; 516 m_cPackedField=*m_pcGifTrack++; 517 m_iTotalReadByte+=9; 518 m_iMaxByte=m_iWidth1*m_iHeight; 519 pcInfo=new BYTE[256*sizeof(RGBQUAD)+sizeof(BITMAPINFOHEADER)+m_iMaxByte+sizeof(GIFTABLE)*4096]; 520 521 bitmapheader=(BITMAPINFOHEADER*)pcInfo; 522 pcColorTable=pcInfo+sizeof(BITMAPINFOHEADER); 523 m_pcBitmap=pcColorTable+256*sizeof(RGBQUAD); 524 pcGifTable=(GIFTABLE*)(m_pcBitmap+m_iMaxByte); 525 for(int i=0;i<4096;i++) 526 pcGifTable[i].previouscode=pcGifTable[i].nextcode=0; 527 bitmapheader->biSize=sizeof(BITMAPINFOHEADER); 528 bitmapheader->biWidth=m_iWidth; 529 bitmapheader->biHeight=-m_iHeight; 530 bitmapheader->biPlanes=1; 531 bitmapheader->biBitCount=8; 532 bitmapheader->biCompression=BI_RGB; 533 bitmapheader->biSizeImage=0; 534 bitmapheader->biXPelsPerMeter=0; 535 bitmapheader->biYPelsPerMeter=0; 536 bitmapheader->biClrUsed=256; 537 bitmapheader->biClrImportant=256; 538 if(m_cPackedField&0x80) 539 { 540 uLocalColorTableSize=1; 541 uLocalColorTableSize<<=(m_cPackedField&7)+1; 542 if(m_bTransparentIndex) 543 { 544 m_TransparentColor=RGB(m_pcGifTrack[m_iTransparentIndex*3],m_pcGifTrack[m_iTransparentIndex*3+1],m_pcGifTrack[m_iTransparentIndex*3+2]); 545 } 546 m_iTotalReadByte+=uLocalColorTableSize*3; 547 for(UINT i=0;i<uLocalColorTableSize;i++) 548 { 549 pcColorTable[2]=*m_pcGifTrack++; 550 pcColorTable[1]=*m_pcGifTrack++; 551 pcColorTable[0]=*m_pcGifTrack++; 552 pcColorTable[3]=0; 553 pcColorTable+=4; 554 } 555 } 556 else 557 { 558 BYTE *pcGlobalColor=m_pcGlobalColorTable; 559 if(m_bTransparentIndex) 560 { 561 m_TransparentColor=RGB(pcGlobalColor[m_iTransparentIndex*3],pcGlobalColor[m_iTransparentIndex*3+1],pcGlobalColor[m_iTransparentIndex*3+2]); 562 } 563 for(int i=0;i<m_iGlobalColorSize;i++) 564 { 565 pcColorTable[2]=*pcGlobalColor++; 566 pcColorTable[1]=*pcGlobalColor++; 567 pcColorTable[0]=*pcGlobalColor++; 568 pcColorTable[3]=0; 569 pcColorTable+=4; 570 } 571 } 572 m_uPrimaryBitSize=m_uBitSize=(*m_pcGifTrack++); 573 m_iTotalReadByte++; 574 iPrimaryTableSize=iTableSize=(1<<m_uBitSize)+2; 575 iFinishCode=iTableSize-1; 576 iResetCode=iFinishCode-1; 577 m_uPrimaryBitSize++; 578 m_uBitSize++; 579 m_uRemain=0; 580 m_cCurentByte=0; 581 m_uBlockSize=0; 582 m_uReadByte=1; 583 m_x=m_y=0; 584 m_iPass=1; 585 m_iRow=0; 586 while((code=GetCode())!=iFinishCode) 587 { 588 if(code==iResetCode) 589 { 590 m_uBitSize=m_uPrimaryBitSize; 591 iTableSize=iPrimaryTableSize; 592 oldcode=GetCode(); 593 if(oldcode>iTableSize) 594 { 595 delete[] pcInfo; 596 return 0; 597 } 598 Output((BYTE)oldcode); 599 continue; 600 } 601 if(code<iTableSize) //<code> exist in the string pcGifTable 602 { 603 code1=code; 604 WORD code2=0; 605 while(code1>=iPrimaryTableSize) 606 { 607 pcGifTable[code1].nextcode=code2; 608 code2=code1; 609 code1=pcGifTable[code1].previouscode; 610 if(code1>=code2) 611 { 612 delete[] pcInfo; 613 return 0; 614 } 615 } 616 Output((BYTE)code1); 617 while(code2!=0) 618 { 619 Output(pcGifTable[code2].bit); 620 code2=pcGifTable[code2].nextcode; 621 } 622 pcGifTable[iTableSize].bit=(BYTE)code1; 623 pcGifTable[iTableSize].previouscode=oldcode; 624 iTableSize++; 625 if(iTableSize==(0x0001<<m_uBitSize)) 626 m_uBitSize++; 627 if(m_uBitSize>12) 628 m_uBitSize=12; 629 oldcode=code; 630 } 631 else 632 { 633 code1=oldcode; 634 WORD code2=0; 635 while(code1>=iPrimaryTableSize) 636 { 637 pcGifTable[code1].nextcode=code2; 638 code2=code1; 639 code1=pcGifTable[code1].previouscode; 640 if(code1>=code2) 641 { 642 delete[] pcInfo; 643 return 0; 644 } 645 } 646 Output((BYTE)code1); 647 while(code2!=0) 648 { 649 Output(pcGifTable[code2].bit); 650 code2=pcGifTable[code2].nextcode; 651 } 652 Output((BYTE)code1); 653 pcGifTable[iTableSize].bit=(BYTE)code1; 654 pcGifTable[iTableSize].previouscode=oldcode; 655 iTableSize++; 656 if(iTableSize==(0x0001<<m_uBitSize)) 657 m_uBitSize++; 658 if(m_uBitSize>12) 659 m_uBitSize=12; 660 oldcode=code; 661 } 662 } 663 hBitmap = DIBTohBitmap(m_hDC,(LPSTR)pcInfo); 664 m_pcGifTrack++; 665 m_iTotalReadByte++; 666 delete[] pcInfo; 667 return hBitmap; 668 } 669 void CGIFShow::SetPosition(int x,int y) 670 { 671 m_nPosX=x; 672 m_nPosY=y; 673 } 674 void CGIFShow::Pause(bool status) 675 { 676 m_bPause=status; 677 } 678 HBITMAP CGIFShow::DIBTohBitmap(HDC hDC,LPSTR lpSrcDIB) 679 { 680 HBITMAP hBitmap = NULL; 681 HBITMAP hOldBmp = NULL; 682 HDC hTmpDC = NULL; 683 BITMAPINFOHEADER* bitmapheader = (BITMAPINFOHEADER*)lpSrcDIB; 684 hBitmap = CreateCompatibleBitmap(hDC,bitmapheader->biWidth, 685 -(bitmapheader->biHeight)); 686 hTmpDC=CreateCompatibleDC(hDC); 687 hOldBmp=(HBITMAP)SelectObject(hTmpDC,hBitmap); 688 StretchDIBits(hTmpDC,0,0,bitmapheader->biWidth, 689 -bitmapheader->biHeight,0,0,bitmapheader->biWidth, 690 -bitmapheader->biHeight,lpSrcDIB+40 + 256*sizeof(RGBQUAD),(BITMAPINFO*)lpSrcDIB, 691 DIB_RGB_COLORS,SRCCOPY); 692 SelectObject(hTmpDC,hOldBmp); 693 DeleteDC(hTmpDC); 694 return hBitmap; 695 }
======================================= 3) 调用CGIFShow类示例 (1) 定义全局变量 CGIFShow *pGIFInst; (2) 在窗体的WM_CREATE消息处理中初始化CGIFShow类的实例 pGIFInst = new CGIFShow(GetDC(hWnd)); 注: CGIFShow 类需要显示在类似于窗体这样(应该说是具有画布属性)的句柄上。 在第一次使用CGIFShow类时,我想显示在listview上,但是没有成功 (3) GIF动画显示 if(pGIFInst->Load(TEXT("waiting.gif"))) { RECT rcClient; GetClientRect(hWnd, &rcClient); pGIFInst->SetPosition(96,130); pGIFInst->Play(); } /*需要等待处理的调用代码*/ pGIFInst->Stop(); (4) 最后记得清理内存 if(NULL != pGIFInst) delete pGIFInst;