⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comeowmoniker.cpp

📁 com编程
💻 CPP
字号:
// CoMeowMoniker.cpp : Implementation of CoMeowMoniker

#include "stdafx.h"
#include <hrx.h>
#include <assert.h>
#include <ustring.h>
#include <ustring.cpp>

#include "MeowMoniker.h"
#include "CoMeowMoniker.h"
#include "Base64.h"
#include <mkbase.cpp>

/////////////////////////////////////////////////////////////////////////////
// CoMeowMoniker

#define BAD_POINTER_RETURN(p) if( !p ) return E_POINTER
#define BAD_POINTER_RETURN_OR_ZERO(p) if( !p ) return E_POINTER; else *p = 0

// Marshal interface into m_pszItf
HRESULT CoMeowMoniker::MarshalInterface(
    IUnknown*   punk,
    REFIID      riid,
    DWORD       dwDestContext,
    DWORD       mshlflags)
{
    COM_TRY
    {
        HRX   hrx;
        if( m_pszItf ) hrx = E_UNEXPECTED;

        // Marshal the interface into a stream
        SI(IStream) pstm;
        hrx = CreateStreamOnHGlobal(0, TRUE, pstm.RelItfRef());
        hrx = CoMarshalInterface(pstm.Itf(), riid, punk, dwDestContext, 0, mshlflags);

        // Treat the marshalled interface as an array of bytes
        HGLOBAL hg;
        hrx = GetHGlobalFromStream(pstm.Itf(), &hg);

        BYTE*   rgbRaw = (BYTE*)GlobalLock(hg);
        if( !rgbRaw ) hrx = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WINDOWS, GetLastError());

        // Allocate enough memory for encoded string
        ULONG   nRawSize = GlobalSize(hg);
        size_t  nEncodedLen = (nRawSize + 2)/3 * 4; // Round up
        m_pszItf = new char[nEncodedLen + 1];
        if( !m_pszItf ) hrx = E_OUTOFMEMORY;

        // Base64 encode raw data into a string
        hrx = BufferEncode64(const_cast<char*>(m_pszItf), nEncodedLen, rgbRaw, nRawSize);

        // NULL-terminate for convenience
        const_cast<char*>(m_pszItf)[nEncodedLen] = 0;
    }
    COM_CATCH;
}

// Unmarshal interface from m_pszItf
HRESULT CoMeowMoniker::UnmarshalInterface(
    REFIID  riid,
    void**  ppv)
{
    COM_TRY
    {
        HRX   hrx;

        if( !m_pszItf ) hrx = E_UNEXPECTED;

        // Allocate memory for decoded itf
        size_t  nEncodedLen = strlen(m_pszItf);
        assert(nEncodedLen && (nEncodedLen%4 == 0));

        size_t  nRawSize = nEncodedLen/4 * 3;
        HGLOBAL hg = GlobalAlloc(GPTR, nRawSize);
        if( !hg ) hrx = E_OUTOFMEMORY;

        // Build a stream on the memory
        SI(IStream) pstm;
        hrx = CreateStreamOnHGlobal(hg, TRUE, pstm.RelItfRef());

        // Base64 decode from string into raw memory
        BYTE*   rgbRaw = (BYTE*)GlobalLock(hg);
        if( !rgbRaw ) hrx = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WINDOWS, GetLastError());

        hrx = BufferDecode64(rgbRaw, &nRawSize, m_pszItf, nEncodedLen);

        // Unmarshal the interface pointer from the stream
        hrx = CoUnmarshalInterface(pstm.Itf(), riid, ppv);
    }
    COM_CATCH;
}

STDMETHODIMP CoMeowMoniker::BindToObject(
    IBindCtx*   pbc,
    IMoniker*   pmkToLeft,
    REFIID      riidResult,
    void**      ppvResult)
{
    BAD_POINTER_RETURN_OR_ZERO(ppvResult);
    BAD_POINTER_RETURN(pbc);

    COM_TRY
    {
        HRX   hrx;
        if( pmkToLeft ) hrx = E_UNEXPECTED;
        hrx = UnmarshalInterface(riidResult, ppvResult); 
    }
    COM_CATCH;
}

STDMETHODIMP CoMeowMoniker::GetDisplayName(
    IBindCtx*   pbc,
    IMoniker*   pmkToLeft,
    LPOLESTR*   ppwszDisplayName)
{
    BAD_POINTER_RETURN_OR_ZERO(ppwszDisplayName);
    BAD_POINTER_RETURN(pbc);

    COM_TRY
    {
        HRX   hrx;
        if( pmkToLeft ) hrx = E_UNEXPECTED;
        if( !m_pszItf ) hrx = E_UNEXPECTED;

        // Name Format: "dm.meow.1:<marshalled interface as base64 encoding>"
        size_t  cb = (wcslen(ProgID()) + 1 + strlen(m_pszItf) + 1) * sizeof(wchar_t);
        *ppwszDisplayName = (wchar_t*)CoTaskMemAlloc(cb);
        if( !*ppwszDisplayName ) hrx = E_OUTOFMEMORY;
        
        wcscpy(*ppwszDisplayName, ProgID());
        wcscat(*ppwszDisplayName, L":");
        mbstowcs(*ppwszDisplayName + wcslen(*ppwszDisplayName), m_pszItf, strlen(m_pszItf) + 1);
    }
    COM_CATCH;
}

STDMETHODIMP CoMeowMoniker::ParseDisplayName(
    IBindCtx*   pbc,
    IMoniker*   pmkToLeft,
    LPOLESTR    pwszDisplayName,
    ULONG*      pchEaten,
    IMoniker**  ppmkOut)
{
    BAD_POINTER_RETURN_OR_ZERO(ppmkOut);
    BAD_POINTER_RETURN_OR_ZERO(pchEaten);
    BAD_POINTER_RETURN(pbc);
    BAD_POINTER_RETURN(pwszDisplayName);
    BAD_POINTER_RETURN(pchEaten);

    COM_TRY
    {
        HRX   hrx;
        if( pmkToLeft ) hrx = E_UNEXPECTED;
        if( m_pszItf ) hrx = E_UNEXPECTED;

        const wchar_t*  pwszDisplayParam;
        if( CComMonikerBase::MatchesProgID(pwszDisplayName, &pwszDisplayParam) )
        {
            int cchItf = wcslen(pwszDisplayParam);
            m_pszItf = new char[cchItf + 1];
            if( !m_pszItf ) hrx = E_OUTOFMEMORY;

            wcstombs(const_cast<char*>(m_pszItf), pwszDisplayParam, cchItf + 1);
            *pchEaten = wcslen(pwszDisplayName);
            (*ppmkOut = this)->AddRef();
        }
    }
    COM_CATCH;
}

STDAPI CreateMeowMoniker(
    IUnknown*   punk,
    REFIID      riid,
    DWORD       dwDestContext,
    DWORD       mshlflags,
    IMoniker**  ppmk)
{
    BAD_POINTER_RETURN_OR_ZERO(ppmk);

    HRESULT         hr = E_OUTOFMEMORY;
    CoMeowMoniker*  pMeow = new CComObject<CoMeowMoniker>;
    if( pMeow )
    {
        // Just to do AddRef() and Release() so moniker object
        // is properly destroyed if it isn't handed out
        SI(IUnknown)    punkMeow = pMeow->GetUnknown();
        hr = pMeow->MarshalInterface(punk, riid, dwDestContext, mshlflags);
        if( SUCCEEDED(hr) )
        {
            (*ppmk = pMeow)->AddRef();
        }
    }

    return hr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -