Gif89a.cpp
上传用户:wanyou818
上传日期:2007-01-02
资源大小:30k
文件大小:24k
源码类别:

图片显示

开发平台:

Visual C++

  1. // Gif89a.cpp : Implementation of CGif89a
  2. #include "stdafx.h"
  3. #include "Gif89.h"
  4. #include "Gif89a.h"
  5. #include<stdio.h>
  6. DWORD WINAPI ThreadFunc(CGif89a* ptr);
  7. BOOL CALLBACK DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); 
  8. /////////////////////////////////////////////////////////////////////////////
  9. // CGif89a
  10. HRESULT CGif89a::OnDraw(ATL_DRAWINFO& di)
  11. {
  12. GetAmbientUserMode(m_bRunMode);
  13. if(!m_bRunMode)
  14. {
  15. RECT& rc = *(RECT*)di.prcBounds;
  16. OLE_COLOR backcolor;
  17. COLORREF cl;
  18. HBRUSH br;
  19. HBITMAP bmp,oldbitmap;
  20. if(m_bGlass==FALSE)
  21. {
  22. HPALETTE pal;
  23. GetAmbientPalette(pal);
  24. GetAmbientBackColor(backcolor);
  25. OleTranslateColor(backcolor,pal,&cl);
  26. br=CreateSolidBrush(cl);
  27. FillRect(di.hdcDraw,&rc,br);
  28. DeleteObject(br);
  29. }
  30. m_hDC=di.hdcDraw;
  31. bmp=FirstImage();
  32. if(bmp!=0)
  33. {
  34. HDC dc;
  35. dc=CreateCompatibleDC(di.hdcDraw);
  36. oldbitmap=(HBITMAP)SelectObject(dc,bmp);
  37. ::BitBlt(di.hdcDraw,rc.left+m_iLeft,rc.top+m_iTop,m_iWidth,m_iHeight,dc,0,0,SRCCOPY);
  38. SelectObject(dc,oldbitmap);
  39. DeleteObject(bmp);
  40. DeleteDC(dc);
  41. }
  42. else
  43. {
  44. DrawText(di.hdcDraw, _T("Gif Control"), -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  45. }
  46. m_pcGifTrack=m_pcGif;
  47. m_iTotalReadByte=0;
  48. }
  49. else
  50. {
  51. if((flag==0)&&(m_bAutoStart!=FALSE))
  52. {
  53. flag=1;
  54. OLE_COLOR backcolor;
  55. RECT& rc = *(RECT*)di.prcBounds;
  56. HBRUSH br;
  57. COLORREF cl;
  58. if(m_bGlass==FALSE)
  59. {
  60. HPALETTE pal;
  61. GetAmbientPalette(pal);
  62. GetAmbientBackColor(backcolor);
  63. OleTranslateColor(backcolor,pal,&cl);
  64. br=CreateSolidBrush(cl);
  65. FillRect(di.hdcDraw,&rc,br);
  66. DeleteObject(br);
  67. }
  68. Play();
  69. return S_OK;
  70. }
  71. if((flag==0)&&(m_bAutoStart==FALSE))
  72. {
  73. OLE_COLOR backcolor;
  74. HBRUSH br;
  75. COLORREF cl;
  76. if(m_bGlass==FALSE)
  77. {
  78. RECT& rc = *(RECT*)di.prcBounds;
  79. HPALETTE pal;
  80. GetAmbientPalette(pal);
  81. GetAmbientBackColor(backcolor);
  82. OleTranslateColor(backcolor,pal,&cl);
  83. br=CreateSolidBrush(cl);
  84. FillRect(di.hdcDraw,&rc,br);
  85. DeleteObject(br);
  86. }
  87. return S_OK;
  88. }
  89. if(m_hRedrawBitmap!=0)
  90. {
  91. while(m_bLockBitmap);
  92. m_bLockBitmap=TRUE;
  93. HBITMAP old;
  94. HBRUSH br;
  95. OLE_COLOR backcolor;
  96. RECT& rc = *(RECT*)di.prcBounds;
  97. COLORREF cl;
  98. if(m_bGlass==FALSE)
  99. {
  100. HPALETTE pal;
  101. GetAmbientPalette(pal);
  102. GetAmbientBackColor(backcolor);
  103. OleTranslateColor(backcolor,pal,&cl);
  104. br=CreateSolidBrush(cl);
  105. FillRect(di.hdcDraw,&rc,br);
  106. DeleteObject(br);
  107. }
  108. HDC dc=::CreateCompatibleDC(di.hdcDraw);
  109. old=(HBITMAP)::SelectObject(dc,m_hRedrawBitmap);
  110. ::BitBlt(di.hdcDraw,0,0,m_iGifWidth,m_iGifHeight,dc,0,0,SRCCOPY);
  111. ::SelectObject(dc,old);
  112. m_bLockBitmap=FALSE;
  113. DeleteDC(dc);
  114. }
  115. }
  116. return S_OK;
  117. }
  118. STDMETHODIMP CGif89a::AboutBox()
  119. {
  120. DialogBox(_Module.m_hInst,MAKEINTRESOURCE(IDD_DIALOGBAR),0,DialogProc);
  121. return S_OK;
  122. }
  123. STDMETHODIMP CGif89a::Play()
  124. {
  125. // TODO: Add your implementation code here
  126. HANDLE hThread;
  127. DWORD ThreadId;
  128. if(m_hWnd==0)return S_OK;
  129. if(m_pcGif==0)return S_OK;
  130. if(m_EndRun==5)return S_OK;
  131. m_pcGifTrack=m_pcGif;
  132. m_iTotalReadByte=0;
  133. m_EndRun=5;
  134. hThread=CreateThread(NULL,0,(unsigned long(_stdcall*)(void*))ThreadFunc,this,0,&ThreadId);
  135. CloseHandle(hThread);
  136. return S_OK;
  137. }
  138. STDMETHODIMP CGif89a::Stop()
  139. {
  140. // TODO: Add your implementation code here
  141. if(m_EndRun!=5)return S_OK;
  142. m_EndRun=1;
  143. while(m_EndRun!=2);
  144. return S_OK;
  145. }
  146. STDMETHODIMP CGif89a::get_FileName(BSTR * pVal)
  147. {
  148. // TODO: Add your implementation code here
  149. USES_CONVERSION;
  150. *pVal=T2BSTR(filename);
  151. return S_OK;
  152. }
  153. STDMETHODIMP CGif89a::put_FileName(BSTR newVal)
  154. {
  155. // TODO: Add your implementation code here
  156. USES_CONVERSION;
  157. strcpy(filename,OLE2T(newVal));
  158. if(!Load(filename)){FireViewChange();return S_OK;}
  159. if(m_bAutoStart)flag=0;
  160. if(m_bAutoSize1)
  161. {
  162. SIZEL size5,size6;
  163. size5.cx=m_iGifWidth;
  164. size5.cy=m_iGifHeight;
  165. AtlPixelToHiMetric(&size5,&size6);
  166. m_rcPos.right=m_iGifWidth+m_rcPos.left;
  167. m_rcPos.bottom=m_iGifHeight+m_rcPos.top;
  168. SetExtent(DVASPECT_CONTENT,&size6);
  169. if((m_spInPlaceSite!=NULL)&&m_bInPlaceActive)m_spInPlaceSite->OnPosRectChange(&m_rcPos);
  170. else if(m_hWnd!=NULL)SetWindowPos(NULL,m_rcPos.left,m_rcPos.top,m_iGifWidth,m_iGifHeight,SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
  171. }
  172. FireViewChange();
  173. return S_OK;
  174. }
  175. STDMETHODIMP CGif89a::get_AutoStart(VARIANT_BOOL * pVal)
  176. {
  177. // TODO: Add your implementation code here
  178. *pVal=m_bAutoStart;
  179. return S_OK;
  180. }
  181. STDMETHODIMP CGif89a::get_AutoSize(VARIANT_BOOL * pVal)
  182. {
  183. // TODO: Add your implementation code here
  184. *pVal=m_bAutoSize1;
  185. return S_OK;
  186. }
  187. STDMETHODIMP CGif89a::put_AutoStart(VARIANT_BOOL newVal)
  188. {
  189. // TODO: Add your implementation code here
  190. m_bAutoStart=newVal;
  191. m_bRequiresSave=TRUE;
  192. return S_OK;
  193. }
  194. STDMETHODIMP CGif89a::put_AutoSize(VARIANT_BOOL newVal)
  195. {
  196. // TODO: Add your implementation code here
  197. if((newVal)&&(m_pcGif!=0))
  198. {
  199. SIZEL size5,size6;
  200. size5.cx=m_iGifWidth;
  201. size5.cy=m_iGifHeight;
  202. m_rcPos.right=m_iGifWidth+m_rcPos.left;
  203. m_rcPos.bottom=m_iGifHeight+m_rcPos.top;
  204. AtlPixelToHiMetric(&size5,&size6);
  205. SetExtent(DVASPECT_CONTENT,&size6);
  206. if((m_spInPlaceSite!=NULL)&&m_bInPlaceActive)m_spInPlaceSite->OnPosRectChange(&m_rcPos);
  207. else if(m_hWnd!=NULL)SetWindowPos(NULL,m_rcPos.left,m_rcPos.top,m_iGifWidth,m_iGifHeight,SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
  208. FireViewChange();
  209. }
  210. m_bRequiresSave=TRUE;
  211. m_bAutoSize1=newVal;
  212. return S_OK;
  213. }
  214. CGif89a::CGif89a()
  215. {
  216. m_bAutoStart=TRUE;
  217. m_bAutoSize1=TRUE;
  218. m_bEmbed=FALSE;
  219. m_pcGlobalColorTable=0;
  220. m_pcGif=0;
  221. m_iGifSize=0;
  222. m_iGlobalColorSize=0;
  223. m_bTransparentIndex=FALSE;
  224. m_iDelayTime=0;
  225. m_EndRun=0;
  226. m_dwSpeed=50;
  227. m_hRedrawBitmap=0;
  228. m_bLockBitmap=FALSE;
  229. flag=0;
  230. strcpy(filename,_T(""));
  231. m_bWindowOnly=TRUE;
  232. m_bNegotiatedWnd=FALSE;
  233. m_bWndLess=FALSE;
  234. m_bRunMode=1;
  235. m_bResizeNatural=TRUE;
  236. m_bRecomposeOnResize=TRUE;
  237. m_bGlass=FALSE;
  238. }
  239. CGif89a::~CGif89a(void)
  240. {
  241.  Stop();
  242.  if(m_hRedrawBitmap!=0)DeleteObject(m_hRedrawBitmap);
  243.  if(m_pcGlobalColorTable!=NULL)delete[] m_pcGlobalColorTable;
  244.  if(m_pcGif!=NULL)delete[] m_pcGif;
  245. }
  246. DWORD WINAPI ThreadFunc(CGif89a* ptr)
  247. {
  248. ptr->Play1();
  249. return 0;
  250. }
  251. BOOL CGif89a::Play1(void)
  252. {
  253. HDC hDC,hMemDC,hMemDC1;
  254. HBITMAP hOldBitmap,hOldBitmap1,hBitmap,hPreviousBitmap;
  255. DWORD systimer1,systimer2,speed;
  256. hDC=::GetDC(m_hWnd);
  257. hMemDC=::CreateCompatibleDC(hDC);
  258. hMemDC1=::CreateCompatibleDC(hDC);
  259. m_hDC=hDC;
  260. hPreviousBitmap=0;
  261. while(m_bLockBitmap);
  262. m_bLockBitmap=TRUE;
  263. if(m_hRedrawBitmap!=0)DeleteObject(m_hRedrawBitmap);
  264. m_hRedrawBitmap=::CreateCompatibleBitmap(hDC,m_iGifWidth,m_iGifHeight);
  265. hOldBitmap1=(HBITMAP)SelectObject(hMemDC1,m_hRedrawBitmap);
  266. ::BitBlt(hMemDC1,0,0,m_iGifWidth,m_iGifHeight,hDC,0,0,SRCCOPY);
  267. SelectObject(hMemDC1,hOldBitmap1);
  268. m_bLockBitmap=FALSE;
  269. m_iDisposalMethod=DISPOSAL_NOT;
  270. while(m_EndRun!=1)
  271. {
  272. systimer2=systimer1=GetTickCount();
  273. while(m_bLockBitmap);
  274. m_bLockBitmap=TRUE;
  275. hOldBitmap1=(HBITMAP)SelectObject(hMemDC1,m_hRedrawBitmap);
  276. //****************************************************
  277. //Restore Background
  278. switch(m_iDisposalMethod)
  279. {
  280. case DISPOSAL_NO:
  281. break;
  282. case DISPOSAL_NOT:
  283. break;
  284. case DISPOSAL_RESTBACK:
  285. case DISPOSAL_RESTORE:
  286. hOldBitmap=(HBITMAP)SelectObject(hMemDC,hPreviousBitmap);
  287. ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hMemDC,0,0,SRCCOPY);
  288. SelectObject(hMemDC,hOldBitmap);
  289. DeleteObject(hPreviousBitmap);
  290. hPreviousBitmap=0;
  291. break;
  292. }
  293. m_iDisposalMethod=DISPOSAL_NO;
  294. //***************************************************
  295. //Start Output Image
  296. hBitmap=NextImage();
  297. switch(m_iDisposalMethod)
  298. {
  299. case DISPOSAL_NO:
  300. break;
  301. case DISPOSAL_NOT:
  302. break;
  303. case DISPOSAL_RESTBACK:
  304. // break;
  305. case DISPOSAL_RESTORE:
  306. hPreviousBitmap=::CreateCompatibleBitmap(hDC,m_iWidth,m_iHeight);
  307. hOldBitmap=(HBITMAP)SelectObject(hMemDC,hPreviousBitmap);
  308. ::BitBlt(hMemDC,0,0,m_iWidth,m_iHeight,hMemDC1,m_iLeft,m_iTop,SRCCOPY);
  309. SelectObject(hMemDC,hOldBitmap);
  310. break;
  311. }
  312. hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);
  313. if(m_bTransparentIndex)
  314. {
  315. HBITMAP    bmAndBack, bmAndObject;
  316. HBITMAP    bmBackOld, bmObjectOld;
  317. HDC        hdcBack, hdcObject;
  318. COLORREF cColor;
  319. hdcBack=::CreateCompatibleDC(hDC);
  320. hdcObject=::CreateCompatibleDC(hDC);
  321. bmAndBack=CreateBitmap(m_iWidth,m_iHeight,1,1,NULL);
  322. bmAndObject=CreateBitmap(m_iWidth,m_iHeight,1,1,NULL);
  323. bmBackOld=(HBITMAP)SelectObject(hdcBack,bmAndBack);
  324. bmObjectOld=(HBITMAP)SelectObject(hdcObject,bmAndObject);
  325. cColor=SetBkColor(hMemDC,m_TransparentColor);
  326. ::BitBlt(hdcObject,0,0,m_iWidth,m_iHeight,hMemDC,0,0,SRCCOPY);
  327. SetBkColor(hMemDC,cColor);
  328. ::BitBlt(hdcBack,0,0,m_iWidth,m_iHeight,hdcObject,0,0,NOTSRCCOPY);
  329. ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hdcObject,0,0,SRCAND);
  330. ::BitBlt(hMemDC,0,0,m_iWidth,m_iHeight,hdcBack,0,0,SRCAND);
  331. ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hMemDC,0,0,SRCPAINT);
  332. DeleteObject(SelectObject(hdcBack,bmBackOld));
  333. DeleteObject(SelectObject(hdcObject,bmObjectOld));
  334. DeleteDC(hdcBack);
  335. DeleteDC(hdcObject);
  336. }
  337. else 
  338. {
  339. ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hMemDC,0,0,SRCCOPY);
  340. }
  341. SelectObject(hMemDC,hOldBitmap);
  342. DeleteObject(hBitmap);
  343. ::BitBlt(hDC,0,0,m_iGifWidth,m_iGifHeight,hMemDC1,0,0,SRCCOPY);
  344. SelectObject(hMemDC1,hOldBitmap1);
  345. m_bLockBitmap=FALSE;
  346. if(m_iDelayTime!=0)speed=m_iDelayTime*10;else speed=m_dwSpeed;
  347. while((m_EndRun!=1)&&(speed>systimer2-systimer1))
  348. {
  349. Sleep(10);
  350. systimer2=GetTickCount();
  351. }
  352. }
  353. if(hPreviousBitmap!=0)DeleteObject(hPreviousBitmap);
  354. DeleteDC(hMemDC);
  355. DeleteDC(hMemDC1);
  356. ::ReleaseDC(m_hWnd,hDC);
  357. m_EndRun=2;
  358. return TRUE;
  359. }
  360. BOOL CGif89a::Load(LPCTSTR filename)
  361. {
  362. HANDLE hFile;
  363. DWORD size,size1,readbyte;
  364. BYTE temp[13];
  365. if(m_bEmbed)return FALSE;
  366. //free memory from previous image
  367. Stop();
  368. if(m_pcGlobalColorTable!=NULL)delete[] m_pcGlobalColorTable;
  369. if(m_pcGif!=NULL)delete[] m_pcGif;
  370. if(m_hRedrawBitmap!=0){DeleteObject(m_hRedrawBitmap);m_hRedrawBitmap=0;};
  371. m_pcGlobalColorTable=m_pcGif=0;
  372. m_iTotalReadByte=0;
  373. m_iGifSize=m_iGlobalColorSize=0;
  374. hFile=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
  375. if(INVALID_HANDLE_VALUE==hFile)return FALSE;
  376. size=GetFileSize(hFile,&size1);
  377. if(size==0xFFFFFFFF){CloseHandle(hFile);return FALSE;}
  378. ReadFile(hFile,temp,13,&readbyte,NULL);
  379. if((readbyte!=13)||((temp[0]!='G')||(temp[1]!='I')||(temp[2]!='F')||(temp[3]!='8')||((temp[4]!='7')&&(temp[4]!='9'))||(temp[5]!='a')))
  380. {
  381. CloseHandle(hFile);
  382. return FALSE;
  383. }
  384. m_iGifWidth=*(WORD*)(temp+6);
  385. m_iGifHeight=*(WORD*)(temp+8);
  386. m_iBackgroundColor=temp[11];
  387. if(temp[10]&0x80)
  388. {
  389. m_iGlobalColorSize=0x01<<((temp[10]&0x07)+1);
  390. m_pcGlobalColorTable=new BYTE[3*m_iGlobalColorSize];
  391. ReadFile(hFile,m_pcGlobalColorTable,3*m_iGlobalColorSize,&readbyte,NULL);
  392. if(readbyte!=3*m_iGlobalColorSize)
  393. {
  394. delete[] m_pcGlobalColorTable;
  395. m_pcGlobalColorTable=0;
  396. m_iGlobalColorSize=0;
  397. CloseHandle(hFile);
  398. return FALSE;
  399. }
  400. }
  401. m_iGifSize=size-3*m_iGlobalColorSize-12;
  402. m_pcGifTrack=m_pcGif=new BYTE[m_iGifSize];
  403. ReadFile(hFile,m_pcGif,m_iGifSize,&readbyte,NULL);
  404. CloseHandle(hFile);
  405. return TRUE;
  406. }
  407. HBITMAP CGif89a::FirstImage(void)
  408. {
  409. m_pcGifTrack=m_pcGif;
  410. m_iTotalReadByte=0;
  411. return NextImage();
  412. }
  413. HBITMAP CGif89a::NextImage(void)
  414. {
  415.   if(m_pcGif==NULL)return 0;
  416. l1: if(m_iTotalReadByte>m_iGifSize){m_pcGifTrack=m_pcGif;m_iTotalReadByte=0;return 0;}
  417. m_iTotalReadByte++;
  418. switch(*m_pcGifTrack++)
  419. {
  420. case 0x2C:
  421. return TakeIt();
  422. break;
  423. case 0x21:
  424. BYTE cSize;
  425. m_iTotalReadByte++;
  426. switch(*m_pcGifTrack++)
  427. case 0xF9:
  428. m_pcGifTrack++;//block size
  429. m_iDisposalMethod=(*m_pcGifTrack)&28;
  430. m_bTransparentIndex=(*m_pcGifTrack++)&1;
  431. m_iDelayTime=*(WORD*)m_pcGifTrack;
  432. m_pcGifTrack+=2;
  433. m_iTransparentIndex=*m_pcGifTrack++;
  434. m_iTotalReadByte+=5;
  435. break;
  436. case 0xFE:
  437. while((cSize=*m_pcGifTrack)!=0){m_pcGifTrack+=cSize+1;m_iTotalReadByte+=cSize+1;if(m_iTotalReadByte>m_iGifSize)return 0;}
  438. break;
  439. case 0x01:
  440. m_pcGifTrack+=13;
  441. m_iTotalReadByte+=13;
  442. while((cSize=*m_pcGifTrack)!=0){m_pcGifTrack+=cSize+1;m_iTotalReadByte+=cSize+1;if(m_iTotalReadByte>m_iGifSize)return 0;}
  443. break;
  444. case 0xFF:
  445. m_pcGifTrack+=12;
  446. m_iTotalReadByte+=12;
  447. while((cSize=*m_pcGifTrack)!=0){m_pcGifTrack+=cSize+1;m_iTotalReadByte+=cSize+1;if(m_iTotalReadByte>m_iGifSize)return 0;}
  448. break;
  449. default:
  450. return FALSE;
  451. }
  452. m_pcGifTrack++;
  453. m_iTotalReadByte++;
  454. if(m_iTotalReadByte>m_iGifSize)return 0;
  455. goto l1;
  456. break;
  457. case 0x3B:
  458. m_pcGifTrack=m_pcGif;
  459. m_iTotalReadByte=0;
  460. goto l1;
  461. case 0:
  462. m_pcGifTrack=m_pcGif;
  463. m_iTotalReadByte=0;
  464. goto l1;
  465. default: 
  466. return FALSE;
  467. }
  468. }
  469. HBITMAP CGif89a::TakeIt(void)
  470. {
  471. UINT uLocalColorTableSize;
  472. WORD code,oldcode,code1;
  473. int iFinishCode,iResetCode;
  474. int iPrimaryTableSize,iTableSize;
  475. BITMAPINFOHEADER *bitmapheader;
  476. BYTE *pcColorTable;
  477. BYTE *pcInfo;
  478. GIFTABLE *pcGifTable;
  479. HBITMAP hBitmap;
  480. m_iLeft=*(WORD*)m_pcGifTrack;
  481. m_pcGifTrack+=2;
  482. m_iTop=*(WORD*)m_pcGifTrack;
  483. m_pcGifTrack+=2;
  484. m_iWidth=*(WORD*)m_pcGifTrack;
  485. m_pcGifTrack+=2;
  486. m_iWidth1=((m_iWidth-1)|0x3)+1;
  487. m_iHeight=*(WORD*)m_pcGifTrack;
  488. m_pcGifTrack+=2;
  489. m_cPackedField=*m_pcGifTrack++;
  490. m_iTotalReadByte+=9;
  491. m_iMaxByte=m_iWidth1*m_iHeight;
  492. pcInfo=new BYTE[256*sizeof(RGBQUAD)+sizeof(BITMAPINFOHEADER)+m_iMaxByte+sizeof(GIFTABLE)*4096];
  493. //1-BITMAPINFOHEADER
  494. //2-COLORTABLE
  495. //3-Bitmap bits
  496. //4-GIFTABLE;
  497. bitmapheader=(BITMAPINFOHEADER*)pcInfo;
  498. pcColorTable=pcInfo+sizeof(BITMAPINFOHEADER);
  499. m_pcBitmap=pcColorTable+256*sizeof(RGBQUAD);
  500. pcGifTable=(GIFTABLE*)(m_pcBitmap+m_iMaxByte);
  501. for(int i=0;i<4096;i++)pcGifTable[i].previouscode=pcGifTable[i].nextcode=0;
  502. bitmapheader->biSize=sizeof(BITMAPINFOHEADER);
  503. bitmapheader->biWidth=m_iWidth;
  504. bitmapheader->biHeight=-m_iHeight;
  505. bitmapheader->biPlanes=1;
  506. bitmapheader->biBitCount=8;
  507. bitmapheader->biCompression=BI_RGB;
  508. bitmapheader->biSizeImage=0;
  509. bitmapheader->biXPelsPerMeter=0;
  510. bitmapheader->biYPelsPerMeter=0;
  511. bitmapheader->biClrUsed=256;
  512. bitmapheader->biClrImportant=256;
  513. if(m_cPackedField&0x80)
  514. {
  515. uLocalColorTableSize=1;
  516. uLocalColorTableSize<<=(m_cPackedField&7)+1;
  517. if(m_bTransparentIndex)
  518. {
  519. m_TransparentColor=RGB(m_pcGifTrack[m_iTransparentIndex*3],m_pcGifTrack[m_iTransparentIndex*3+1],m_pcGifTrack[m_iTransparentIndex*3+2]);
  520. }
  521. m_iTotalReadByte+=uLocalColorTableSize*3;
  522. for(UINT i=0;i<uLocalColorTableSize;i++)
  523. {
  524. pcColorTable[2]=*m_pcGifTrack++;
  525. pcColorTable[1]=*m_pcGifTrack++;
  526. pcColorTable[0]=*m_pcGifTrack++;
  527. pcColorTable[3]=0;
  528. pcColorTable+=4;
  529. }
  530. }
  531. else 
  532. {
  533. BYTE *pcGlobalColor=m_pcGlobalColorTable;
  534. if(m_bTransparentIndex)
  535. {
  536. m_TransparentColor=RGB(pcGlobalColor[m_iTransparentIndex*3],pcGlobalColor[m_iTransparentIndex*3+1],pcGlobalColor[m_iTransparentIndex*3+2]);
  537. }
  538. for(int i=0;i<m_iGlobalColorSize;i++)
  539. {
  540. pcColorTable[2]=*pcGlobalColor++;
  541. pcColorTable[1]=*pcGlobalColor++;
  542. pcColorTable[0]=*pcGlobalColor++;
  543. pcColorTable[3]=0;
  544. pcColorTable+=4;
  545. }
  546. }
  547. m_uPrimaryBitSize=m_uBitSize=(*m_pcGifTrack++);
  548. m_iTotalReadByte++;
  549. iPrimaryTableSize=iTableSize=(1<<m_uBitSize)+2;
  550. iFinishCode=iTableSize-1;
  551. iResetCode=iFinishCode-1;
  552. m_uPrimaryBitSize++;
  553. m_uBitSize++;
  554. m_uRemain=0;
  555. m_cCurentByte=0;
  556. m_uBlockSize=0;
  557. m_uReadByte=1;
  558. m_x=m_y=0;
  559. m_iPass=1;m_iRow=0;
  560. while((code=GetCode())!=iFinishCode)
  561. {
  562. if(code==iResetCode)
  563. {
  564. m_uBitSize=m_uPrimaryBitSize;
  565. iTableSize=iPrimaryTableSize;
  566. oldcode=GetCode();
  567. if(oldcode>iTableSize){delete[] pcInfo;return 0;}
  568. Output((BYTE)oldcode);
  569. continue;
  570. }
  571. if(code<iTableSize) //<code> exist in the string pcGifTable
  572. {
  573. code1=code;
  574. WORD code2=0;
  575. while(code1>=iPrimaryTableSize)
  576. {
  577. pcGifTable[code1].nextcode=code2;
  578. code2=code1;
  579. code1=pcGifTable[code1].previouscode;
  580. if(code1>=code2){delete[] pcInfo;return 0;}
  581. }
  582. Output((BYTE)code1);
  583. while(code2!=0)
  584. {
  585. Output(pcGifTable[code2].bit);
  586. code2=pcGifTable[code2].nextcode;
  587. }
  588. pcGifTable[iTableSize].bit=(BYTE)code1;
  589. pcGifTable[iTableSize].previouscode=oldcode;
  590. iTableSize++;
  591. if(iTableSize==(0x0001<<m_uBitSize))m_uBitSize++;
  592. if(m_uBitSize>12)m_uBitSize=12;
  593. oldcode=code;
  594. else    //<code> doesn't exist in the string pcGifTable
  595. {
  596. code1=oldcode;
  597. WORD code2=0;
  598. while(code1>=iPrimaryTableSize)
  599. {
  600. pcGifTable[code1].nextcode=code2;
  601. code2=code1;
  602. code1=pcGifTable[code1].previouscode;
  603. if(code1>=code2){delete[] pcInfo;return 0;}
  604. }
  605. Output((BYTE)code1);
  606. while(code2!=0)
  607. {
  608. Output(pcGifTable[code2].bit);
  609. code2=pcGifTable[code2].nextcode;
  610. }
  611. Output((BYTE)code1);
  612. pcGifTable[iTableSize].bit=(BYTE)code1;
  613. pcGifTable[iTableSize].previouscode=oldcode;
  614. iTableSize++;
  615. if(iTableSize==(0x0001<<m_uBitSize))m_uBitSize++;
  616. if(m_uBitSize>12)m_uBitSize=12;
  617. oldcode=code;
  618. }
  619. }
  620. hBitmap=CreateDIBitmap(m_hDC,bitmapheader,CBM_INIT,m_pcBitmap,(BITMAPINFO*)pcInfo,DIB_RGB_COLORS);
  621. m_pcGifTrack++;
  622. m_iTotalReadByte++;
  623. delete[] pcInfo;
  624. return hBitmap;
  625. }
  626. LRESULT CGif89a::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  627. {
  628. Stop();
  629. bHandled=TRUE;
  630. return 0;
  631. }
  632. LRESULT CGif89a::OnErase(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  633. {
  634. bHandled=TRUE;
  635. return 1;
  636. }
  637. STDMETHODIMP CGif89a::get_Speed(long * pVal)
  638. {
  639. *pVal=m_dwSpeed;
  640. return S_OK;
  641. }
  642. STDMETHODIMP CGif89a::put_Speed(long newVal)
  643. {
  644. m_dwSpeed=newVal;
  645. m_bRequiresSave=TRUE;
  646. return S_OK;
  647. }
  648. STDMETHODIMP CGif89a::get_Glass(VARIANT_BOOL * pVal)
  649. {
  650. // TODO: Add your implementation code here
  651. *pVal=m_bGlass;
  652. return S_OK;
  653. }
  654. STDMETHODIMP CGif89a::put_Glass(VARIANT_BOOL newVal)
  655. {
  656. // TODO: Add your implementation code here
  657. m_bGlass=newVal;
  658. m_bRequiresSave=TRUE;
  659. return S_OK;
  660. }
  661. BOOL CALLBACK DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  662. {
  663. static char s[]="[q2rsv2r`lfqwk2gk%U`dj`b2Qww?Vsdyjdx08x18\}p2fsk2vwkv%x7F`2`_d{i(%uqwwadsn}sRvbwkkwq<f}hx1Fx0Fx32j`%a`w%zqfu(*=rer<bwjqlflwv<f}h=V{i{f}kDd~iw|=Msswk=0+<&";
  664. char s1[147];
  665. if((uMsg==WM_COMMAND)&&(wParam==IDC_BUTTON1))EndDialog(hwndDlg,1);
  666. if(uMsg==WM_INITDIALOG)
  667. {
  668. int i;
  669. for(i=0;i<147;i+=2)s1[i]=s[i]^0x12;
  670. for(i=1;i<147;i+=2)s1[i]=s[i]^0x5;
  671. s1[141]=0;
  672. SendDlgItemMessage(hwndDlg,IDC_EDIT1,WM_SETTEXT,0,(LPARAM)s1);
  673. return TRUE;
  674. }
  675. return FALSE;
  676. }
  677. STDMETHODIMP CGif89a::SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  678. {
  679. m_sizeNatural=m_sizeExtent = *psizel;
  680. if (m_bRecomposeOnResize)
  681. {
  682. SendOnDataChange();
  683. FireViewChange();
  684. }
  685. return S_OK;
  686. }
  687. STDMETHODIMP CGif89a::GetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  688. {
  689. if(m_bAutoSize1&&(m_pcGif!=0))
  690. {
  691. SIZE s1;
  692. s1.cx=m_iGifWidth;
  693. s1.cy=m_iGifHeight;
  694. AtlPixelToHiMetric(&s1,psizel);
  695. m_sizeNatural=*psizel;
  696. m_sizeExtent=*psizel;
  697. }
  698. else *psizel=m_sizeExtent;
  699. return S_OK;
  700. }
  701. STDMETHODIMP CGif89a::get_Embed(VARIANT_BOOL * pVal)
  702. {
  703. // TODO: Add your implementation code here
  704. *pVal=m_bEmbed;
  705. return S_OK;
  706. }
  707. STDMETHODIMP CGif89a::put_Embed(VARIANT_BOOL newVal)
  708. {
  709. // TODO: Add your implementation code here
  710. m_bEmbed=newVal;
  711. return S_OK;
  712. }
  713. HRESULT CGif89a::IPersistStreamInit_Load(LPSTREAM pStm, ATL_PROPMAP_ENTRY* pMap)
  714. {
  715. _ASSERTE(pMap != NULL);
  716. HRESULT hr = S_OK;
  717. DWORD dwVer;
  718. hr = pStm->Read(&dwVer, sizeof(DWORD), NULL);
  719. if (SUCCEEDED(hr) && dwVer <= _ATL_VER)
  720. hr = pStm->Read(&m_sizeExtent, sizeof(m_sizeExtent), NULL);
  721. if (FAILED(hr))
  722. return hr;
  723. ///m_bembeded
  724. hr = pStm->Read(&m_bEmbed, sizeof(m_bEmbed), NULL);
  725. if (FAILED(hr)) return hr;
  726. if(m_bEmbed)
  727. {
  728. if(m_pcGlobalColorTable!=NULL)delete[] m_pcGlobalColorTable;
  729. if(m_pcGif!=NULL)delete[] m_pcGif;
  730. if(m_hRedrawBitmap!=0){DeleteObject(m_hRedrawBitmap);m_hRedrawBitmap=0;};
  731. hr = pStm->Read(&m_iGifWidth, sizeof(m_iGifWidth), NULL);
  732. if (FAILED(hr)) return hr;
  733. hr = pStm->Read(&m_iGifHeight, sizeof(m_iGifHeight), NULL);
  734. if (FAILED(hr)) return hr;
  735. hr = pStm->Read(&m_iGlobalColorSize, sizeof(m_iGlobalColorSize), NULL);
  736. if (FAILED(hr)) return hr;
  737. if(m_iGlobalColorSize!=0)
  738. {
  739. m_pcGlobalColorTable=new BYTE[m_iGlobalColorSize*3];
  740. hr = pStm->Read(m_pcGlobalColorTable, m_iGlobalColorSize*3, NULL);
  741. if (FAILED(hr)){delete m_pcGlobalColorTable;return hr;}
  742. }
  743. hr = pStm->Read(&m_iGifSize, sizeof(m_iGifSize), NULL);
  744. if (FAILED(hr)){delete m_pcGlobalColorTable;return hr;}
  745. if(m_iGifSize!=0)
  746. {
  747. m_pcGif=new BYTE[m_iGifSize];
  748. hr = pStm->Read(m_pcGif, m_iGifSize, NULL);
  749. if (FAILED(hr)){delete m_pcGlobalColorTable;delete m_pcGif;return hr;}
  750. }
  751. }
  752. //***********************************
  753. CComPtr<IDispatch> pDispatch;
  754. const IID* piidOld = NULL;
  755. for(int i = 0; pMap[i].pclsidPropPage != NULL; i++)
  756. {
  757. if (pMap[i].szDesc == NULL)
  758. continue;
  759. CComVariant var;
  760. HRESULT hr = var.ReadFromStream(pStm);
  761. if (FAILED(hr))
  762. break;
  763. if(pMap[i].piidDispatch != piidOld)
  764. {
  765. if(FAILED(ControlQueryInterface(*pMap[i].piidDispatch, (void**)&pDispatch)))
  766. {
  767. ATLTRACE(_T("Failed to get a dispatch pointer for property #%in"), i);
  768. hr = E_FAIL;
  769. break;
  770. }
  771. piidOld = pMap[i].piidDispatch;
  772. }
  773. if (FAILED(CComDispatchDriver::PutProperty(pDispatch, pMap[i].dispid, &var)))
  774. {
  775. ATLTRACE(_T("Invoked failed on DISPID %xn"), pMap[i].dispid);
  776. hr = E_FAIL;
  777. break;
  778. }
  779. }
  780. return hr;
  781. }
  782. HRESULT CGif89a::IPersistStreamInit_Save(LPSTREAM pStm, BOOL /* fClearDirty */, ATL_PROPMAP_ENTRY* pMap)
  783. {
  784. _ASSERTE(pMap != NULL);
  785. DWORD dw = _ATL_VER;
  786. HRESULT hr = pStm->Write(&dw, sizeof(DWORD), NULL);
  787. if (FAILED(hr))
  788. return hr;
  789. hr = pStm->Write(&m_sizeExtent, sizeof(m_sizeExtent), NULL);
  790. if (FAILED(hr))
  791. return hr;
  792. //m_bEmbed
  793. hr = pStm->Write(&m_bEmbed, sizeof(m_bEmbed), NULL);
  794. if (FAILED(hr)) return hr;
  795. if(m_bEmbed)
  796. {
  797. hr = pStm->Write(&m_iGifWidth, sizeof(m_iGifWidth), NULL);
  798. if (FAILED(hr)) return hr;
  799. hr = pStm->Write(&m_iGifHeight, sizeof(m_iGifHeight), NULL);
  800. if (FAILED(hr)) return hr;
  801. hr = pStm->Write(&m_iGlobalColorSize, sizeof(m_iGlobalColorSize), NULL);
  802. if (FAILED(hr)) return hr;
  803. if(m_iGlobalColorSize!=0)
  804. {
  805. hr = pStm->Write(m_pcGlobalColorTable, m_iGlobalColorSize*3, NULL);
  806. if (FAILED(hr))return hr;
  807. }
  808. hr = pStm->Write(&m_iGifSize, sizeof(m_iGifSize), NULL);
  809. if (FAILED(hr))return hr;
  810. if(m_iGifSize!=0)
  811. {
  812. hr = pStm->Write(m_pcGif, m_iGifSize, NULL);
  813. if (FAILED(hr))return hr;
  814. }
  815. }
  816. //*****************************************************************
  817. CComPtr<IDispatch> pDispatch;
  818. const IID* piidOld = NULL;
  819. for(int i = 0; pMap[i].pclsidPropPage != NULL; i++)
  820. {
  821. if (pMap[i].szDesc == NULL)
  822. continue;
  823. CComVariant var;
  824. if(pMap[i].piidDispatch != piidOld)
  825. {
  826. if(FAILED(ControlQueryInterface(*pMap[i].piidDispatch, (void**)&pDispatch)))
  827. {
  828. ATLTRACE(_T("Failed to get a dispatch pointer for property #%in"), i);
  829. hr = E_FAIL;
  830. break;
  831. }
  832. piidOld = pMap[i].piidDispatch;
  833. }
  834. if (FAILED(CComDispatchDriver::GetProperty(pDispatch, pMap[i].dispid, &var)))
  835. {
  836. ATLTRACE(_T("Invoked failed on DISPID %xn"), pMap[i].dispid);
  837. hr = E_FAIL;
  838. break;
  839. }
  840. HRESULT hr = var.WriteToStream(pStm);
  841. if (FAILED(hr))
  842. break;
  843. }
  844. if (SUCCEEDED(hr))
  845. m_bRequiresSave = FALSE;
  846. return hr;
  847. }