mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-12-22 16:37:50 +08:00
375 lines
10 KiB
Diff
375 lines
10 KiB
Diff
|
diff --git a/DuiLib/Control/UIGifAnim-patch.cpp b/DuiLib/Control/UIGifAnim-patch.cpp
|
||
|
new file mode 100644
|
||
|
index 0000000..61aa32f
|
||
|
--- /dev/null
|
||
|
+++ b/DuiLib/Control/UIGifAnim-patch.cpp
|
||
|
@@ -0,0 +1,368 @@
|
||
|
+#include "StdAfx.h"
|
||
|
+#include "UIGifAnim.h"
|
||
|
+
|
||
|
+///////////////////////////////////////////////////////////////////////////////////////
|
||
|
+DECLARE_HANDLE(HZIP); // An HZIP identifies a zip file that has been opened
|
||
|
+typedef DWORD ZRESULT;
|
||
|
+typedef struct
|
||
|
+{
|
||
|
+ int index; // index of this file within the zip
|
||
|
+ char name[MAX_PATH]; // filename within the zip
|
||
|
+ DWORD attr; // attributes, as in GetFileAttributes.
|
||
|
+ FILETIME atime,ctime,mtime;// access, create, modify filetimes
|
||
|
+ long comp_size; // sizes of item, compressed and uncompressed. These
|
||
|
+ long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
||
|
+} ZIPENTRY;
|
||
|
+typedef struct
|
||
|
+{
|
||
|
+ int index; // index of this file within the zip
|
||
|
+ TCHAR name[MAX_PATH]; // filename within the zip
|
||
|
+ DWORD attr; // attributes, as in GetFileAttributes.
|
||
|
+ FILETIME atime,ctime,mtime;// access, create, modify filetimes
|
||
|
+ long comp_size; // sizes of item, compressed and uncompressed. These
|
||
|
+ long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
||
|
+} ZIPENTRYW;
|
||
|
+#define OpenZip OpenZipU
|
||
|
+#define CloseZip(hz) CloseZipU(hz)
|
||
|
+extern HZIP OpenZipU(void *z,unsigned int len,DWORD flags);
|
||
|
+extern ZRESULT CloseZipU(HZIP hz);
|
||
|
+#ifdef _UNICODE
|
||
|
+#define ZIPENTRY ZIPENTRYW
|
||
|
+#define GetZipItem GetZipItemW
|
||
|
+#define FindZipItem FindZipItemW
|
||
|
+#else
|
||
|
+#define GetZipItem GetZipItemA
|
||
|
+#define FindZipItem FindZipItemA
|
||
|
+#endif
|
||
|
+extern ZRESULT GetZipItemA(HZIP hz, int index, ZIPENTRY *ze);
|
||
|
+extern ZRESULT GetZipItemW(HZIP hz, int index, ZIPENTRYW *ze);
|
||
|
+extern ZRESULT FindZipItemA(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze);
|
||
|
+extern ZRESULT FindZipItemW(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRYW *ze);
|
||
|
+extern ZRESULT UnzipItem(HZIP hz, int index, void *dst, unsigned int len, DWORD flags);
|
||
|
+///////////////////////////////////////////////////////////////////////////////////////
|
||
|
+
|
||
|
+namespace DuiLib
|
||
|
+{
|
||
|
+
|
||
|
+ CGifAnimUI::CGifAnimUI(void)
|
||
|
+ {
|
||
|
+ m_pGifImage = NULL;
|
||
|
+ m_pPropertyItem = NULL;
|
||
|
+ m_nFrameCount = 0;
|
||
|
+ m_nFramePosition = 0;
|
||
|
+ m_bIsAutoPlay = true;
|
||
|
+ m_bIsAutoSize = false;
|
||
|
+ m_bIsPlaying = false;
|
||
|
+ m_pStream = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
+ CGifAnimUI::~CGifAnimUI(void)
|
||
|
+ {
|
||
|
+ DeleteGif();
|
||
|
+ m_pManager->KillTimer( this, EVENT_TIEM_ID );
|
||
|
+
|
||
|
+ }
|
||
|
+
|
||
|
+ LPCTSTR CGifAnimUI::GetClass() const
|
||
|
+ {
|
||
|
+ return DUI_CTR_GIFANIM;
|
||
|
+ }
|
||
|
+
|
||
|
+ LPVOID CGifAnimUI::GetInterface( LPCTSTR pstrName )
|
||
|
+ {
|
||
|
+ if( _tcscmp(pstrName, DUI_CTR_GIFANIM) == 0 ) return static_cast<CGifAnimUI*>(this);
|
||
|
+ return CControlUI::GetInterface(pstrName);
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::DoInit()
|
||
|
+ {
|
||
|
+ InitGifImage();
|
||
|
+ }
|
||
|
+
|
||
|
+ bool CGifAnimUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
|
||
|
+ {
|
||
|
+ if ( NULL == m_pGifImage )
|
||
|
+ {
|
||
|
+ InitGifImage();
|
||
|
+ }
|
||
|
+ DrawFrame( hDC );
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::DoEvent( TEventUI& event )
|
||
|
+ {
|
||
|
+ if( event.Type == UIEVENT_TIMER )
|
||
|
+ OnTimer( (UINT_PTR)event.wParam );
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::SetVisible(bool bVisible /* = true */)
|
||
|
+ {
|
||
|
+ CControlUI::SetVisible(bVisible);
|
||
|
+ if (bVisible)
|
||
|
+ PlayGif();
|
||
|
+ else
|
||
|
+ StopGif();
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
|
||
|
+ {
|
||
|
+ if( _tcscmp(pstrName, _T("bkimage")) == 0 ) SetBkImage(pstrValue);
|
||
|
+ else if( _tcscmp(pstrName, _T("autoplay")) == 0 ) {
|
||
|
+ SetAutoPlay(_tcscmp(pstrValue, _T("true")) == 0);
|
||
|
+ }
|
||
|
+ else if( _tcscmp(pstrName, _T("autosize")) == 0 ) {
|
||
|
+ SetAutoSize(_tcscmp(pstrValue, _T("true")) == 0);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ CControlUI::SetAttribute(pstrName, pstrValue);
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::SetBkImage(LPCTSTR pStrImage)
|
||
|
+ {
|
||
|
+ if( m_sBkImage == pStrImage || NULL == pStrImage) return;
|
||
|
+
|
||
|
+ m_sBkImage = pStrImage;
|
||
|
+
|
||
|
+ StopGif();
|
||
|
+ DeleteGif();
|
||
|
+
|
||
|
+ Invalidate();
|
||
|
+
|
||
|
+ }
|
||
|
+
|
||
|
+ LPCTSTR CGifAnimUI::GetBkImage()
|
||
|
+ {
|
||
|
+ return m_sBkImage.GetData();
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::SetAutoPlay(bool bIsAuto)
|
||
|
+ {
|
||
|
+ m_bIsAutoPlay = bIsAuto;
|
||
|
+ }
|
||
|
+
|
||
|
+ bool CGifAnimUI::IsAutoPlay() const
|
||
|
+ {
|
||
|
+ return m_bIsAutoPlay;
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::SetAutoSize(bool bIsAuto)
|
||
|
+ {
|
||
|
+ m_bIsAutoSize = bIsAuto;
|
||
|
+ }
|
||
|
+
|
||
|
+ bool CGifAnimUI::IsAutoSize() const
|
||
|
+ {
|
||
|
+ return m_bIsAutoSize;
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::PlayGif()
|
||
|
+ {
|
||
|
+ if (m_bIsPlaying || m_pGifImage == NULL)
|
||
|
+ {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ long lPause = ((long*) m_pPropertyItem->value)[m_nFramePosition] * 10;
|
||
|
+ if ( lPause == 0 ) lPause = 100;
|
||
|
+ m_pManager->SetTimer( this, EVENT_TIEM_ID, lPause );
|
||
|
+
|
||
|
+ m_bIsPlaying = true;
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::PauseGif()
|
||
|
+ {
|
||
|
+ if (!m_bIsPlaying || m_pGifImage == NULL)
|
||
|
+ {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ m_pManager->KillTimer(this, EVENT_TIEM_ID);
|
||
|
+ this->Invalidate();
|
||
|
+ m_bIsPlaying = false;
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::StopGif()
|
||
|
+ {
|
||
|
+ if (!m_bIsPlaying)
|
||
|
+ {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ m_pManager->KillTimer(this, EVENT_TIEM_ID);
|
||
|
+ m_nFramePosition = 0;
|
||
|
+ this->Invalidate();
|
||
|
+ m_bIsPlaying = false;
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::InitGifImage()
|
||
|
+ {
|
||
|
+ m_pGifImage = LoadGifFromFile(GetBkImage());
|
||
|
+ if ( NULL == m_pGifImage ) return;
|
||
|
+ UINT nCount = 0;
|
||
|
+ nCount = m_pGifImage->GetFrameDimensionsCount();
|
||
|
+ GUID* pDimensionIDs = new GUID[ nCount ];
|
||
|
+ m_pGifImage->GetFrameDimensionsList( pDimensionIDs, nCount );
|
||
|
+ m_nFrameCount = m_pGifImage->GetFrameCount( &pDimensionIDs[0] );
|
||
|
+ int nSize = m_pGifImage->GetPropertyItemSize( PropertyTagFrameDelay );
|
||
|
+ m_pPropertyItem = (Gdiplus::PropertyItem*) malloc( nSize );
|
||
|
+ m_pGifImage->GetPropertyItem( PropertyTagFrameDelay, nSize, m_pPropertyItem );
|
||
|
+ delete[] pDimensionIDs;
|
||
|
+ pDimensionIDs = NULL;
|
||
|
+
|
||
|
+ if (m_bIsAutoSize)
|
||
|
+ {
|
||
|
+ SetFixedWidth(m_pGifImage->GetWidth());
|
||
|
+ SetFixedHeight(m_pGifImage->GetHeight());
|
||
|
+ }
|
||
|
+ if (m_bIsAutoPlay && nSize > 0)
|
||
|
+ {
|
||
|
+ PlayGif();
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::DeleteGif()
|
||
|
+ {
|
||
|
+ if (m_pStream != NULL )
|
||
|
+ {
|
||
|
+ m_pStream->Release();
|
||
|
+ m_pStream = NULL;
|
||
|
+ }
|
||
|
+ if ( m_pGifImage != NULL )
|
||
|
+ {
|
||
|
+ delete m_pGifImage;
|
||
|
+ m_pGifImage = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ if ( m_pPropertyItem != NULL )
|
||
|
+ {
|
||
|
+ free( m_pPropertyItem );
|
||
|
+ m_pPropertyItem = NULL;
|
||
|
+ }
|
||
|
+ m_nFrameCount = 0;
|
||
|
+ m_nFramePosition = 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::OnTimer( UINT_PTR idEvent )
|
||
|
+ {
|
||
|
+ if ( idEvent != EVENT_TIEM_ID )
|
||
|
+ return;
|
||
|
+ m_pManager->KillTimer( this, EVENT_TIEM_ID );
|
||
|
+ this->Invalidate();
|
||
|
+
|
||
|
+ m_nFramePosition = (++m_nFramePosition) % m_nFrameCount;
|
||
|
+
|
||
|
+ long lPause = ((long*) m_pPropertyItem->value)[m_nFramePosition] * 10;
|
||
|
+ if ( lPause == 0 ) lPause = 100;
|
||
|
+ m_pManager->SetTimer( this, EVENT_TIEM_ID, lPause );
|
||
|
+ }
|
||
|
+
|
||
|
+ void CGifAnimUI::DrawFrame( HDC hDC )
|
||
|
+ {
|
||
|
+ if ( NULL == hDC || NULL == m_pGifImage ) return;
|
||
|
+ GUID pageGuid = Gdiplus::FrameDimensionTime;
|
||
|
+ Gdiplus::Graphics graphics( hDC );
|
||
|
+ graphics.DrawImage( m_pGifImage, m_rcItem.left, m_rcItem.top, m_rcItem.right-m_rcItem.left, m_rcItem.bottom-m_rcItem.top );
|
||
|
+ m_pGifImage->SelectActiveFrame( &pageGuid, m_nFramePosition );
|
||
|
+ }
|
||
|
+
|
||
|
+ Gdiplus::Image* CGifAnimUI::LoadGifFromFile(LPCTSTR pstrGifPath)
|
||
|
+ {
|
||
|
+ LPBYTE pData = NULL;
|
||
|
+ DWORD dwSize = 0;
|
||
|
+
|
||
|
+ do
|
||
|
+ {
|
||
|
+ CDuiString sFile = CPaintManagerUI::GetResourcePath();
|
||
|
+ if( CPaintManagerUI::GetResourceZip().IsEmpty() ) {
|
||
|
+ sFile += pstrGifPath;
|
||
|
+ HANDLE hFile = ::CreateFile(sFile.GetData(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, \
|
||
|
+ FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
+ if( hFile == INVALID_HANDLE_VALUE ) break;
|
||
|
+ dwSize = ::GetFileSize(hFile, NULL);
|
||
|
+ if( dwSize == 0 ) break;
|
||
|
+
|
||
|
+ DWORD dwRead = 0;
|
||
|
+ pData = new BYTE[ dwSize ];
|
||
|
+ ::ReadFile( hFile, pData, dwSize, &dwRead, NULL );
|
||
|
+ ::CloseHandle( hFile );
|
||
|
+
|
||
|
+ if( dwRead != dwSize ) {
|
||
|
+ delete[] pData;
|
||
|
+ pData = NULL;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else {
|
||
|
+ sFile += CPaintManagerUI::GetResourceZip();
|
||
|
+ HZIP hz = NULL;
|
||
|
+ if( CPaintManagerUI::IsCachedResourceZip() ) hz = (HZIP)CPaintManagerUI::GetResourceZipHandle();
|
||
|
+ else hz = OpenZip((void*)sFile.GetData(), 0, 2);
|
||
|
+ if( hz == NULL ) break;
|
||
|
+ ZIPENTRY ze;
|
||
|
+ int i;
|
||
|
+ if( FindZipItem(hz, pstrGifPath, true, &i, &ze) != 0 ) break;
|
||
|
+ dwSize = ze.unc_size;
|
||
|
+ if( dwSize == 0 ) break;
|
||
|
+ pData = new BYTE[ dwSize ];
|
||
|
+ int res = UnzipItem(hz, i, pData, dwSize, 3);
|
||
|
+ if( res != 0x00000000 && res != 0x00000600) {
|
||
|
+ delete[] pData;
|
||
|
+ pData = NULL;
|
||
|
+ if( !CPaintManagerUI::IsCachedResourceZip() ) CloseZip(hz);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ if( !CPaintManagerUI::IsCachedResourceZip() ) CloseZip(hz);
|
||
|
+ }
|
||
|
+
|
||
|
+ } while (0);
|
||
|
+
|
||
|
+ while (!pData)
|
||
|
+ {
|
||
|
+ HANDLE hFile = ::CreateFile(pstrGifPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, \
|
||
|
+ FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
+ if( hFile == INVALID_HANDLE_VALUE ) break;
|
||
|
+ dwSize = ::GetFileSize(hFile, NULL);
|
||
|
+ if( dwSize == 0 ) break;
|
||
|
+
|
||
|
+ DWORD dwRead = 0;
|
||
|
+ pData = new BYTE[ dwSize ];
|
||
|
+ ::ReadFile( hFile, pData, dwSize, &dwRead, NULL );
|
||
|
+ ::CloseHandle( hFile );
|
||
|
+
|
||
|
+ if( dwRead != dwSize ) {
|
||
|
+ delete[] pData;
|
||
|
+ pData = NULL;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ if (!pData)
|
||
|
+ {
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ Gdiplus::Image* pImage = LoadGifFromMemory(pData, dwSize);
|
||
|
+ delete[] pData;
|
||
|
+ return pImage;
|
||
|
+ }
|
||
|
+
|
||
|
+ Gdiplus::Image* CGifAnimUI::LoadGifFromMemory( LPVOID pBuf,size_t dwSize )
|
||
|
+ {
|
||
|
+ HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize);
|
||
|
+ BYTE* pMem = (BYTE*)::GlobalLock(hMem);
|
||
|
+
|
||
|
+ memcpy(pMem, pBuf, dwSize);
|
||
|
+ ::GlobalUnlock(hMem);
|
||
|
+
|
||
|
+ ::CreateStreamOnHGlobal(hMem, TRUE, &m_pStream);
|
||
|
+ Gdiplus::Image *pImg = Gdiplus::Image::FromStream(m_pStream);
|
||
|
+ if(!pImg || pImg->GetLastStatus() != Gdiplus::Ok)
|
||
|
+ {
|
||
|
+ m_pStream->Release();
|
||
|
+ m_pStream = NULL;
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ return pImg;
|
||
|
+ }
|
||
|
+
|
||
|
+}
|