📄 gifviewer.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#define INITGUID
#include "GifViewer.h"
#ifndef UNDER_CE
#include <tchar.h>
#endif
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
IImage * g_pImage = NULL;
IImagingFactory * g_pImagingFactory = NULL;
TCHAR * g_tszFilename;
IImagingFactory *pImagingFactory = NULL;
IImageSink *pImageSink = NULL;
IImage *pImage = NULL;
IImageDecoder *pImageDecoder = NULL;
IImageEncoder *pImageEncoder = NULL, *pIETemp = NULL;
IBitmapImage *pBitmapImage = NULL;
IStream *pStream = NULL;
UINT count;
ImageInfo ii;
typedef HRESULT (*DLLGETCLASSOBJECT) (REFCLSID, REFIID, VOID**);
int WINAPI WinMain
(
HINSTANCE hInstance,
HINSTANCE hInstPrev,
#ifdef UNDER_CE
LPWSTR pszCmdLine,
#else
LPSTR pszCmdLine,
#endif
int nCmdShow
)
{
HRESULT hr;
HINSTANCE hiImaging = NULL;
MSG msg;
TCHAR *tszError;
TCHAR *tszName;
TCHAR tszNotReg[] = TEXT("REGDB_E_CLASSNOTREG");
TCHAR tszNoAgg[] = TEXT("CLASS_E_NOAGGREGATION");
TCHAR tszUnknown[] = TEXT("unknown hr");
g_hInst = hInstance;
if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
info(TEXT("CoInitializeEx failed, hr: 0x%08x"), hr);
return 1;
}
hr = CoCreateInstance(CLSID_ImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IImagingFactory,
(void**) &pImagingFactory);
if (FAILED(hr))
{
switch(hr)
{
case REGDB_E_CLASSNOTREG:
tszError = tszNotReg;
break;
case CLASS_E_NOAGGREGATION:
tszError = tszNoAgg;
break;
default:
tszError = tszUnknown;
break;
}
info(TEXT("CoCreateInstance failed, hr: 0x%08x (%s)"), hr, tszError);
goto finish;
}
tszName = TEXT("\\storage Card\\fox.gif");
info(TEXT("Opening %s"), tszName);
if (FAILED(hr = CreateStreamOnFile(tszName, &pStream)))
{
info(TEXT("CreateStreamOnFile failed, hr: 0x%08x"), hr);
goto finish;
}
GetCodecCLSID(pImagingFactory, NULL, NULL, eDecoder);
if (FAILED(hr = pImagingFactory->CreateImageDecoder(pStream, DecoderInitFlagBuiltIn1st, &pImageDecoder)))
{
info(TEXT("CreateImageDecoder failed, hr: 0x%08x"), hr);
goto finish;
}
pImageDecoder->GetImageInfo(&ii);
if (FAILED(hr = pImageDecoder->GetFrameCount(&FrameDimensionTime, &count)))
{
return 0;
}
/*
if (FAILED(hr = pImageDecoder->GetFrameDimensionsCount(&count)))
{
info(TEXT("GetFrameDimensionsCount for Image from BitmapImage failed, hr: 0x%08x"), hr);
goto finish;
}
if (FAILED(hr = pImageDecoder->GetFrameDimensionsList(DimID, count)))
{
goto finish;
}
*/
/*
if (FAILED(hr = pImageDecoder->GetFrameCount(FrameDimensionTime, &count)))
{
goto finish;
}
if (FAILED(hr = pImagingFactory->CreateNewBitmap(ii.Width, ii.Height, ii.PixelFormat, &pBitmapImage)))
{
info(TEXT("CreateNewBitmap failed, hr = 0x%08x"), hr);
goto finish;
}
if (FAILED(hr = pBitmapImage->QueryInterface(IID_IImageSink, (void**)&pImageSink)))
{
info(TEXT("QueryInterface for ImageSink from BitmapImage failed, hr: 0x%08x"), hr);
goto finish;
}
if (FAILED(hr = pBitmapImage->QueryInterface(IID_IImage, (void**)&g_pImage)))
{
info(TEXT("QueryInterface for Image from BitmapImage failed, hr: 0x%08x"), hr);
goto finish;
}
if (FAILED(hr = pImageDecoder->BeginDecode(pImageSink, NULL)))
{
info(TEXT("BeginDecode into Bitmap Image failed, hr = 0x%08d"), hr);
goto finish;
}
while (E_PENDING == (hr = pImageDecoder->Decode()))
{
Sleep(0);
}
hr = pImageDecoder->EndDecode(hr);
if (FAILED(hr))
{
info(TEXT("Decoding failed, hr = 0x%08x"), hr);
goto finish;
}
*/
g_pImagingFactory = pImagingFactory;
g_tszFilename = tszName;
OpenWindow(ii.Width, ii.Height, tszName);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
finish:
if (pBitmapImage)
pBitmapImage->Release();
if (pStream)
pStream->Release();
if (pImageSink)
pImageSink->Release();
if (pImageDecoder)
pImageDecoder->Release();
if (pImageEncoder)
pImageEncoder->Release();
if (g_pImage)
g_pImage->Release();
if (pImagingFactory)
pImagingFactory->Release();
CoUninitialize();
return 0;
}
BOOL OpenWindow(DWORD dwWidth, DWORD dwHeight, const TCHAR * tszName)
{
WNDCLASS wc;
TCHAR tszClassName[] = TEXT("ImagingT");
int x, y, width, height;
wc.style = 0;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = (HINSTANCE) g_hInst;
wc.hIcon = 0;
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = tszClassName;
RegisterClass(&wc);
RECT rcWorkArea;
if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0))
{
SetRect(&rcWorkArea, 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN));
}
x = 0;
y = 0;
width = dwWidth + 2 * GetSystemMetrics(SM_CXBORDER);
height = dwHeight + 2 * GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYCAPTION);
g_hWnd = CreateWindowEx(
0,
tszClassName,
tszName,
WS_OVERLAPPED|WS_CAPTION|WS_BORDER|WS_VISIBLE|WS_SYSMENU,
x,
y,
width,
height,
NULL,
NULL,
(HINSTANCE) g_hInst,
NULL );
if( g_hWnd == NULL )
return FALSE;
ShowWindow( g_hWnd, SW_SHOWNORMAL );
UpdateWindow( g_hWnd );
info(TEXT("Main window created, x = %d, y=%d, width = %d, height = %d"),
x, y, width, height);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
RECT rc;
HRESULT hr;
static int index;
switch(wMsg)
{
case WM_CREATE:
SetTimer(hWnd,1,100,NULL);
return 0;
case WM_TIMER:
hdc = GetDC(hWnd);
GetClientRect(hWnd, &rc);
if (FAILED(hr = pImagingFactory->CreateNewBitmap(ii.Width, ii.Height, ii.PixelFormat, &pBitmapImage)))
{
info(TEXT("CreateNewBitmap failed, hr = 0x%08x"), hr);
return 0;
}
if (FAILED(hr = pBitmapImage->QueryInterface(IID_IImageSink, (void**)&pImageSink)))
{
info(TEXT("QueryInterface for ImageSink from BitmapImage failed, hr: 0x%08x"), hr);
return 0;
}
if (FAILED(hr = pBitmapImage->QueryInterface(IID_IImage, (void**)&g_pImage)))
{
info(TEXT("QueryInterface for Image from BitmapImage failed, hr: 0x%08x"), hr);
return 0;
}
if (FAILED(hr = pImageDecoder->SelectActiveFrame(&FrameDimensionTime, index)))
{
return 0;
}
if (FAILED(hr = pImageDecoder->BeginDecode(pImageSink, NULL)))
{
info(TEXT("BeginDecode into Bitmap Image failed, hr = 0x%08d"), hr);
return 0;
}
while (E_PENDING == (hr = pImageDecoder->Decode()))
{
Sleep(0);
}
hr = pImageDecoder->EndDecode(hr);
if (FAILED(hr))
{
info(TEXT("Decoding failed, hr = 0x%08x"), hr);
return 0;
}
g_pImage->Draw(hdc, &rc, NULL);
index ++;
if(index == count)
{
index = 0;
}
ReleaseDC(hWnd,hdc);
if (pBitmapImage)
pBitmapImage->Release();
if (pImageSink)
pImageSink->Release();
if (g_pImage)
g_pImage->Release();
return 0;
case WM_DESTROY:
KillTimer(hWnd,1);
PostQuitMessage(0);
return 0;
}
g_hWnd = hWnd;
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
void info(const TCHAR* tszFormat, ...)
{
va_list va;
TCHAR tszInfo[1024];
va_start(va, tszFormat);
_vstprintf(tszInfo, tszFormat, va);
va_end(va);
OutputDebugString(tszInfo);
}
HRESULT CreateStreamOnFile(const TCHAR * tszFilename, IStream ** ppStream)
{
HRESULT hrRet = S_OK;
HGLOBAL hg = NULL;
HANDLE hFile = NULL;
DWORD dwSize, dwRead;
BYTE* pbLocked = NULL;
// Open the file
hFile = CreateFile(tszFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
info(TEXT("CreateFile failed with GLE = %d"), GetLastError());
hrRet = 0x80000000 + GetLastError();
goto error;
}
dwSize = GetFileSize(hFile, NULL);
if (0xffffffff == dwSize)
{
info(TEXT("GetFileSize failed with GLE = %d"), GetLastError());
hrRet = 0x80000000 + GetLastError();
goto error;
}
// Open a memory object
hg = GlobalAlloc(GMEM_MOVEABLE, dwSize);
if (NULL == hg)
{
info(TEXT("GlobalAlloc failed with GLE = %d"), GetLastError());
hrRet = 0x80000000 + GetLastError();
goto error;
}
// Ge a pointer to the memory we just allocated
pbLocked = (BYTE*) GlobalLock(hg);
if (NULL == pbLocked)
{
info(TEXT("GlobalLock failed with GLE = %d"), GetLastError());
hrRet = 0x80000000 + GetLastError();
goto error;
}
// copy the file
if (!ReadFile(hFile, pbLocked, dwSize, &dwRead, NULL))
{
info(TEXT("ReadFile failed with GLE = %d"), GetLastError());
hrRet = 0x80000000 + GetLastError();
goto error;
}
GlobalUnlock(hg);
// Create the stream
hrRet = CreateStreamOnHGlobal(hg, TRUE, ppStream);
CloseHandle(hFile);
return hrRet;
error:
if (pbLocked)
GlobalUnlock(hg);
if (hg)
GlobalFree(hg);
if (hFile)
CloseHandle(hFile);
return hrRet;
}
BOOL GetCodecCLSID(IImagingFactory* pImagingFactory, CLSID * pclsid, WCHAR * wszMimeType, CodecType ctCodec)
{
UINT uiCount;
ImageCodecInfo * codecs;
HRESULT hr;
BOOL fRet = FALSE;
TCHAR * tszCodec;
if (eEncoder == ctCodec)
{
hr = pImagingFactory->GetInstalledEncoders(&uiCount, &codecs);
tszCodec = TEXT("Encoder");
}
else
{
hr = pImagingFactory->GetInstalledDecoders(&uiCount, &codecs);
tszCodec = TEXT("Decoder");
}
if (FAILED(hr))
{
info(TEXT("GetInstalled%ss returned 0x%08x"), tszCodec, hr);
return FALSE;
}
for (UINT i = 0; i < uiCount; i++)
{
info(TEXT("%s %d of %d: MimeType = %s"), tszCodec, i + 1, uiCount, codecs[i].MimeType);
if (wszMimeType && !wcscmp(wszMimeType, codecs[i].MimeType))
{
*pclsid = codecs[i].Clsid;
fRet = TRUE;
break;
}
}
CoTaskMemFree(codecs);
return fRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -