轉載自:http://blog.csdn.net/zhaoze87/article/details/6369593
在很多軟件的CListCtrl列表控件都能顯示Gif動態(tài)圖標,昨天我也剛好要實現(xiàn)這個功能,向同事請教后,他們發(fā)給我一個ImageEx顯示GIF的例子。我拿這個例子來研究,發(fā)現(xiàn)上面的Demo只是在窗口中顯示一個Gif表情,但是我要用的是在列表控件中顯示,拖動滾動條的時候可以顯示和隱藏GIF圖標;同時這個類為每一個要顯示GIF對象都創(chuàng)建了一個線程,如果我要顯示幾百張GIF表情的話,要創(chuàng)建幾百個線程,這簡直是不可接受的。
于是我開始了解ImageEx顯示Gif的原理,期望可以在這個基礎上改進后能實現(xiàn)我的要求。ImageEx在創(chuàng)建對象是傳遞GIF資源ID或者是文件路徑后,然后會調用初始化函數(shù)InitAnimation(HWND hWnd, CPoint pt);傳遞一個窗口句柄和顯示位置。然后這個類讀取GIF的文件信息,得到幀數(shù)和每一幀的時間。在線程里面定時更新當前幀數(shù),同時將當前幀的圖片繪制到之前傳遞的窗口的指定位置。代碼如下:
1: long hmWidth = GIFWIDTH;//GetWidth();
2: long hmHeight = GIFHEIGHT;//GetHeight();
3:
4: HDC hDC = GetDC(m_hWnd);
5: if (hDC)
6: {
7: HBITMAP hMemBmp = CreateCompatibleBitmap(hDC, hmWidth, hmHeight);
8:
9: HDC hMemDC = CreateCompatibleDC(hDC);
10: HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hMemBmp);
11:
12: Rectangle(hMemDC, 0, 0, hmWidth, hmHeight);
13: Graphics graphics(hMemDC);
14: graphics.DrawImage(this, 1, 1, hmWidth-2, hmHeight-2);
15: BitBlt(hDC, 0, 0, hmWidth, hmHeight, hMemDC, 0, 0, SRCCOPY);
在我的需求里面由于滾動條的拖動,GIF的顯示位置也會變化,同時我可能還會在GIF上面繪制一些其他的圖標,如果以之前ImageEx的顯示方式,肯定會覆蓋掉我先繪制的圖標。所以我思考過后采取了一種新方案,ImageEx內部只負責更新當前的幀數(shù),然后定時刷新CListCtrl,CListCtrl在重繪的時候會取出GIF當前幀數(shù)的圖片,將其以背景圖片的方式繪制,然后在上面繪制其他圖片。
同時為了避免創(chuàng)建一個對象就開一個線程,我增加一個ImageManager類,這個類管理所有創(chuàng)建的ImageEx對象,同時只開啟一個線程,在線程函數(shù)里面定時查詢所有的ImageEx對象,如果某個ImageEx對象需要更新到下一幀,就調用SelectActiveFrame(&pageGuid, m_nFramePosition++); 切換到下一幀,這樣就實現(xiàn)了GIF的逐幀顯示效果。代碼片段如下:
1: //ImageManager遍歷調用更新ImageEx幀數(shù)代碼
2: for (ImageMap::iterator iter = m_ImageList.begin(); iter != m_ImageList.end(); iter++)
3: {
4: if (iter->second != NULL)
5: iter->second->DrawFrameGIF();
6: }
7:
8: //ImageEx更新當前幀數(shù)代碼 DrawFrameGIF
9: GUID pageGuid = FrameDimensionTime;
10: SelectActiveFrame(&pageGuid, m_nFramePosition++);
11:
12: if (m_nFramePosition >= m_nFrameCount)
13: m_nFramePosition = 0;
先插一個效果圖:
由于實際要求, 對于多行插入同一個GIF,在ImageManager只創(chuàng)建了一個對象,所以顯示的GIF的動畫的動作會一樣,這樣會減小內存消耗。
先放上一個執(zhí)行文件地址:http://download.csdn.net/detail/zhaoze87/3890938
附上代碼下載地址:http://download.csdn.net/detail/zhaoze87/3891058(之前的疏忽,沒有加上Gdi+的環(huán)境)
歡迎大家多多提意見!