Flash ActiveX:如何从内存、资源或流加载电影?

发布于 2024-07-11 00:21:39 字数 353 浏览 9 评论 0原文

我正在我的 C++ 应用程序中嵌入 Flash ActiveX 控件(Flash.ocx、Flash10a.ocx 等,具体取决于您的 Flash 版本)。

我可以通过调用 LoadMovie(0, filename) 加载 SWF 文件,但该文件需要物理驻留在磁盘中。 如何从内存(或资源、或流)加载SWF? 我确信一定有办法,因为像f-in-box这样的商业解决方案的功能直接从内存加载 Flash 影片 也使用 Flash ActiveX 控件。

I'm embedding a Flash ActiveX control in my C++ app (Flash.ocx, Flash10a.ocx, etc depending on your Flash version).

I can load an SWF file by calling LoadMovie(0, filename), but the file needs to physically reside in the disk. How to load the SWF from memory (or resource, or stream)? I'm sure there must be a way, because commercial solutions like f-in-box's feature Load flash movies from memory directly also uses Flash ActiveX control.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

累赘 2024-07-18 00:21:39

显然我需要提供投票“赞成”的详细信息……好的。

首次初始化时,内部闪存缓冲区指示是否已加载电影或缓冲区是否在缓冲区前四个字节中保存属性。

gUfU——没有加载电影。 要遵循的属性 ....

fUfU -- .. [4bytes] 大小为整数。

然后是未压缩的电影或 SWF。
编写一个 IStream 类。
填写如上。
另存为 szFile

TFlashStream *fStream = new TFlashStream(szFile);
// QI flash player

IPersistStreamInit * psStreamInit = 0;
shock->QueryInterface(::IID_IPersistStreamInit,  
                     (LPVOID*)&psStreamInit);
if(psStreamInit)
{
    psStreamInit->InitNew();
    psStreamInit->Load(fStream);
    psStreamInit->Release();
}
delete fStream;

注意事项:
当 psStreamInit->Load(fStream); 时
将调用 IStream::Read 查找标头“fUfU”。

如果返回正确,则 psStreamInit 调用 IStream::Read 来获取缓冲区大小。

如果到目前为止一切正常,psStreamInit 会读取 1024 字节块,直到读取完毕。
然而。 用于标题和文件大小。

STDMETHOD(Read)(void *pv, ULONG cb, ULONG *pcbRead)

pcbRead 无效。 你可能想使用类似的东西
IsBadReadPtr——

迈克尔

Appearantly I a going to need to supply details for a vote 'up'.. OK.

The internal flash buffer when first initiailized indicates if a movie is loaded or if the buffer hold properties in the buffer fisrt four bytes.

gUfU -- no movie loaded. properties to follow ....

fUfU -- .. [4bytes] size as integer.

then the UNCOMPRESSED movie or SWF as it were.
Write a IStream class.
fill with above.
save as szFile


TFlashStream *fStream = new TFlashStream(szFile);
// QI flash player

IPersistStreamInit * psStreamInit = 0;
shock->QueryInterface(::IID_IPersistStreamInit,  
                     (LPVOID*)&psStreamInit);
if(psStreamInit)
{
    psStreamInit->InitNew();
    psStreamInit->Load(fStream);
    psStreamInit->Release();
}
delete fStream;

Things to note :
When psStreamInit->Load(fStream);
will call IStream::Read looking for the header 'fUfU'.

if the return is correct psStreamInit then calls IStream::Read for the buffer size.

If everthing looks good so far, psStreamInit then reads in 1024 byte chunks until the read is exhausted.
However. for the header and file size.


STDMETHOD(Read)(void *pv, ULONG cb, ULONG *pcbRead)

pcbRead is invalid. you may want to use something like
IsBadReadPtr

--

Michael

悲念泪 2024-07-18 00:21:39

为了节省您打字的时间。 它以这种方式对我有用(只是没有经过广泛测试):

void flash_load_memory(FlashWidget* w, void* data, ULONG size) {
        FlashMemoryStream fStream = FlashMemoryStream(data, size);
        IPersistStreamInit* psStreamInit = NULL;
        w->mFlashInterface->QueryInterface(IID_IPersistStreamInit,(LPVOID*) &psStreamInit);
        if(psStreamInit) {
            psStreamInit->InitNew();
            psStreamInit->Load((LPSTREAM)&fStream);
            psStreamInit->Release();
        }
    }

class FlashMemoryStream : IStream {
    public:
        FlashMemoryStream(void* data,ULONG size) {
            this->data = data;
            this->size = size;
            this->pos = 0;
        }

        HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppv) {
            return E_NOTIMPL;
        }

        ULONG STDMETHODCALLTYPE AddRef() {  
            return E_NOTIMPL;
        }

        ULONG STDMETHODCALLTYPE Release() {  
            return E_NOTIMPL;
        }

        // IStream methods
        STDMETHOD(Read) (void *pv,ULONG cb,ULONG *pcbRead) {
            if(pos == 0 && cb == 4) {
                memcpy(pv,"fUfU",4);
                pos += 4;
                return S_OK;
            }
            else if(pos == 4 && cb == 4) {
                memcpy(pv,&size,4);
                size += 8;
                pos += 4;
                return S_OK;
            }
            else {
                if(pos + cb > size) cb = size - pos;
                if(cb == 0) return S_FALSE;
                memcpy(pv,(char*)data + pos - 8,cb);
                if(pcbRead) (*pcbRead) = cb;
                pos += cb;
                return S_OK;
            }
        }

        STDMETHOD(Write) (void const *pv,ULONG cb,ULONG *pcbWritten) { return E_NOTIMPL; }
        STDMETHOD(Seek) (LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER *plibNewPosition) { return E_NOTIMPL; }
        STDMETHOD(SetSize) (ULARGE_INTEGER libNewSize) { return E_NOTIMPL; }
        STDMETHOD(CopyTo) (IStream *pstm,ULARGE_INTEGER cb,ULARGE_INTEGER *pcbRead,ULARGE_INTEGER *pcbWritten) { return E_NOTIMPL; }
        STDMETHOD(Commit) (DWORD grfCommitFlags) { return E_NOTIMPL; }
        STDMETHOD(Revert) (void) { return E_NOTIMPL; }
        STDMETHOD(LockRegion) (ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType) { return E_NOTIMPL; }
        STDMETHOD(UnlockRegion) (ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType) { return E_NOTIMPL; }
        STDMETHOD(Stat) (STATSTG *pstatstg,DWORD grfStatFlag) { return E_NOTIMPL; }
        STDMETHOD(Clone) (IStream **ppstm) { return E_NOTIMPL; }

        void* data;
        ULONG size;
        ULONG pos;
    };

To spare you some typing. It works for me in this way (just works not extensively tested):

void flash_load_memory(FlashWidget* w, void* data, ULONG size) {
        FlashMemoryStream fStream = FlashMemoryStream(data, size);
        IPersistStreamInit* psStreamInit = NULL;
        w->mFlashInterface->QueryInterface(IID_IPersistStreamInit,(LPVOID*) &psStreamInit);
        if(psStreamInit) {
            psStreamInit->InitNew();
            psStreamInit->Load((LPSTREAM)&fStream);
            psStreamInit->Release();
        }
    }

class FlashMemoryStream : IStream {
    public:
        FlashMemoryStream(void* data,ULONG size) {
            this->data = data;
            this->size = size;
            this->pos = 0;
        }

        HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppv) {
            return E_NOTIMPL;
        }

        ULONG STDMETHODCALLTYPE AddRef() {  
            return E_NOTIMPL;
        }

        ULONG STDMETHODCALLTYPE Release() {  
            return E_NOTIMPL;
        }

        // IStream methods
        STDMETHOD(Read) (void *pv,ULONG cb,ULONG *pcbRead) {
            if(pos == 0 && cb == 4) {
                memcpy(pv,"fUfU",4);
                pos += 4;
                return S_OK;
            }
            else if(pos == 4 && cb == 4) {
                memcpy(pv,&size,4);
                size += 8;
                pos += 4;
                return S_OK;
            }
            else {
                if(pos + cb > size) cb = size - pos;
                if(cb == 0) return S_FALSE;
                memcpy(pv,(char*)data + pos - 8,cb);
                if(pcbRead) (*pcbRead) = cb;
                pos += cb;
                return S_OK;
            }
        }

        STDMETHOD(Write) (void const *pv,ULONG cb,ULONG *pcbWritten) { return E_NOTIMPL; }
        STDMETHOD(Seek) (LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER *plibNewPosition) { return E_NOTIMPL; }
        STDMETHOD(SetSize) (ULARGE_INTEGER libNewSize) { return E_NOTIMPL; }
        STDMETHOD(CopyTo) (IStream *pstm,ULARGE_INTEGER cb,ULARGE_INTEGER *pcbRead,ULARGE_INTEGER *pcbWritten) { return E_NOTIMPL; }
        STDMETHOD(Commit) (DWORD grfCommitFlags) { return E_NOTIMPL; }
        STDMETHOD(Revert) (void) { return E_NOTIMPL; }
        STDMETHOD(LockRegion) (ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType) { return E_NOTIMPL; }
        STDMETHOD(UnlockRegion) (ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType) { return E_NOTIMPL; }
        STDMETHOD(Stat) (STATSTG *pstatstg,DWORD grfStatFlag) { return E_NOTIMPL; }
        STDMETHOD(Clone) (IStream **ppstm) { return E_NOTIMPL; }

        void* data;
        ULONG size;
        ULONG pos;
    };
