Gif.cpp
上传用户:hyb6888
上传日期:2016-01-24
资源大小:5186k
文件大小:20k
源码类别:

输入法编程

开发平台:

Visual C++

  1. // Gif.cpp: implementation of the CGif class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "GIF.h"
  6. #include "stdio.h"
  7. static UINT GifThread(LPVOID p_Gif,LPVOID hwnd);
  8. BMPIMAGE::BMPIMAGE()
  9. {
  10. pImageData = NULL;
  11. }
  12. BMPIMAGE::~BMPIMAGE()
  13. {
  14. if (pImageData)
  15. GlobalFree(pImageData);
  16. }
  17. ////////////////////////////////////////////////////////
  18. //  myCPtrList class
  19. ////////////////////////////////////////////////////////
  20. myCPtrList::myCPtrList()
  21. {
  22. m_pNodeTail=&m_pNodeHead;
  23. m_pNodeFree=NULL;
  24. m_nCount=-1;
  25. }
  26. myCPtrList::~myCPtrList()
  27. {
  28. }
  29. myPOSITION myCPtrList::AddTail(void* newElement)//把一个图像加入集合中
  30. {
  31.    BMPIMAGE * pBmpImage;
  32.    CNode  *pnd;
  33.    pBmpImage=(BMPIMAGE*) newElement;
  34.    pnd=new CNode;
  35.    pnd->data=pBmpImage;
  36.     m_pNodeTail->pNext=pnd;
  37.     pnd->pPrev=m_pNodeTail;
  38.     m_pNodeTail=pnd;
  39. m_nCount++;
  40.    return 0;
  41. }
  42. //只释放节点,而数据由外部释放
  43. void myCPtrList::RemoveTail()         // 删除元素
  44. {
  45.     if((m_pNodeTail != &m_pNodeHead) && (m_nCount > -1))
  46. {
  47. m_pNodeTail=m_pNodeTail->pPrev;
  48. m_pNodeTail->pNext->data;
  49. delete m_pNodeTail->pNext;
  50. m_nCount--;
  51. }
  52. }
  53. void*myCPtrList::GetTail()//得到最后一个元素
  54. {
  55. void* pp=NULL;
  56. if(m_pNodeTail!=NULL)
  57. pp=m_pNodeTail->data;
  58.    return pp;
  59. }
  60. myPOSITION myCPtrList::FindIndex(int nIndex) //得到nIndex指定的元素,可能为空
  61. {
  62. CNode *pp=NULL;
  63. int i;
  64. pp=m_pNodeHead.pNext;
  65.    if((nIndex > -1) && (nIndex < m_nCount))
  66.    {
  67.     for(i=0;i<=nIndex;i++)
  68. pp=pp->pNext;
  69.    }
  70.    else
  71.    pp=NULL;
  72.    return (myPOSITION)pp;
  73. }
  74. void*myCPtrList::GetAt(myPOSITION position)//得到指定位置的一个元素
  75. {
  76. CNode *pp=NULL;
  77. pp=(CNode *)position;
  78. return pp->data;
  79. }
  80. bool myCPtrList:: IsEmpty ()
  81. {
  82. return m_nCount <0;
  83. }
  84. //
  85. CGIF::CGIF()
  86. {
  87. hMapFile = NULL;
  88. lpMapFileBase = NULL;
  89. }
  90. CGIF::~CGIF()
  91. {
  92. BMPIMAGE * pBmpImage;
  93. while (!m_ImageList.IsEmpty ())
  94. {
  95. pBmpImage = (BMPIMAGE *) m_ImageList.GetTail ();
  96. m_ImageList.RemoveTail ();
  97. delete pBmpImage;
  98. }
  99. if(lpMapFileBase!=NULL)
  100. UnmapViewOfFile(lpMapFileBase);
  101. if(hMapFile!=NULL)
  102. CloseHandle(hMapFile);
  103. }
  104. BOOL CGIF::LoadGIF(LPCTSTR GifFileName)
  105. {
  106. //pFileContent;
  107. int ret=0 ;
  108. HANDLE  hfile;
  109. LPUSTR pFileContent;
  110. if(strlen(GifFileName)==0)
  111.   return 1;
  112. if(lpMapFileBase!=NULL)
  113. UnmapViewOfFile(lpMapFileBase);
  114. if(hMapFile!=NULL)
  115. CloseHandle(hMapFile);
  116. {
  117. hfile=CreateFile(GifFileName,
  118. GENERIC_READ,FILE_SHARE_READ ,NULL,
  119. OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  120.     if(hfile==INVALID_HANDLE_VALUE)
  121. {
  122. //MessageBox(0,"文件没有打开",0,0);
  123. return 1;
  124. }
  125.   ret=1;
  126. if ( (hMapFile=CreateFileMapping(hfile,NULL,PAGE_READONLY,0,0,"GIFte1")) == NULL) 
  127. {
  128. //MessageBox(0,"文件句柄的误",0,0);
  129. CloseHandle(hfile);
  130. return 1;
  131. }
  132. if ( (lpMapFileBase = (LPVOID) MapViewOfFile( hMapFile, FILE_MAP_READ,0,0,0)) == NULL) 
  133. {
  134. //MessageBox(0,"文件可能为空",0,0);
  135. CloseHandle(hMapFile);
  136. CloseHandle(hfile);
  137. return 1;
  138. }
  139. CloseHandle(hfile);
  140. pFileContent=(LPUSTR)lpMapFileBase;
  141. }
  142. //Clear 
  143. BMPIMAGE * pBmpImage;
  144. while (!m_ImageList.IsEmpty ())
  145. {
  146. pBmpImage = (BMPIMAGE *) m_ImageList.GetTail ();
  147. m_ImageList.RemoveTail ();
  148. delete pBmpImage;
  149. }
  150. UINT HeaderSize = AnalizeFileHeader(pFileContent);
  151. m_pDataArea = pFileContent + HeaderSize;
  152. /*{
  153. char ss[1000];
  154. sprintf(ss,"%d",pFileContent);
  155. MessageBox(0,ss,"not 781",0);
  156. }*/
  157. m_CurTColorIndex = -1;
  158. m_CurDelayTime = 0;
  159. LPUSTR p = m_pDataArea;
  160. UINT  Offset;
  161. while (1)
  162. {
  163. if (p[0] == 0x21 && p[1] == 0xf9 && p[2] == 0x04)
  164. {
  165. Offset = GetGrphContent(p);
  166. p += Offset;
  167. }
  168. else if (p[0] == 0x21 && p[1] == 0x01 && p[2] == 0x0c)
  169. {
  170. Offset = ShowText(p);
  171. p += Offset;
  172. }
  173. else if (p[0] == 0x21 && p[1] == 0xff && p[2] == 0x0b)
  174. {
  175. Offset = GetAppContent(p);
  176. p += Offset;
  177. }
  178. else if (p[0] == 0x21 && p[1] == 0xfe)
  179. {
  180.    Offset = GetNoteContent(p);
  181.    p += Offset;
  182. }
  183. else if (p[0] == 0x2c)
  184. {
  185.    Offset = GetImage(p);
  186.    p += Offset;
  187. }
  188. else break;
  189. }
  190. GlobalFree(pFileContent);
  191. return 0;
  192. }
  193. UINT  CGIF::AnalizeFileHeader(LPUSTR pFileContent)
  194. {
  195. // GIF File Header
  196. GIFHEADER gifHeader;//
  197. int sz;
  198. sz=sizeof(GIFINFO);
  199. sz=sizeof(GIFHEADER);
  200. memcpy(&gifHeader,pFileContent,sz);
  201. m_GifInfo.Width = gifHeader.ScreenWidth ;
  202. m_GifInfo.Height = gifHeader.ScreenDepth ;
  203. m_GifInfo.ColorMode  = (gifHeader.GlobalFlagByte & 0x07) + 1;//肅︹家Α 1,2,3,4,5,6,7,8
  204. m_GifInfo.InitPixelBits = m_GifInfo.ColorMode + 1;
  205. m_GifInfo.ColorType = 1;
  206. switch (m_GifInfo.ColorMode)
  207. {
  208. case 1:
  209. m_GifInfo.ColorType = m_GifInfo.ColorType << 1;
  210. break;
  211. case 2:
  212. m_GifInfo.ColorType = m_GifInfo.ColorType << 2;
  213. break;
  214. case 3:
  215. m_GifInfo.ColorType = m_GifInfo.ColorType << 3;
  216. break;
  217. case 4:
  218. m_GifInfo.ColorType = m_GifInfo.ColorType << 4;
  219. break;
  220. case 5:
  221. m_GifInfo.ColorType = m_GifInfo.ColorType << 5;
  222. break;
  223. case 6:
  224. m_GifInfo.ColorType = m_GifInfo.ColorType << 6;
  225. break;
  226. case 7:
  227. m_GifInfo.ColorType = m_GifInfo.ColorType << 7;
  228. break;
  229. case 8:
  230. m_GifInfo.ColorType = m_GifInfo.ColorType << 8;
  231. break;
  232. }
  233. //end
  234. if (gifHeader.GlobalFlagByte & 0x80) 
  235. //read pal data and save it to BitMap pal
  236. LPUSTR p = pFileContent + sz;
  237. MYRGB * pRGB = (MYRGB *)p;
  238. for (UINT j = 0; j < m_GifInfo.ColorType ; j ++)
  239. {
  240. m_CurRgbQuad[j].rgbRed       = pRGB->bRed;
  241. m_CurRgbQuad[j].rgbGreen     = pRGB->bGreen;
  242. m_CurRgbQuad[j].rgbBlue      = pRGB->bBlue;
  243. m_CurRgbQuad[j].rgbReserved  = 0;
  244. pRGB++;
  245. }
  246. p += 3 * m_GifInfo.ColorType;//pass pal
  247. return  sz+ 3 * m_GifInfo.ColorType;
  248. }
  249. return sz;
  250. }
  251. UINT CGIF::GetGrphContent(LPUSTR pGrCtrl)
  252. {
  253. GRAPHCTRL GraphCtrl;
  254. memcpy(&GraphCtrl,pGrCtrl,sizeof(GRAPHCTRL));
  255. USHORT Flag = GraphCtrl.PackedField;
  256. m_CurTColorIndex = -1;
  257. m_CurDelayTime = 0;
  258. if (Flag & 1)
  259. m_CurTColorIndex = GraphCtrl.TranColorIndex ;
  260. if (Flag & 2)
  261. m_CurDelayTime = GraphCtrl.DelayTime ;
  262. return sizeof(GRAPHCTRL);
  263. }
  264. UINT CGIF::ShowText(LPUSTR pText)
  265. {
  266. TEXTCTRL TextCtrl;
  267. memcpy(&TextCtrl,pText,sizeof(TEXTCTRL));
  268. return sizeof(TEXTCTRL)+TextCtrl.Data [0] - 256 + 1;
  269. }
  270. UINT CGIF::GetAppContent(LPUSTR pApp)
  271. {
  272. APPCTRL AppCtrl;
  273. memcpy(&AppCtrl,pApp,sizeof(APPCTRL));
  274. return sizeof(APPCTRL)+AppCtrl.Data [0] - 256 + 1;
  275. }
  276. UINT CGIF::GetNoteContent(LPUSTR pNote)
  277. {
  278. NOTEHCTRL NoteCtrl;
  279. memcpy(&NoteCtrl,pNote,sizeof(NOTEHCTRL));
  280. return sizeof(NOTEHCTRL)+NoteCtrl.Data[0] - 256 + 1;
  281. }
  282. UINT CGIF::GetImage(LPUSTR pData)
  283. {
  284. IMAGEDATAINFO ImageData;
  285. memcpy(&ImageData,pData,sizeof(IMAGEDATAINFO));
  286. LPUSTR p = pData + sizeof(IMAGEDATAINFO);
  287. UINT PalSize = 0;
  288. m_CurSaveMode = 0;
  289. m_CurX = ImageData.ImageLeft;
  290. m_CurY = ImageData.ImageTop ;
  291. m_CurWidth = ImageData.ImageWidth ;
  292. m_CurHeight = ImageData.ImageHeight;
  293. if (ImageData.LocalFlagByte  & 0x80) 
  294. MYRGB * pRGB = (MYRGB *)p;
  295. for (UINT j = 0; j < m_GifInfo.ColorType ; j ++)
  296. {
  297. m_CurRgbQuad[j].rgbRed       = pRGB->bRed;
  298. m_CurRgbQuad[j].rgbGreen     = pRGB->bGreen;
  299. m_CurRgbQuad[j].rgbBlue      = pRGB->bBlue;
  300. m_CurRgbQuad[j].rgbReserved  = 0;
  301. pRGB++;
  302. }
  303. p += 3 * m_GifInfo.ColorType;//pass pal
  304. PalSize = 3 * m_GifInfo.ColorType;
  305. }
  306. else if (ImageData.LocalFlagByte  & 0x40)
  307. {
  308. m_CurSaveMode = 1;
  309. }
  310. UINT InitBits = *p++;
  311. UINT offset;
  312. UINT dataCount = GetCodeCountOnChar(p,offset);
  313. LPUSTR pCodeData = GetCodeDataOnChar(p);
  314. LPUSTR pTrueCodeData = GetCodeDataOnBits (pCodeData,m_GifInfo.InitPixelBits,dataCount);
  315. ConvertToBmpImage(pTrueCodeData);
  316. GlobalFree(pCodeData);
  317. GlobalFree(pTrueCodeData);
  318. return sizeof(IMAGEDATAINFO) + offset + PalSize;
  319. }
  320. USHORT CGIF::GetOneCode(LPUSTR CodeStr ,UINT CodeStrLen, UINT OffsetChar , UINT OffsetBits, UINT Length)
  321. {
  322. UCHAR *pValue,*lp = (UCHAR*)CodeStr;
  323. UINT value = 0;
  324. pValue = (UCHAR *)&value;
  325. pValue[0] = lp[OffsetChar+0];
  326. if (OffsetChar + 1 < CodeStrLen)
  327. pValue[1] = lp[OffsetChar+1];
  328. if (OffsetChar + 2 < CodeStrLen)
  329. pValue[2] = lp[OffsetChar+2];
  330. if (OffsetChar + 3 < CodeStrLen)
  331. pValue[3] = lp[OffsetChar+3];
  332. value = value >> OffsetBits;
  333. value = value << (32 - Length);
  334. value = value >> (32 - Length);
  335. return (USHORT)value;
  336. }
  337. UINT CGIF::GetCodeCountOnChar (LPUSTR CodeDataStr,UINT &AllDataLen)
  338. {
  339. UINT dataCount = 0;
  340. UCHAR dataLen;
  341. LPUSTR p1 = CodeDataStr;
  342. AllDataLen = 0;
  343. while (1)
  344. {
  345. dataLen = *p1 ++;
  346. p1 += dataLen;
  347. dataCount += dataLen;
  348. AllDataLen += (dataLen + 1);
  349. if (dataLen == 0x00) break;
  350. }
  351. AllDataLen ++;
  352. return dataCount;
  353. }
  354. LPUSTR CGIF::GetCodeDataOnChar (LPUSTR CodeDataStr)
  355. {
  356. UINT offset;
  357. UINT dataCount = GetCodeCountOnChar(CodeDataStr,offset);
  358. LPUSTR pData,p2;
  359. pData = (LPUSTR)GlobalAlloc (GPTR,dataCount+1);
  360. p2 = pData;
  361. UCHAR dataLen;
  362. LPUSTR p1 = CodeDataStr;
  363. while (1)
  364. {
  365. dataLen = *p1 ++;
  366. if (dataLen == 0x00) 
  367. break;
  368. memcpy(p2,p1,dataLen);
  369. p1 += dataLen;
  370. p2 += dataLen;
  371. dataCount += dataLen;
  372. }
  373. return pData;
  374. }
  375. LPUSTR  CGIF::GetCodeDataOnBits (LPUSTR CodeDataStr ,UINT InitLen ,UINT &CodeDataLen)
  376. {
  377. LPUSTR p = CodeDataStr;
  378. LPUSTR pData = (LPUSTR ) GlobalAlloc (GPTR ,m_CurWidth*m_CurHeight*2);
  379. LPUSTR pTrueData = pData;
  380. int i = 0;
  381. UINT BitsCount = 0;
  382. USHORT TCode,s = m_GifInfo.ColorType + 2;//
  383. UINT TableLen,iLen = InitLen;
  384. UINT Pos,index,j = 0;
  385. UINT SrcCodeLEN = CodeDataLen;
  386. while (1)
  387. {
  388. TCode = GetOneCode(p ,CodeDataLen,BitsCount / 8, BitsCount % 8, iLen);
  389. BitsCount += iLen;
  390. if (TCode < m_GifInfo.ColorType)
  391. {
  392. LZWTable[j].Header = TCode;
  393. LZWTable[j].Code   = s ++;
  394. if (j != 0)
  395. {
  396. LZWTable[j - 1].Tail = TCode;
  397. }
  398. j++;
  399. }
  400. else if (TCode > m_GifInfo.ColorType + 1)
  401. {
  402. if (j == 0) continue;
  403. LZWTable[j].Header = TCode;
  404. LZWTable[j].Code   = s ++;
  405. index = j - 1;
  406. Pos = j;
  407. while (1)
  408. {
  409. Pos = LZWTable[Pos].Header - (m_GifInfo.ColorType + 2) ;
  410. if (LZWTable[Pos].Header < m_GifInfo.ColorType) 
  411. break;
  412. }
  413. LZWTable[index].Tail  = LZWTable[Pos].Header;
  414. j++;
  415. }
  416. else if (TCode == m_GifInfo.ColorType)
  417. {
  418. iLen = InitLen;
  419. TableLen = j;
  420. j = 0;
  421. GetPartImageDataFromTable(pData,LZWTable,TableLen);
  422. //pData+=TableLen;
  423. s = m_GifInfo.ColorType + 2 ;
  424. }
  425. else if (TCode == m_GifInfo.ColorType + 1) 
  426. {
  427. //end build table
  428. iLen = InitLen;
  429. TableLen = j;
  430. GetPartImageDataFromTable(pData,LZWTable,TableLen);
  431. //pData+=TableLen;
  432. s = m_GifInfo.ColorType + 2;
  433. break;
  434. }
  435. if (s == 3)
  436. iLen = 2;
  437. else if (s == 5)
  438. iLen = 3;
  439. else if (s == 9)
  440. iLen = 4;
  441. else if (s == 17)
  442. iLen = 5;
  443. else if (s == 33)
  444. iLen = 6;
  445. else if (s == 65)
  446. iLen = 7;
  447. else if (s == 129)
  448. iLen  = 8;
  449. else if (s == 257)
  450. iLen  = 9;
  451. else if ( s == 513 ) 
  452. iLen = 10;
  453. else if (s == 1025 ) 
  454. iLen = 11;
  455. else if (s == 2049 ) 
  456. iLen = 12;
  457. if (BitsCount / 8 > SrcCodeLEN)
  458. {
  459. iLen = InitLen;
  460. TableLen = j;
  461. GetPartImageDataFromTable(pData,LZWTable,TableLen);
  462. s = m_GifInfo.ColorType + 2;
  463. break;
  464. }
  465. }
  466. CodeDataLen = BitsCount / 8;
  467. return pTrueData;
  468. }
  469. void  CGIF::GetPartImageDataFromTable(LPUSTR &pImage,LZWTABLE * Table,UINT TableLen)
  470. {
  471. UINT i;
  472. LPUSTR p = pImage;
  473. USHORT *TailStack = new USHORT[5200];
  474. int j;
  475. int sp;
  476. for (i = 0 ; i < TableLen; i++)
  477. {
  478. if (Table[i].Header < m_GifInfo.ColorType)
  479. {
  480. *p++ = (UCHAR)Table[i].Header ;
  481. }
  482. else
  483. {
  484. sp = 0;
  485. j = Table[i].Header - (m_GifInfo.ColorType + 2);
  486. while (Table[j].Header > m_GifInfo.ColorType + 1)
  487. {
  488. TailStack[sp++] = Table[j].Tail ;
  489. j = Table[j].Header;
  490. j -= (m_GifInfo.ColorType + 2);
  491. }
  492. *p++ = (UCHAR)Table[j].Header;
  493. *p++ = (UCHAR)Table[j].Tail;
  494. sp --;
  495. while (sp >= 0)
  496. {
  497. *p++ = (UCHAR)TailStack[sp--];
  498. }
  499. }
  500. }
  501. int len = p - pImage;
  502. pImage = p;
  503. delete []TailStack;
  504. }
  505. BOOL CGIF::ConvertToBmpImage(LPUSTR SrcData)
  506. {
  507. LPUSTR pSrcData = SrcData;
  508. UINT i,j,k,Step;
  509. if (m_CurSaveMode )
  510. {
  511. LPUSTR p2 = (LPUSTR)GlobalAlloc(GPTR,m_CurWidth*m_CurHeight);
  512. LPUSTR pTmp = p2;
  513. k = 0; Step = 8;
  514. for (j = 0; j < m_CurHeight  ; j ++)
  515. {
  516. memcpy(pTmp+k*m_CurWidth,pSrcData+j*m_CurWidth,m_CurWidth);
  517. k += Step;
  518. if (k >= m_CurHeight) break;
  519. }
  520. j++;
  521. k = 4; Step = 8;
  522. for (; j < m_CurHeight  ; j ++)
  523. {
  524. memcpy(pTmp+k*m_CurWidth,pSrcData+j*m_CurWidth,m_CurWidth);
  525. k += Step;
  526. if (k >= m_CurHeight) break;
  527. }
  528. j++;
  529. k = 2; Step = 4;
  530. for (; j < m_CurHeight  ; j ++)
  531. {
  532. memcpy(pTmp+k*m_CurWidth,pSrcData+j*m_CurWidth,m_CurWidth);
  533. k += Step;
  534. if (k >= m_CurHeight) break;
  535. }
  536. j++;
  537. k = 1; Step = 2;
  538. for (; j < m_CurHeight  ; j ++)
  539. {
  540. memcpy(pTmp+k*m_CurWidth,pSrcData+j*m_CurWidth,m_GifInfo.Width);
  541. k += Step;
  542. if (k >= m_CurHeight) break;
  543. }
  544. pSrcData = p2;
  545. }
  546. BMPIMAGE * pBmpImage = new BMPIMAGE;
  547. pBmpImage->tColor = m_CurTColorIndex;
  548. pBmpImage->DelayTime = m_CurDelayTime;
  549. pBmpImage->Left = m_CurX;
  550. pBmpImage->Top = m_CurY;
  551. pBmpImage->Width = m_CurWidth ;
  552. pBmpImage->Height = m_CurHeight ;
  553. pBmpImage->SaveMode = m_CurSaveMode;
  554. memcpy(&pBmpImage->Palette ,&m_CurRgbQuad,sizeof(RGBQUAD)*256);
  555. USHORT TrueWidth = WIDTHBYTES(m_CurWidth * 8);
  556. pBmpImage->pImageData = (LPUSTR)GlobalAlloc(GPTR,TrueWidth*m_CurHeight );
  557. LPUSTR p0,p1;
  558. p0 = pSrcData;
  559.     p1 = pBmpImage->pImageData;
  560. for (j = 0; j < m_CurHeight  ; j ++)
  561. {
  562. k = (m_CurHeight - j - 1);
  563. for (i = 0 ; i < m_CurWidth ;i ++)
  564. {
  565. p1[ k * TrueWidth + i] = p0[j*m_CurWidth+i];
  566. }
  567. }
  568. if (m_CurSaveMode)
  569. {
  570. GlobalFree(pSrcData);
  571. }
  572. m_ImageList.AddTail (pBmpImage);
  573. return 1;
  574. }
  575. BOOL CGIF::ShowImage(HDC hDC, POINT StartPos, UINT ImageNo)
  576. {
  577. BITMAPINFOHEADER  BmpInfoHeader;
  578. BmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
  579. BmpInfoHeader.biPlanes = 1;
  580. BmpInfoHeader.biBitCount = 8;
  581. BmpInfoHeader.biCompression = BI_RGB;
  582. BmpInfoHeader.biSizeImage = 0;
  583. BmpInfoHeader.biXPelsPerMeter = 0;
  584. BmpInfoHeader.biYPelsPerMeter = 0;
  585. BmpInfoHeader.biClrUsed = 0;
  586. BmpInfoHeader.biClrImportant = 0;
  587. myPOSITION Pos;
  588. Pos = m_ImageList.FindIndex(ImageNo);
  589. if (Pos)
  590. {
  591. BMPIMAGE * pBmpImage = (BMPIMAGE *)m_ImageList.GetAt(Pos );
  592. BmpInfoHeader.biWidth = pBmpImage->Width;
  593. BmpInfoHeader.biHeight = pBmpImage->Height;
  594. BITMAPINFO  *pBmInfo = (BITMAPINFO  *)GlobalAlloc(GPTR,sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
  595. memcpy(&pBmInfo->bmiHeader ,&BmpInfoHeader,sizeof(BITMAPINFOHEADER));
  596. memcpy(pBmInfo->bmiColors ,pBmpImage->Palette ,sizeof(RGBQUAD)*256);
  597. if (pBmpImage->tColor >= 0)
  598. {
  599. HDC hMemDC = ::CreateCompatibleDC(hDC);
  600. HBITMAP hBmp = (HBITMAP)::CreateCompatibleBitmap(hDC,pBmpImage->Width,pBmpImage->Height);
  601. HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC,hBmp);
  602. ::StretchDIBits(hMemDC,0 ,0,pBmpImage->Width,pBmpImage->Height,
  603. 0,0,pBmpImage->Width,pBmpImage->Height ,pBmpImage->pImageData,pBmInfo,
  604. DIB_RGB_COLORS,SRCCOPY);
  605. COLORREF cRgb = RGB(pBmpImage->Palette [pBmpImage->tColor].rgbRed,
  606. pBmpImage->Palette [pBmpImage->tColor].rgbGreen,
  607. pBmpImage->Palette [pBmpImage->tColor].rgbBlue );
  608. BitBltEx(hDC,pBmpImage->Left+StartPos.x ,pBmpImage->Top+StartPos.y ,pBmpImage->Width,pBmpImage->Height,hMemDC,0,0 ,cRgb);
  609. ::SelectObject(hMemDC,hOldBmp);
  610. ::DeleteObject(hBmp);
  611. ::DeleteDC(hMemDC);
  612. }
  613. else ::StretchDIBits(hDC,pBmpImage->Left+StartPos.x ,pBmpImage->Top+StartPos.y ,pBmpImage->Width,pBmpImage->Height,
  614. 0,0,pBmpImage->Width,pBmpImage->Height ,pBmpImage->pImageData,pBmInfo,
  615. DIB_RGB_COLORS,SRCCOPY);
  616.  
  617. GlobalFree(pBmInfo);
  618. }
  619. else
  620. return 0;
  621. return 1;
  622. }
  623. BOOL BitBltEx(
  624.   HDC hdcDest,             // 目标设备上下文句柄
  625.   int nXDest, int nYDest,  // 目标矩形左上角的坐标
  626.   int nWidth,int nHeight,  // 目标矩形
  627.   HDC hdcSrc,              // 源设备上下文句柄
  628.   int nXSrc, int nYSrc,    // 源矩形左上角的坐标
  629.   COLORREF cTransparentColor  )
  630. {
  631. HDC hDC1,hDC2;
  632. hDC1 = CreateCompatibleDC( hdcSrc );
  633. hDC2 = CreateCompatibleDC( hdcSrc );
  634. HBITMAP bmp1Old, bmp1 = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
  635. bmp1Old = (HBITMAP)SelectObject(hDC1, bmp1);
  636. COLORREF cColor = SetBkColor(hdcSrc, cTransparentColor); 
  637. ::BitBlt(hDC1,0,0,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,SRCCOPY);
  638. HBITMAP bmp2Old, bmp2 = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
  639. bmp2Old = (HBITMAP)SelectObject(hDC2, bmp2);
  640. ::BitBlt(hDC2,0,0,nWidth,nHeight,hDC1,0,0,NOTSRCCOPY);
  641. HDC hDC3;
  642. hDC3 = CreateCompatibleDC( hdcSrc );
  643. HBITMAP bmp3Old, bmp3 = CreateCompatibleBitmap(hdcSrc, nWidth, nHeight);
  644. bmp3Old = (HBITMAP)SelectObject(hDC3, bmp3);
  645. ::BitBlt(hDC3,0,0,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,SRCCOPY);
  646. ::BitBlt(hDC3,0,0,nWidth,nHeight,hDC2,0,0,SRCAND);
  647. SelectObject(hDC2, bmp2Old);
  648. DeleteObject(bmp2);
  649. DeleteDC(hDC2);
  650. HDC hDC4;
  651. hDC4 = CreateCompatibleDC( hdcSrc );
  652. HBITMAP bmp4Old, bmp4 = CreateCompatibleBitmap(hdcSrc, nWidth, nHeight);
  653. bmp4Old = (HBITMAP)SelectObject(hDC4, bmp4);
  654. ::BitBlt(hDC4,0,0,nWidth,nHeight,hdcDest,nXDest,nYDest,SRCCOPY);
  655. ::BitBlt(hDC4,0,0,nWidth,nHeight,hDC1,0,0,SRCAND);
  656. SelectObject(hDC1, bmp1Old);
  657. DeleteObject(bmp1);
  658. DeleteDC(hDC1);
  659. HDC hDC5;
  660. hDC5 = CreateCompatibleDC( hdcSrc );
  661. HBITMAP bmp5Old, bmp5 = CreateCompatibleBitmap(hdcSrc, nWidth, nHeight);
  662. bmp5Old = (HBITMAP)SelectObject(hDC5, bmp5);
  663. ::BitBlt(hDC5,0,0,nWidth,nHeight,hDC3,0,0,SRCCOPY);
  664. ::BitBlt(hDC5,0,0,nWidth,nHeight,hDC4,0,0,SRCPAINT);
  665. SelectObject(hDC3, bmp3Old);
  666. DeleteObject(bmp3);
  667. DeleteDC(hDC3);
  668. SelectObject(hDC4, bmp4Old);
  669. DeleteObject(bmp4);
  670. DeleteDC(hDC4);
  671. ::BitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hDC5,0,0,SRCCOPY);
  672. SelectObject(hDC5, bmp5Old);
  673. DeleteObject(bmp5);
  674. DeleteDC(hDC5);
  675. return 1;
  676. }
  677. BOOL CGIF::GetImageInfo(RECT &Rect,COLORREF &tColor ,UINT ImageNo)
  678. {
  679. myPOSITION Pos;
  680. Pos = m_ImageList.FindIndex(ImageNo);
  681. if (Pos)
  682. {
  683. BMPIMAGE * pBmpImage = (BMPIMAGE *)m_ImageList.GetAt(Pos );
  684. Rect.left = pBmpImage->Left ;
  685. Rect.top =  pBmpImage->Top ;
  686. Rect.right = pBmpImage->Left + pBmpImage->Width ;
  687. Rect.bottom = pBmpImage->Top + pBmpImage->Height ;
  688. tColor = pBmpImage->tColor ;
  689. return 1;
  690. }
  691. else return 0;
  692. }
  693. //AfxBeginThread(GifThread,(LPVOID)m_hWnd);
  694. //可以采用多线程实现动画
  695. static UINT GifThread(LPVOID p_Gif,LPVOID hwnd)
  696. {
  697.         CGIF *m_Gif=(CGIF *)p_Gif;
  698. // TODO: Add your control notification handler code here
  699. HDC m_hDC=GetDC((HWND)hwnd);
  700. HDC hMemDC = ::CreateCompatibleDC(m_hDC);
  701. HBITMAP hBmp = (HBITMAP)::CreateCompatibleBitmap(m_hDC ,800,600);
  702. HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC,hBmp);
  703. ::BitBlt (hMemDC,0,0,800,600,m_hDC,0,0,SRCCOPY);
  704. HDC hMemDC1 = ::CreateCompatibleDC(m_hDC);
  705. HBITMAP hBmp1 = (HBITMAP)::CreateCompatibleBitmap(m_hDC ,800,600);
  706. HBITMAP hOldBmp1 = (HBITMAP)::SelectObject(hMemDC1,hBmp1);
  707. POINT pt;
  708. pt.x=30;
  709. pt.y=30;
  710. int i = 0;
  711. int k = 0;
  712. MSG msg;
  713. RECT Rect;
  714. COLORREF tColor;
  715. while (1)
  716. {
  717. if (!m_Gif->ShowImage (hMemDC1,pt,i++))
  718. {
  719. i = 0;
  720. m_Gif->ShowImage (hMemDC1,pt,i++);
  721. k++;
  722. if (k > 10) break;
  723. }//hMemDC1中保存背景图片
  724. ::BitBlt (hMemDC,0,0,800,600,m_hDC,0,0,SRCCOPY);
  725. if (m_Gif->GetImageInfo (Rect,tColor,i-1))
  726. {
  727.   ::BitBlt (m_hDC ,0,0,Rect.right-Rect.left+pt.x + 50,Rect.bottom-Rect.top+pt.y + 50,hMemDC1,0,0,SRCCOPY);
  728. ::BitBlt (hMemDC1,0,0,Rect.right-Rect.left+pt.x + 50,Rect.bottom-Rect.top+pt.y+50,hMemDC,0,0,SRCCOPY);
  729. }
  730. else
  731. {
  732. ::BitBlt (m_hDC ,0,0,800,600,hMemDC1,0,0,SRCCOPY);
  733. ::BitBlt (hMemDC1,0,0,800,600,hMemDC,0,0,SRCCOPY);
  734. }
  735. if(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE ))
  736. {
  737. ::TranslateMessage(&msg);
  738. ::DispatchMessage(&msg);
  739. }
  740. Sleep(100);
  741. ::BitBlt (m_hDC,0,0,800,600,hMemDC,0,0,SRCCOPY);
  742. if(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE ))
  743. {
  744. ::TranslateMessage(&msg);
  745. ::DispatchMessage(&msg);
  746. }
  747. }
  748. ::SelectObject(hMemDC,hOldBmp);
  749. ::DeleteObject(hBmp);
  750. ::DeleteDC(hMemDC);
  751. ::SelectObject(hMemDC1,hOldBmp1);
  752. ::DeleteObject(hBmp1);
  753. ::DeleteDC(hMemDC1);
  754. ReleaseDC((HWND)hwnd,m_hDC);
  755. return 1;
  756. }