Skip to content

Instantly share code, notes, and snippets.

@z4none
Created December 5, 2024 09:32
Show Gist options
  • Select an option

  • Save z4none/bd408669ef6c7893bfb858a7951ce14d to your computer and use it in GitHub Desktop.

Select an option

Save z4none/bd408669ef6c7893bfb858a7951ce14d to your computer and use it in GitHub Desktop.
IDispatch helper class
#pragma once
#include <wrl.h>
#include <comutil.h>
#include <vector>
#include <string>
#include <atlbase.h>
#include <comdef.h>
//
class SimpleObject : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IDispatch>
{
public:
SimpleObject(const std::vector<std::pair<std::wstring, CComVariant>>& props)
{
// i don't know why but access the 1st prop always failed, so place a dummy one here
m_props.push_back({ L"_", CComVariant() });
for (auto& prop : props)
{
m_props.push_back(prop);
}
}
HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT, LCID, ITypeInfo**)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pCount)
{
*pCount = m_props.size();
return S_OK;
}
HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
{
for (UINT i = 0; i < cNames; ++i)
{
bool found = false;
LPOLESTR name = rgszNames[i];
for (size_t j = 0; j < m_props.size(); ++j)
{
if (wcscmp(name, m_props[j].first.c_str()) == 0)
{
found = true;
rgDispId[i] = static_cast<DISPID>(j);
break;
}
}
if (!found)
{
rgDispId[i] = DISPID_UNKNOWN;
}
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
if (wFlags & DISPATCH_PROPERTYGET)
{
if (dispIdMember < 0 || static_cast<size_t>(dispIdMember) >= m_props.size())
{
return E_INVALIDARG;
}
auto& pair = m_props[static_cast<size_t>(dispIdMember)];
if (pVarResult)
{
VariantInit(pVarResult);
HRESULT hr = VariantCopy(pVarResult, &pair.second);
if (FAILED(hr))
{
return hr;
}
}
return S_OK;
}
return E_FAIL;
}
private:
std::vector<std::pair<std::wstring, CComVariant>> m_props;
};
std::vector<std::pair<std::wstring, CComVariant>> props;
props.push_back({ L"id", CComVariant{1} });
props.push_back({ L"name", CComVariant{L"hello"} });
auto object = Microsoft::WRL::Make<SimpleObject>(props);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment