imageshow.cpp

来自「类似QQ,MSN表情的richedit调用控件,实现gif的显示.」· C++ 代码 · 共 969 行 · 第 1/2 页

CPP
969
字号
// ImageShow.cpp : CImageShow 的实现
#include "stdafx.h"
#include "ImageOle.h"
#include "ImageShow.h"

// CImageShow

STDMETHODIMP CImageShow::get_Embed(VARIANT_BOOL* pVal)
{
	// TODO: 在此添加实现代码
	*pVal = m_bEmbed;
	return S_OK;
}

STDMETHODIMP CImageShow::put_Embed(VARIANT_BOOL newVal)
{
	// TODO: 在此添加实现代码

	m_bEmbed = newVal;
	return S_OK;
}

STDMETHODIMP CImageShow::get_FileName(BSTR* pVal)
{
	// TODO: 在此添加实现代码

	USES_CONVERSION;
	*pVal = T2BSTR(filename);
	return S_OK;
}

STDMETHODIMP CImageShow::put_FileName(BSTR newVal)
{
	// TODO: 在此添加实现代码
	USES_CONVERSION;
	lstrcpy(filename,OLE2T(newVal));	
	if( !Load(filename) )
	{
		FireViewChange();
		return S_OK;
	}
	if( m_bAutoStart )
		flag = 0;
	if( m_bAutoSize1 )
	{
		SIZEL size5;
		SIZEL size6;
		size5.cx = m_iGifWidth;
		size5.cy = m_iGifHeight;
		AtlPixelToHiMetric(&size5,&size6);
		m_rcPos.right  = m_iGifWidth + m_rcPos.left;
		m_rcPos.bottom = m_iGifHeight+ m_rcPos.top;
		SetExtent(DVASPECT_CONTENT,&size6);
		if( (m_spInPlaceSite != NULL) && m_bInPlaceActive )
			m_spInPlaceSite->OnPosRectChange(&m_rcPos);
		else if( m_hWnd != NULL )
			SetWindowPos(NULL,m_rcPos.left,m_rcPos.top,m_iGifWidth,m_iGifHeight,SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
	}

	FireViewChange();
	return S_OK;
}

STDMETHODIMP CImageShow::get_AutoStart(VARIANT_BOOL* pVal)
{
	// TODO: 在此添加实现代码
	*pVal = m_bAutoStart;
	return S_OK;
}

STDMETHODIMP CImageShow::put_AutoStart(VARIANT_BOOL newVal)
{
	// TODO: 在此添加实现代码
	m_bAutoStart	= newVal;
	m_bRequiresSave	= TRUE;
	return S_OK;
}

STDMETHODIMP CImageShow::Stop(void)
{
	// TODO: 在此添加实现代码

	m_HideWnd.KillThisTimer();
	if( m_EndRun != 5 )
		return S_OK;
	m_EndRun = 1;
	//while( m_EndRun != 2 );
	return S_OK;
}


STDMETHODIMP CImageShow::Play(void)
{
	// TODO: 在此添加实现代码

	HANDLE	hThread;
	DWORD	ThreadId;

	//GetAmbientUserMode(m_bRunMode);
	//if( m_hWnd == 0 && m_bRunMode )
	//	return S_OK;
	if( m_pcGif == 0 )
		return S_OK;
	if( m_EndRun == 5 )
		return S_OK;
	m_pcGifTrack     = m_pcGif;
	m_iTotalReadByte = 0;
	m_EndRun	= 5;
	/*hThread = CreateThread(NULL,
		                   0,
						   (unsigned long(_stdcall*)(void*))ThreadFunc,
						   this,
						   0,
						   &ThreadId);
	CloseHandle(hThread);*/
	//Play2();
	m_HideWnd.AttachCtl(this);                //将辅助类对象与本对象绑定
	m_HideWnd.SetThisTimer(ID_TIMER, 500, NULL);//为辅助类对象设置时钟
	//Play2();
	return S_OK;
}


STDMETHODIMP CImageShow::get_Glass(VARIANT_BOOL* pVal)
{
	// TODO: 在此添加实现代码
	*pVal = m_bGlass;
	return S_OK;
}

STDMETHODIMP CImageShow::put_Glass(VARIANT_BOOL newVal)
{
	// TODO: 在此添加实现代码
	m_bGlass		= newVal;
	m_bRequiresSave	= TRUE;
	return S_OK;
}

BOOL CALLBACK DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static char s[]="[q2rsv2r`lfqwk2gk%U`dj`b2Qww?Vsdyjd\x08\x18\\}p2fsk2vwkv%\x7F`2`_d{i(%uqwwadsn}sRvbwkkwq<f}h\x1F\x0F\x32j`%a`w%zqfu(*=rer<bwjqlflwv<f}h=V{i{f}kDd~iw|=Msswk=0+<&";
	char s1[147];
	if( (uMsg==WM_COMMAND) && 
		(wParam==IDC_BUTTON1) )
		EndDialog(hwndDlg,1);

	if( uMsg==WM_INITDIALOG )
	{
		int i;
		for( i = 0 ; i < 147 ; i += 2)
			s1[i] = s[i]^0x12;
		for( i = 1 ; i < 147 ; i += 2 )
			s1[i] = s[i]^0x5;
		s1[141] = 0;
		SendDlgItemMessage(hwndDlg,IDC_EDIT1,WM_SETTEXT,0,(LPARAM)s1);
		return TRUE;
	}
	return FALSE;
}

