【问题标题】:How to load GDI::Image (GIF) from Resource in c++(winapi)?如何从 C++(winapi) 中的资源加载 GDI::Image (GIF)?
【发布时间】:2019-11-29 06:11:05
【问题描述】:

我正在使用 winapi(非 MFC)制作一个窗口 c++ 并显示 gif。为此,我使用 GDI++。我正在从路径中将 gif 加载到 GDI::Image 中,但我想从资源中加载它。我该怎么做?

    hMWDC = GetDC(hWnd);
    pGphcs = new Graphics(hMWDC);
    WCHAR path[MAX_PATH];
    GetModuleFileNameW(NULL, path, MAX_PATH);
    PathRemoveFileSpecW(path);
    PathAppendW(path, L"gifs\\test.gif");
    pImg = new Image(path);

    if (pImg) {
        nFrmCnt = pImg->GetFrameCount(&FrameDimensionTime);
        SetTimer(hWnd, DRAW_ANIM, 100, NULL);

    }
case WM_TIMER:
        if (wParam == DRAW_ANIM)
        {
            pImg->SelectActiveFrame(&FrameDimensionTime, nFrm);
            Rect DRC(0, 0, pImg->GetWidth(), pImg->GetHeight());
            pGphcs->Clear(Color(128, 128, 128));


            pGphcs->DrawImage(pImg, DRC);
            if (nFrm < (nFrmCnt - 1)) nFrm++; else nFrm = 0;
        }

        break;

【问题讨论】:

    标签: c++ winapi gdi animated-gif


    【解决方案1】:

    有一个 Image constructor 接受 IStream*。

    您可以通过在资源的原始缓冲区上调用SHCreateMemStream来创建流,可以通过调用FindResource/LoadResource/LockResource和SizeOfResource获得。

    【讨论】:

    • @TheGamerCoder 阅读了迈克尔链接到的文档,并给出了示例。
    • hr = pIStorage->OpenStream(L"StreamImage1", NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &pIStream1);
    • 并且没有更多示例。好的。但是,如果没有关于 Resource 的内容,我该如何使用它
    • @TheGamerCoder Image 构造函数文档显示传递从 IStorage 获得的 IStream。 SHCreateMemStream() 将内存指针和大小作为输入并返回 IStream。资源文档向您展示了如何获取资源的指针和大小。不难弄清楚如何将一个例子应用于另一个例子。我发布了一个显示代码的答案。
    【解决方案2】:

    在编译时将 GIF 文件添加到应用的资源中。例如,通过将类似于下面的.rc 文件编译成.res 文件,然后您可以链接到您的可执行文件(一些编译器/IDE 具有自动执行此步骤的工具):

    资源.rh

    #define MY_GIF_ID 100
    

    资源.rc

    #include "Resources.rh"
    MY_GIF_ID RCDATA "gifs\\test.gif"
    

    然后,您可以在运行时获取指向资源原始字节的指针。

    #include "Resources.rh"
    
    HMODULE hMod = GetModuleHandle(NULL);
    
    HRSRC hRes = FindResource(hMod, MAKEINTRESOURCE(MY_GIF_ID), RT_RCDATA);
    if (!hRes) { ... error handling ... } 
    
    HGLOBAL hGlobal = LoadResource(hMod, hRes);
    if (!hGlobal) { ... error handling ... } 
    
    void *pResData = LockResource(hGlobal);
    if (!pResData) { ... error handling ... } 
    
    DWORD dwResData = SizeofResource(hMod, hRes);
    

    有关详细信息,请参阅 MSDN:

    Introduction to Resources

    Finding and Loading Resources

    最后,将资源字节传递给Image 构造函数,该构造函数将IStream* 作为输入:

    #include <shlwapi.h>
    
    IStream *pStream = SHCreateMemStream((BYTE*)pResData, dwResData);
    if (!pStream) { ... error handling ... } 
    
    pImg = new Image(pStream);
    pStream->Release();
    

    【讨论】:

    • 问题是 gif 是 flick。我试图在 WM_ERASEBKGND 上返回 0 并将 WNDCLASSEX 的画笔设置为 NULL;没用
    • @TheGamerCoder 这与从资源加载 GIF 完全不同。发布一个关于闪烁的新问题。如果您能够从资源中成功加载 GIF,则将答案标记为已接受并继续
    • 好的。我会做到的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 2013-08-26
    • 2011-07-24
    相关资源
    最近更新 更多