GDI 双缓冲技术

通过获取帧的维度与每一个帧的时间间隔来绘制gif图片

gif也是手机上用到最多的表情包动态图片

双缓冲

2D游戏经常用到的技术在内存中开辟一个空间来绘制图片

#include<windows.h>
#include<Gdiplus.h>
#pragma comment(lib,"Gdiplus.lib")
using namespace Gdiplus;
GdiplusStartupInput gdiplusstartupinput;
ULONG_PTR gdiplusTokeny;
#define WINDOW_WIDTH GetSystemMetrics(SM_CXSCREEN)
#define WINDOW_HEIGHT GetSystemMetrics(SM_CYSCREEN)
HDC hdc, hMemdc;
POINT point;
DWORD DrawGIF(HWND hwnd)//播放GIF动态图
{
    GdiplusStartup(&gdiplusTokeny, &gdiplusstartupinput, NULL);
    RECT rect;
    GetClientRect(hwnd, &rect);
    Image *pimage=new Image(L"c://4.gif");
    int count = pimage->GetFrameDimensionsCount();
    GUID *pDimensionIDs = new GUID[count];
    pimage->GetFrameDimensionsList(pDimensionIDs, count);
    int frameCount = pimage->GetFrameCount(&pDimensionIDs[0]);
    delete []pDimensionIDs;

    int Size = pimage->GetPropertyItemSize(PropertyTagFrameDelay);
    PropertyItem* pItem = (PropertyItem*)malloc(Size);
    pimage->GetPropertyItem(PropertyTagFrameDelay,Size,pItem);

    GUID Guid = FrameDimensionTime;
    int fcount = 0;
    free(pItem);

    while (TRUE)
    {
        hdc = GetDC(hwnd);
        hMemdc = CreateCompatibleDC(hdc);
        HBITMAP hbmp = CreateCompatibleBitmap(hdc,rect.right - rect.left, rect.bottom - rect.top);
        SelectObject(hMemdc, hbmp);
        Graphics graphics(hMemdc);
        graphics.DrawImage(pimage, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
        pimage->SelectActiveFrame(&Guid,fcount++);
        if (fcount == frameCount)
            fcount = 0;
        BitBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
            hMemdc, 0, 0, SRCCOPY);
        ReleaseDC(hwnd,hdc);
        DeleteDC(hMemdc);
        DeleteObject(hbmp);
        Sleep(100);
    }
    
}



DWORD DrawImage(HWND hwnd)//双缓冲技术
{
    hdc = GetDC(hwnd);
    RECT rect;
    GetClientRect(hwnd, &rect);
    GetCursorPos(&point);
    GdiplusStartup(&gdiplusTokeny, &gdiplusstartupinput, NULL);
    Bitmap *p = new Bitmap(rect.right-rect.left,rect.bottom-rect.top);
    Graphics graphics(p);
    Image image(L"c://MP3//JPG/1.jpg");
    Image imm(L"c://MP3//JPG/2.jpg");
    graphics.DrawImage(&image, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
    ScreenToClient(hwnd,&point);
    graphics.DrawImage(&imm, point.x, point.y, 300, 300);
    Graphics gr(hdc);
    gr.DrawImage(p, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
    delete p;
    return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_PAINT:
        ValidateRect(hwnd,NULL);
        SetTimer(hwnd, 90, NULL,NULL);
        break;
    case WM_TIMER:
        SetCursor(FALSE);
        //DrawImage(hwnd);
        break;
    case WM_DESTROY:
        GdiplusShutdown(gdiplusTokeny);
        PostQuitMessage(0);
        break;
    default:
        DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int _stdcall WinMain(HINSTANCE hinstance,//_stdcall 堆栈从右向左传递
    HINSTANCE hPrevInstance,//实力程序
    LPSTR lpCmdLine,
    int nCmdShow)
{
    WNDCLASSEX wcx;
    wcx.cbClsExtra = 0;
    wcx.cbSize = sizeof(WNDCLASSEX);
    wcx.cbWndExtra = 0;
    wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wcx.hInstance = hinstance;
    wcx.lpfnWndProc = WndProc;
    wcx.lpszClassName = L"a";
    wcx.lpszMenuName = NULL;
    wcx.style = CS_HREDRAW | CS_VREDRAW;
    BOOL bRet;
    bRet = RegisterClassEx(&wcx);
    if (!bRet)
    {
        MessageBox(NULL, L"", L"", MB_OK);
        return E_FAIL;
    }
    HWND hwnd = CreateWindowEx(WS_EX_CONTROLPARENT, L"a", NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hinstance, NULL);
    if (!hwnd)
    {
        MessageBox(NULL, L"", L"", MB_OK);
        return E_FAIL;
    }
    DrawGIF(hwnd);
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    MSG msg = { 0 };
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {

        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值