STDMETHODIMP CImageShow::AboutBox()
{

	//DialogBox(_AtlModule.m_hInst,MAKEINTRESOURCE(IDD_DIALOGBAR),0,DialogProc);
	return S_OK;
}


BOOL CImageShow::Load(LPCTSTR filename)
{
	HANDLE	hFile;
	DWORD	size;
	DWORD	size1;
	DWORD	readbyte;
	BYTE	temp[13];
	if( m_bEmbed )
		return FALSE;
//free memory from previous image
	Stop();

	if( m_pcGlobalColorTable != NULL )
		delete[] m_pcGlobalColorTable;

	if( m_pcGif != NULL )
		delete[] m_pcGif;

	if( m_hRedrawBitmap!=0 )
	{
		DeleteObject(m_hRedrawBitmap);
		m_hRedrawBitmap=0;
	}

	m_pcGlobalColorTable = m_pcGif = 0;
	m_iTotalReadByte = 0;
	m_iGifSize = m_iGlobalColorSize = 0;
	
	hFile = CreateFile(filename,
		               GENERIC_READ,
					   FILE_SHARE_READ,
					   NULL,OPEN_EXISTING,
					   FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,
					   NULL);
	if( INVALID_HANDLE_VALUE == hFile )
		return FALSE;

	size = GetFileSize(hFile,&size1);
	if( size == 0xFFFFFFFF )
	{
		CloseHandle(hFile);
		return FALSE;
	}

	ReadFile(hFile,temp,13,&readbyte,NULL);

	if( (readbyte!=13) || 
		( (temp[0]!='G') || (temp[1]!='I') || ( temp[2]!='F') || (temp[3]!='8')||
		  ( (temp[4]!='7') && (temp[4]!='9') )||
		  (temp[5]!='a') ) )
	{
		CloseHandle(hFile);
		return FALSE;
	}
	m_iGifWidth		= *(WORD*)(temp+6);
	m_iGifHeight	= *(WORD*)(temp+8);
	m_iBackgroundColor = temp[11];
	if( temp[10]&0x80 )
	{
		m_iGlobalColorSize = 0x01<<((temp[10]&0x07)+1);
		m_pcGlobalColorTable = new BYTE[3*m_iGlobalColorSize];
		ReadFile(hFile,m_pcGlobalColorTable,3*m_iGlobalColorSize,&readbyte,NULL);
		if( readbyte != 3*m_iGlobalColorSize )
		{
			delete[] m_pcGlobalColorTable;
			m_pcGlobalColorTable = 0;
			m_iGlobalColorSize   = 0;
			CloseHandle(hFile);
			return FALSE;
		}
	}

	m_iGifSize = size-3*m_iGlobalColorSize-12;
	m_pcGifTrack = m_pcGif = new BYTE[m_iGifSize];

	ReadFile(hFile,m_pcGif,m_iGifSize,&readbyte,NULL);
	CloseHandle(hFile);
	return TRUE;
}


HBITMAP CImageShow::FirstImage(void)
{
	m_pcGifTrack		= m_pcGif;
	m_iTotalReadByte	= 0;
	return NextImage();
}

