5 class WinMergePluginBase : public IDispatch, public ITypeInfo
12 DISPID_ShowSettingsDialog,
13 DISPID_PluginFileFilters,
14 DISPID_PluginIsAutomatic,
15 DISPID_PluginDescription,
18 struct MemberInfo { std::wstring name; DISPID id; int flags; };
20 WinMergePluginBase() : m_nRef(0)
22 static const MemberInfo memberInfo[] =
24 { L"UnpackFile", DISPID_UnpackFile, DISPATCH_METHOD },
25 { L"PackFile", DISPID_PackFile , DISPATCH_METHOD },
26 { L"ShowSettingsDialog", DISPID_ShowSettingsDialog, DISPATCH_METHOD },
27 { L"PluginFileFilters", DISPID_PluginFileFilters, DISPATCH_PROPERTYGET },
28 { L"PluginIsAutomatic", DISPID_PluginIsAutomatic, DISPATCH_PROPERTYGET },
29 { L"PluginDescription", DISPID_PluginDescription, DISPATCH_PROPERTYGET },
30 { L"PluginEvent", DISPID_PluginEvent, DISPATCH_PROPERTYGET },
32 for (auto item : memberInfo)
34 m_memberInfo.push_back(item);
35 m_mapNameToIndex.emplace(item.name, item.id);
39 virtual ~WinMergePluginBase() {}
41 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override
46 ULONG STDMETHODCALLTYPE AddRef(void) override
51 ULONG STDMETHODCALLTYPE Release(void) override
61 HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo) override
63 *pctinfo = static_cast<UINT>(m_memberInfo.size());
67 HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) override
74 HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) override
76 for (unsigned i = 0; i < cNames; ++i)
78 auto it = m_mapNameToIndex.find(rgszNames[i]);
79 if (it == m_mapNameToIndex.end())
80 return DISP_E_UNKNOWNNAME;
81 rgDispId[i] = it->second;
86 HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) override
89 return DISP_E_BADVARTYPE;
90 HRESULT hr = E_NOTIMPL;
91 if (wFlags == DISPATCH_METHOD)
95 case DISPID_UnpackFile:
97 BSTR fileSrc = pDispParams->rgvarg[3].bstrVal;
98 BSTR fileDst = pDispParams->rgvarg[2].bstrVal;
99 VARIANT_BOOL* pbChanged = pDispParams->rgvarg[1].pboolVal;
100 INT* pSubcode = &pDispParams->rgvarg[0].intVal;
101 VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
102 hr = UnpackFile(fileSrc, fileDst, pbChanged, pSubcode, pbSuccess);
105 case DISPID_PackFile:
107 BSTR fileSrc = pDispParams->rgvarg[3].bstrVal;
108 BSTR fileDst = pDispParams->rgvarg[2].bstrVal;
109 VARIANT_BOOL* pbChanged = pDispParams->rgvarg[1].pboolVal;
110 INT subcode = pDispParams->rgvarg[0].intVal;
111 VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
112 hr = PackFile(fileSrc, fileDst, pbChanged, subcode, pbSuccess);
115 case DISPID_ShowSettingsDialog:
116 hr = ShowSettingsDialog(&pVarResult->boolVal);
120 else if (wFlags == DISPATCH_PROPERTYGET)
122 switch (dispIdMember)
124 case DISPID_PluginFileFilters:
125 pVarResult->vt = VT_BSTR;
126 hr = get_PluginFileFilters(&pVarResult->bstrVal);
128 case DISPID_PluginIsAutomatic:
129 pVarResult->vt = VT_BOOL;
130 hr = get_PluginIsAutomatic(&pVarResult->boolVal);
132 case DISPID_PluginDescription:
133 pVarResult->vt = VT_BSTR;
134 hr = get_PluginDescription(&pVarResult->bstrVal);
136 case DISPID_PluginEvent:
137 pVarResult->vt = VT_BSTR;
138 hr = get_PluginEvent(&pVarResult->bstrVal);
145 HRESULT STDMETHODCALLTYPE GetTypeAttr(TYPEATTR** ppTypeAttr) override
147 auto* pTypeAttr = new TYPEATTR();
148 pTypeAttr->cFuncs = static_cast<WORD>(m_memberInfo.size());
149 *ppTypeAttr = pTypeAttr;
153 HRESULT STDMETHODCALLTYPE GetTypeComp(ITypeComp** ppTComp) override
158 HRESULT STDMETHODCALLTYPE GetFuncDesc(UINT index, FUNCDESC** ppFuncDesc) override
160 if (index >= m_memberInfo.size())
162 auto* pFuncDesc = new FUNCDESC();
163 pFuncDesc->invkind = static_cast<INVOKEKIND>(m_memberInfo[index].flags);
164 pFuncDesc->wFuncFlags = 0;
165 pFuncDesc->memid = index;
166 *ppFuncDesc = pFuncDesc;
170 HRESULT STDMETHODCALLTYPE GetVarDesc(UINT index, VARDESC** ppVarDesc) override
175 HRESULT STDMETHODCALLTYPE GetNames(MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) override
177 if (memid >= m_memberInfo.size())
179 *rgBstrNames = SysAllocString(m_memberInfo[memid].name.c_str());
184 HRESULT STDMETHODCALLTYPE GetRefTypeOfImplType(UINT index, HREFTYPE *pRefType) override
189 HRESULT STDMETHODCALLTYPE GetImplTypeFlags(UINT index, INT *pImplTypeFlags) override
194 HRESULT STDMETHODCALLTYPE GetIDsOfNames(LPOLESTR* rgszNames, UINT cNames, MEMBERID* pMemId) override
196 return GetIDsOfNames(IID_NULL, rgszNames, cNames, 0, pMemId);
199 HRESULT STDMETHODCALLTYPE Invoke(PVOID pvInstance, MEMBERID memid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) override
201 return reinterpret_cast<IDispatch*>(pvInstance)->Invoke(memid, IID_NULL, 0, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
204 HRESULT STDMETHODCALLTYPE GetDocumentation(MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile) override
209 HRESULT STDMETHODCALLTYPE GetDllEntry(MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
214 HRESULT STDMETHODCALLTYPE GetRefTypeInfo(HREFTYPE hRefType, ITypeInfo **ppTInfo) override
219 HRESULT STDMETHODCALLTYPE AddressOfMember(MEMBERID memid, INVOKEKIND invKind, PVOID *ppv) override
224 HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, REFIID riid, PVOID *ppvObj) override
229 HRESULT STDMETHODCALLTYPE GetMops(MEMBERID memid, BSTR *pBstrMops) override
234 HRESULT STDMETHODCALLTYPE GetContainingTypeLib(ITypeLib **ppTLib, UINT *pIndex) override
239 void STDMETHODCALLTYPE ReleaseTypeAttr(TYPEATTR *pTypeAttr) override
244 void STDMETHODCALLTYPE ReleaseFuncDesc(FUNCDESC *pFuncDesc) override
249 void STDMETHODCALLTYPE ReleaseVarDesc(VARDESC *pVarDesc) override
253 virtual HRESULT STDMETHODCALLTYPE PackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT subcode, VARIANT_BOOL* pbSuccess)
255 *pbSuccess = VARIANT_FALSE;
259 virtual HRESULT STDMETHODCALLTYPE UnpackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT* pSubcode, VARIANT_BOOL* pbSuccess)
261 *pbSuccess = VARIANT_FALSE;
265 virtual HRESULT STDMETHODCALLTYPE ShowSettingsDialog(VARIANT_BOOL* pbHandled)
267 *pbHandled = VARIANT_FALSE;
271 virtual HRESULT STDMETHODCALLTYPE get_PluginIsAutomatic(VARIANT_BOOL* pVal)
273 *pVal = m_bIsAutomatic ? -1 : 0;
277 virtual HRESULT STDMETHODCALLTYPE get_PluginFileFilters(BSTR* pVal)
279 *pVal = SysAllocString(m_sFileFilters.c_str());
283 virtual HRESULT STDMETHODCALLTYPE get_PluginDescription(BSTR* pVal)
285 *pVal = SysAllocString(m_sDescription.c_str());
289 virtual HRESULT STDMETHODCALLTYPE get_PluginEvent(BSTR* pVal)
291 *pVal = SysAllocString(m_sEvent.c_str());
297 std::map<std::wstring, int> m_mapNameToIndex;
298 std::vector<MemberInfo> m_memberInfo;
299 std::wstring m_sEvent;
300 std::wstring m_sDescription;
301 std::wstring m_sFileFilters;