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 + -
显示快捷键?