HBITMAP CImageShow::NextImage(void)
{
 	if( m_pcGif == NULL )
		return 0;

l1:	if( m_iTotalReadByte > m_iGifSize )
	{
		m_pcGifTrack = m_pcGif;m_iTotalReadByte = 0;
		return 0;
	}
	m_iTotalReadByte++;
	switch(*m_pcGifTrack++)
	{
	case 0x2C:
		return TakeIt();
		break;
	case 0x21:
			BYTE cSize;
			m_iTotalReadByte++;
			switch(*m_pcGifTrack++)
			{ 
			case 0xF9:
				m_pcGifTrack++;//block size
				m_iDisposalMethod	= (*m_pcGifTrack)&28;
				m_bTransparentIndex	= (*m_pcGifTrack++)&1;
				m_iDelayTime		= *(WORD*)m_pcGifTrack;
				m_pcGifTrack		+= 2;
				m_iTransparentIndex	= *m_pcGifTrack++;
				m_iTotalReadByte	+= 5;
				break;
			case 0xFE:
				while( (cSize=*m_pcGifTrack) != 0 )
				{
					m_pcGifTrack     += cSize+1;
					m_iTotalReadByte += cSize+1;
					if( m_iTotalReadByte > m_iGifSize )
						return 0;
				}
				break;
			case 0x01:
				m_pcGifTrack	 += 13;
				m_iTotalReadByte += 13;
				while( (cSize=*m_pcGifTrack) != 0 )
				{
					m_pcGifTrack += cSize+1;
					m_iTotalReadByte += cSize+1;
					if( m_iTotalReadByte > m_iGifSize )
						return 0;
				}
				break;
			case 0xFF:
				m_pcGifTrack += 12;
				m_iTotalReadByte += 12;
				while( (cSize=*m_pcGifTrack) != 0 )
				{
					m_pcGifTrack += cSize+1;
					m_iTotalReadByte += cSize+1;
					if( m_iTotalReadByte > m_iGifSize )
						return 0;
				}
				break;
			default:
				return FALSE;
			}
			m_pcGifTrack++;
			m_iTotalReadByte++;
			if( m_iTotalReadByte > m_iGifSize )
				return 0;
			goto l1;
			break;
	case 0x3B:
		m_pcGifTrack = m_pcGif;
		m_iTotalReadByte = 0;
		goto l1;
	case 0:
		m_pcGifTrack = m_pcGif;
		m_iTotalReadByte = 0;
		goto l1;
	default: 
		return FALSE;
	}
}