潇烟暮雨 2024-07-18 00:21:39

作为一个 Flash 爱好者,我不知道 C++ 端的任何细节,但是如果您在 Flash 端向假协议发出请求,那么在 C 端您可以拦截该请求并用数据流应答它吗? 我的意思是:

var mc:MovieClip = createEmptyMovieClip( "mc", 0 );
mc.loadMovie( "fakeprotocol://"+filename )

只要响应(对于 Flash)看起来像 HTTP 流,就应该可以工作。 (如果“拦截请求并返回数据流”是您寻求帮助的部分,请提前致歉。)

Being a flash guy I don't know any details on the C++ side, but if you made a request on the Flash side to a fake protocol, on the C side can you intercept that request and answer it with a data stream? I mean something like:

var mc:MovieClip = createEmptyMovieClip( "mc", 0 );
mc.loadMovie( "fakeprotocol://"+filename )

As long as the response looks (to Flash) like an HTTP stream, that ought to work. (Apologies in advance if the "intercept the request and return a data stream" is the part you're asking for help with.)

檐上三寸雪 2024-07-18 00:21:39

此外....
Flash 播放器推广 IPersistStorage。
flash.QI IPersistStorage
pStorage.load (mystorage_as_stream)

.. 理论上。

对上述内容感到抱歉..我本来打算发帖
Flash播放器提升IPersistStreamInit。
flash.QI IPersistStreamInit
pStream.load (my_stream)

迈克尔

in addition....
Flash player promotes IPersistStorage.
flash.QI IPersistStorage
pStorage.load (mystorage_as_stream)

.. in theory.

Sorry for the above.. I intended to post
Flash player promotes IPersistStreamInit.
flash.QI IPersistStreamInit
pStream.load (my_stream)

Michael

可是我不能没有你 2024-07-18 00:21:39

当您尝试通过 MovieclipLoader 或 LoadMovie 从另一部电影加载电影时,此方法不起作用!

结果就是替换了调用的SWF文件!! ...所以此方法仅适用于加载基本文件。

有人知道更好的方法也可以与 MovieClipLoader 和 LoadMovie 一起使用吗?
谢谢。

This method don't work when you try to load a movie via the MovieclipLoader or LoadMovie from another movie!!!

The result is to replace the calling SWF file!! ...so this method work only for loading the base file.

Someone know a better method that work also with MovieClipLoader and LoadMovie?
Thanks.

阿楠 2024-07-18 00:21:39

MS VC ATL 示例(使用 VS 2010 SP1 + Windows SDK 7.1 构建,并在带有 Flash64_11_3_300_257.ocx / Flash32_11_3_300_257.ocx 的 Windows 7 SP1 64 位和带有 Flash32_11_3_300_257.ocx 的 Windows XP SP3 32 位上进行测试):

#pragma pack(push, 1)

typedef struct _FLASH_STREAM_HEADER
{
    DWORD m_dwSignature;
    DWORD m_dwDataSize;
} FLASH_STREAM_HEADER, *PFLASH_STREAM_HEADER;

#pragma pack(pop)

static HRESULT LoadFlashMovieFromResource(ATL::CComPtr<IShockwaveFlash>& spShockwaveFlash,
    UINT nResourceID, LPCTSTR pszResourceType = RT_RCDATA)
{
    HMODULE hModule = ATL::_AtlBaseModule.GetModuleInstance();
    ATLASSUME(hModule != NULL);

    //HINSTANCE hResourceInstance = ATL::AtlFindResourceInstance(nResourceID, pszResourceType);
    //HRSRC hResource = ::FindResource(hResourceInstance, MAKEINTRESOURCE(nResourceID),
    //  pszResourceType);

    HRSRC hResource = ::FindResource(hModule, MAKEINTRESOURCE(nResourceID), pszResourceType);

    if (hResource == NULL)
        return HRESULT_FROM_WIN32(::GetLastError());

    DWORD dwResourceDataSize = ::SizeofResource(hModule, hResource);

    if (dwResourceDataSize == 0)
        return HRESULT_FROM_WIN32(::GetLastError());

    HGLOBAL hResourceLoaded = ::LoadResource(hModule, hResource);

    if (hResourceLoaded == NULL)
        return HRESULT_FROM_WIN32(::GetLastError());

    ATL::CComPtr<IStream> spStream;

    HRESULT hResult = ::CreateStreamOnHGlobal(NULL, TRUE, &spStream);

    if (FAILED(hResult))
        return hResult;

    FLASH_STREAM_HEADER fsh = {0x55665566, dwResourceDataSize};

    ULARGE_INTEGER uli = {sizeof (fsh) + dwResourceDataSize};

    hResult = spStream->SetSize(uli);

    if (FAILED(hResult))
        return hResult;

    hResult = spStream->Write(&fsh, sizeof (fsh), NULL);

    if (FAILED(hResult))
        return hResult;

    hResult = spStream->Write(reinterpret_cast<void*>(hResourceLoaded), dwResourceDataSize, NULL);

    if (FAILED(hResult))
        return hResult;

    uli.QuadPart = 0;

    hResult = spStream->Seek(*reinterpret_cast<PLARGE_INTEGER>(&uli), STREAM_SEEK_SET, NULL);

    if (FAILED(hResult))
        return hResult;

    ATL::CComPtr<IPersistStreamInit> spPersistStreamInit;

    hResult = spShockwaveFlash.QueryInterface(&spPersistStreamInit);

    if (SUCCEEDED(hResult))
        hResult = spPersistStreamInit->Load(spStream);

    return hResult;
}

MS VC ATL sample (have built with VS 2010 SP1 + Windows SDK 7.1 and tested on Windows 7 SP1 64-bit with Flash64_11_3_300_257.ocx / Flash32_11_3_300_257.ocx and on Windows XP SP3 32-bit with Flash32_11_3_300_257.ocx):

#pragma pack(push, 1)

typedef struct _FLASH_STREAM_HEADER
{
    DWORD m_dwSignature;
    DWORD m_dwDataSize;
} FLASH_STREAM_HEADER, *PFLASH_STREAM_HEADER;

#pragma pack(pop)

static HRESULT LoadFlashMovieFromResource(ATL::CComPtr<IShockwaveFlash>& spShockwaveFlash,
    UINT nResourceID, LPCTSTR pszResourceType = RT_RCDATA)
{
    HMODULE hModule = ATL::_AtlBaseModule.GetModuleInstance();
    ATLASSUME(hModule != NULL);

    //HINSTANCE hResourceInstance = ATL::AtlFindResourceInstance(nResourceID, pszResourceType);
    //HRSRC hResource = ::FindResource(hResourceInstance, MAKEINTRESOURCE(nResourceID),
    //  pszResourceType);

    HRSRC hResource = ::FindResource(hModule, MAKEINTRESOURCE(nResourceID), pszResourceType);

    if (hResource == NULL)
        return HRESULT_FROM_WIN32(::GetLastError());

    DWORD dwResourceDataSize = ::SizeofResource(hModule, hResource);

    if (dwResourceDataSize == 0)
        return HRESULT_FROM_WIN32(::GetLastError());

    HGLOBAL hResourceLoaded = ::LoadResource(hModule, hResource);

    if (hResourceLoaded == NULL)
        return HRESULT_FROM_WIN32(::GetLastError());

    ATL::CComPtr<IStream> spStream;

    HRESULT hResult = ::CreateStreamOnHGlobal(NULL, TRUE, &spStream);

    if (FAILED(hResult))
        return hResult;

    FLASH_STREAM_HEADER fsh = {0x55665566, dwResourceDataSize};

    ULARGE_INTEGER uli = {sizeof (fsh) + dwResourceDataSize};

    hResult = spStream->SetSize(uli);

    if (FAILED(hResult))
        return hResult;

    hResult = spStream->Write(&fsh, sizeof (fsh), NULL);

    if (FAILED(hResult))
        return hResult;

    hResult = spStream->Write(reinterpret_cast<void*>(hResourceLoaded), dwResourceDataSize, NULL);

    if (FAILED(hResult))
        return hResult;

    uli.QuadPart = 0;

    hResult = spStream->Seek(*reinterpret_cast<PLARGE_INTEGER>(&uli), STREAM_SEEK_SET, NULL);

    if (FAILED(hResult))
        return hResult;

    ATL::CComPtr<IPersistStreamInit> spPersistStreamInit;

    hResult = spShockwaveFlash.QueryInterface(&spPersistStreamInit);

    if (SUCCEEDED(hResult))
        hResult = spPersistStreamInit->Load(spStream);

    return hResult;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文