#define UNICODE
#define _UNICODE
#include <Windows.h>
#include <shlwapi.h>
#ifndef PropertyTagFrameDelay
#define PropertyTagFrameDelay (0x5100)
#endif
#ifndef FrameDimensionTime
#define FrameDimensionTime {0x6AEDBD6D,0x3FB5,0x418A,{0x83,0xA6,0x7F,0x45,0x22,0x9D,0xC8,0x72}}
#endif
typedef struct GdiplusStartupInput {
UINT32 GdiplusVersion;
LPVOID DebugEventCallback;
BOOL SuppressBackgroundThread;
BOOL SuppressExternalCodecs;
}GdiplusStartupInput;
GdiplusStartupInput g_gdiplusStartupInput={1,NULL,FALSE,FALSE};
ULONG_PTR g_gdiplusToken;
typedef int GpImage;
typedef int GpGraphics;
typedef struct PropertyItem
{
PROPID id;
ULONG length;
WORD type;
UNALIGNED VOID* value;
}PropertyItem;
GpImage* g_pImage;
DECLSPEC_IMPORT DWORD WINAPI GdiplusStartup(ULONG_PTR *token,const GdiplusStartupInput *input,LPVOID output);
DECLSPEC_IMPORT void WINAPI GdiplusShutdown(ULONG_PTR token);
DECLSPEC_IMPORT DWORD WINAPI GdipLoadImageFromStream(IStream* stream, GpImage **image);
DECLSPEC_IMPORT DWORD WINAPI GdipGetImageWidth(GpImage *image, UINT *width);
DECLSPEC_IMPORT DWORD WINAPI GdipGetImageHeight(GpImage *image, UINT *height);
DECLSPEC_IMPORT DWORD WINAPI GdipImageGetFrameDimensionsCount(GpImage* image, UINT* count);
DECLSPEC_IMPORT DWORD WINAPI GdipImageGetFrameDimensionsList(GpImage* image, GUID* dimensionIDs, UINT count);
DECLSPEC_IMPORT DWORD WINAPI GdipImageGetFrameCount(GpImage *image, const GUID* dimensionID, UINT* count);
DECLSPEC_IMPORT DWORD WINAPI GdipGetPropertyItemSize(GpImage *image, PROPID propId, UINT* size);
DECLSPEC_IMPORT DWORD WINAPI GdipGetPropertyItem(GpImage *image, PROPID propId,UINT propSize, PropertyItem* buffer);
DECLSPEC_IMPORT DWORD WINAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics);
DECLSPEC_IMPORT DWORD WINAPI GdipDeleteGraphics(GpGraphics *graphics);
DECLSPEC_IMPORT DWORD WINAPI GdipDrawImageRectI(GpGraphics *graphics, GpImage *image, INT x, INT y, INT width, INT height);
DECLSPEC_IMPORT DWORD WINAPI GdipImageSelectActiveFrame(GpImage *image, const GUID* dimensionID, UINT frameIndex);
DECLSPEC_IMPORT DWORD WINAPI GdipSetSmoothingMode(GpGraphics *graphics, int smoothingMode);
HDC g_hDc;
HDC g_hMemDC;
HBITMAP g_hBmp;
HMODULE g_hGdiPlus;
HINSTANCE g_hInst;
LPCTSTR g_lpClassName = TEXT("giftest");
LPCTSTR g_lpWindowName = TEXT("致敬,我们热爱和战斗过的长空");
int g_iCx,g_iCy;
UINT g_uFrameCount;
HWND g_hWnd;
PropertyItem* g_pItem;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
DWORD WINAPI ShutDown(void)
{
GdiplusShutdown(g_gdiplusToken);
HeapFree(GetProcessHeap(),0,g_pItem);
DeleteObject(g_hDc);
DeleteObject(g_hBmp);
ExitProcess(0);
return 0;
}
ULARGE_INTEGER WINAPI GetTimeUlargeInteger(void)
{
SYSTEMTIME systemtime;
FILETIME filetime;
GetSystemTime(&systemtime);
SystemTimeToFileTime(&systemtime,&filetime);
ULARGE_INTEGER u;
u.LowPart=filetime.dwLowDateTime;
u.HighPart=filetime.dwHighDateTime;
return u;
}
DWORD WINAPI ThreadProc(PropertyItem* pItem)
{
PlaySound(TEXT("Sound"),g_hInst,SND_RESOURCE | SND_ASYNC);
int iFcount=0;
GUID Guid = FrameDimensionTime;
ULARGE_INTEGER u0=GetTimeUlargeInteger();
DWORD dwCurrentPassedTime=0;
DWORD dwCurrentDisplayedTime=0;
RECT rcClientRect;
GetClientRect(g_hWnd,&rcClientRect);
while(TRUE)
{
if(dwCurrentDisplayedTime*10000<dwCurrentPassedTime)
{
dwCurrentDisplayedTime+=((long*)pItem->value)[++iFcount]*10;
continue;
}
g_hDc=GetDC(g_hWnd);
g_hMemDC=CreateCompatibleDC(g_hDc);
HBITMAP g_hBmp=CreateCompatibleBitmap(g_hDc,g_iCx,g_iCy);
SelectObject(g_hMemDC,g_hBmp);
GpGraphics* gh;
GdipCreateFromHDC(g_hMemDC,&gh);
#define SmoothingModeAntiAlias8x8 5
GdipSetSmoothingMode(gh,SmoothingModeAntiAlias8x8);
GdipDrawImageRectI(gh,g_pImage,0,0,rcClientRect.right,rcClientRect.bottom);
GdipDeleteGraphics(gh);
BitBlt(g_hDc,0,0,g_iCx,g_iCy,g_hMemDC,0,0,SRCCOPY);
DeleteDC(g_hDc);
DeleteObject(g_hBmp);
ReleaseDC(g_hWnd,g_hDc);
GdipImageSelectActiveFrame(g_pImage,&Guid,iFcount++);
if(iFcount >= g_uFrameCount)
return ShutDown();
long lPause = ((long*)pItem->value)[iFcount]*10;
Sleep(lPause);
ULARGE_INTEGER uCurrent=GetTimeUlargeInteger();
dwCurrentPassedTime=uCurrent.QuadPart-u0.QuadPart;
dwCurrentDisplayedTime+=lPause;
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int uCmdShow)
//用wWinMain的话MinGW无法编译
{
GdiplusStartup(&g_gdiplusToken, &g_gdiplusStartupInput, NULL);
HANDLE hHeap=GetProcessHeap();
HRSRC hRscGif=FindResource(NULL,MAKEINTRESOURCE(1000),TEXT("BINARY"));
HGLOBAL hGlb=LoadResource(NULL,hRscGif);
LPBYTE lpGif=LockResource(hGlb);
IStream* iStream=SHCreateMemStream(lpGif,SizeofResource(NULL,hRscGif));
GdipLoadImageFromStream(iStream,&g_pImage);
UINT uWndWidth,uWndHeight;
GdipGetImageWidth(g_pImage,&uWndWidth);
GdipGetImageHeight(g_pImage,&uWndHeight);
g_iCx=uWndWidth,g_iCy=uWndHeight;
UINT uCount;
GdipImageGetFrameDimensionsCount(g_pImage,&uCount);
GUID *pDimensionIDs=(GUID*)HeapAlloc(hHeap,0,uCount*sizeof(GUID));
GdipImageGetFrameDimensionsList(g_pImage,pDimensionIDs,uCount);
WCHAR pStrGuid[39];
StringFromGUID2(pDimensionIDs, pStrGuid, 39);
UINT uFrameCount;
GdipImageGetFrameCount(g_pImage,pDimensionIDs,&uFrameCount);
g_uFrameCount=uFrameCount;
HeapFree(hHeap,0,pDimensionIDs);
UINT uSize;
GdipGetPropertyItemSize(g_pImage,PropertyTagFrameDelay,&uSize);
g_pItem=HeapAlloc(hHeap,0,uSize);
GdipGetPropertyItem(g_pImage,PropertyTagFrameDelay,uSize,g_pItem);
////////////////////////////////////////////////////////////////////////////////////////////////////////
WNDCLASS wndclass;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = g_lpClassName;
wndclass.lpszMenuName = NULL;
wndclass.style = 0;
RegisterClass(&wndclass);
HWND hWnd=g_hWnd=CreateWindow(
g_lpClassName,
g_lpWindowName,
WS_POPUPWINDOW | WS_CAPTION,
CW_USEDEFAULT,
CW_USEDEFAULT,
uWndWidth,
uWndHeight,
NULL,
NULL,
hInstance,
NULL
);
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(LPVOID)ThreadProc,g_pItem,0,NULL);
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
return 0;
case WM_PAINT:
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_CLOSE:
ShutDown();
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
供大家参考学习,本资源不要币! 起初想用gdi+播放mp4,后来发现gdi+没有这种功能,mp4解码又很复杂自己写不了,于是用格式工厂从视频中提出了wav和gif图,用playsound放wav,用gdi+绘制gif。 网上的讲解gdi+绘制gif的例子运行起来都慢,因为gdi+绘制的效率很低,于是在最初的时候出现了gif比wav的播放慢。后来修改了一下,wav和gif终于同步了。 另外,只能用MinGW编译。已安装MinGW的可以直接运行里面的cmd文件编译。顺便说一下为什么不用VS2019:VS2019不能添加800k以上的资源(怒)。顺便再说一下为什么不用C++:MinGW的gdi+C++头文件有问题,运行就崩不知道为啥。 不会编译没学过C的,在Release文件夹下面有个64位的exe文件,那是编译好的成品直接运行体验一下也ok。 特别鸣谢: 格式工厂软件 视频来源:https://b23.tv/RCHRVUX
资源推荐
资源详情
资源评论
收起资源包目录
giftest.zip (6个子文件)
giftest.c 8KB
make.cmd 212B
Release
giftest.exe 244.56MB
giftest.rc 63B
Into the Sky.gif 217.41MB
Into the Sky.wav 27.13MB
共 6 条
- 1
资源评论
//尚同学:-)
- 粉丝: 1
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功