HBITMAP CImageShow::TakeIt(void)
{
	UINT	uLocalColorTableSize;
	WORD	code;
	WORD	oldcode;
	WORD	code1;
	int		iFinishCode;
	int		iResetCode;
	int		iPrimaryTableSize;
	int		iTableSize;
	BITMAPINFOHEADER *bitmapheader;
	BYTE	*pcColorTable;
	BYTE	*pcInfo;
	GIFTABLE *pcGifTable;
	HBITMAP hBitmap;

	m_iLeft			= *(WORD*)m_pcGifTrack;
	m_pcGifTrack	+= 2;
	m_iTop			=  *(WORD*)m_pcGifTrack;
	m_pcGifTrack	+= 2;
	m_iWidth		= *(WORD*)m_pcGifTrack;
	m_pcGifTrack	+= 2;
	m_iWidth1		= ((m_iWidth-1)|0x3)+1;
	m_iHeight		= *(WORD*)m_pcGifTrack;
	m_pcGifTrack	+= 2;
	m_cPackedField	= *m_pcGifTrack++;
	m_iTotalReadByte+= 9;
	m_iMaxByte		= m_iWidth1*m_iHeight;
	pcInfo			= new BYTE[256*sizeof(RGBQUAD)+sizeof(BITMAPINFOHEADER)+m_iMaxByte+sizeof(GIFTABLE)*4096];
	//1-BITMAPINFOHEADER
	//2-COLORTABLE
	//3-Bitmap bits
	//4-GIFTABLE;
	bitmapheader	= (BITMAPINFOHEADER*)pcInfo;
	pcColorTable	= pcInfo+sizeof(BITMAPINFOHEADER);
	m_pcBitmap		= pcColorTable+256*sizeof(RGBQUAD);
	pcGifTable		= (GIFTABLE*)(m_pcBitmap+m_iMaxByte);
	for( int i = 0 ; i < 4096 ; i++ )
		pcGifTable[i].previouscode = pcGifTable[i].nextcode=0;
	bitmapheader->biSize		= sizeof(BITMAPINFOHEADER);
	bitmapheader->biWidth		= m_iWidth;
	bitmapheader->biHeight		= -m_iHeight;
	bitmapheader->biPlanes		= 1;
	bitmapheader->biBitCount	= 8;
	bitmapheader->biCompression	= BI_RGB;
	bitmapheader->biSizeImage	= 0;
	bitmapheader->biXPelsPerMeter = 0;
	bitmapheader->biYPelsPerMeter = 0;
	bitmapheader->biClrUsed		= 256;
	bitmapheader->biClrImportant= 256;

	if( m_cPackedField&0x80 )
	{
		uLocalColorTableSize	= 1;
		uLocalColorTableSize	<<= (m_cPackedField&7)+1;
		if( m_bTransparentIndex )
		{
			m_TransparentColor	= RGB(m_pcGifTrack[m_iTransparentIndex*3],m_pcGifTrack[m_iTransparentIndex*3+1],m_pcGifTrack[m_iTransparentIndex*3+2]);
		}
		m_iTotalReadByte		+= uLocalColorTableSize*3;
		for( UINT i = 0 ; i < uLocalColorTableSize ; i++ )
		{
			pcColorTable[2]		= *m_pcGifTrack++;
			pcColorTable[1]		= *m_pcGifTrack++;
			pcColorTable[0]		= *m_pcGifTrack++;
			pcColorTable[3]		= 0;
			pcColorTable		+= 4;
		}

	}
	else 
	{
		BYTE *pcGlobalColor		= m_pcGlobalColorTable;
		if( m_bTransparentIndex )
		{
			m_TransparentColor	= RGB(pcGlobalColor[m_iTransparentIndex*3],pcGlobalColor[m_iTransparentIndex*3+1],pcGlobalColor[m_iTransparentIndex*3+2]);
		}
		for( int i = 0 ; i < m_iGlobalColorSize ; i++ )
		{
			pcColorTable[2]		= *pcGlobalColor++;
			pcColorTable[1]		= *pcGlobalColor++;
			pcColorTable[0]		= *pcGlobalColor++;
			pcColorTable[3]		= 0;
			pcColorTable		+= 4;
		}
	}
	m_uPrimaryBitSize = m_uBitSize = (*m_pcGifTrack++);
	m_iTotalReadByte++;
	iPrimaryTableSize = iTableSize = (1<<m_uBitSize)+2;
	iFinishCode					= iTableSize-1;
	iResetCode					= iFinishCode-1;

	m_uPrimaryBitSize++;
	m_uBitSize++;
	m_uRemain		= 0;
	m_cCurentByte	= 0;
	m_uBlockSize	= 0;
	m_uReadByte		= 1;
	m_x = m_y = 0;
	m_iPass			= 1;
	m_iRow			= 0;
	while( (code=GetCode()) != iFinishCode )
	{
		if( code == iResetCode )
		{
			m_uBitSize	= m_uPrimaryBitSize;
			iTableSize	= iPrimaryTableSize;
			oldcode		= GetCode();
			if( oldcode > iTableSize )
			{
				delete[] pcInfo;
				return 0;
			}
			Output((BYTE)oldcode);
			continue;
		}
		if( code < iTableSize ) //<code> exist in the string pcGifTable
		{
			code1		= code;
			WORD code2	= 0;
			while( code1 >= iPrimaryTableSize )
			{
				pcGifTable[code1].nextcode = code2;
				code2	= code1;
				code1	= pcGifTable[code1].previouscode;
				if( code1 >= code2 )
				{
					delete[] pcInfo;
					return 0;
				}
			}
			Output((BYTE)code1);
			while( code2 != 0 )
			{
				Output(pcGifTable[code2].bit);
				code2 = pcGifTable[code2].nextcode;
			}
			pcGifTable[iTableSize].bit = (BYTE)code1;
			pcGifTable[iTableSize].previouscode = oldcode;
			iTableSize++;
			if( iTableSize == (0x0001<<m_uBitSize) )
				m_uBitSize++;
			if( m_uBitSize > 12 )
				m_uBitSize = 12;
			oldcode = code;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?