8 class WinMergePluginBase : public IDispatch, public ITypeInfo
13 DISPID_PluginEvent = 1,
14 DISPID_PluginDescription,
15 DISPID_PluginIsAutomatic,
16 DISPID_PluginFileFilters,
17 DISPID_PluginUnpackedFileExtension,
18 DISPID_PluginExtendedProperties,
19 DISPID_PluginArguments,
20 DISPID_PluginVariables,
27 DISPID_ShowSettingsDialog,
29 using ScriptFuncPtr = HRESULT(STDMETHODCALLTYPE*)(IDispatch* pDispatch, BSTR bstrText, BSTR* pbstrResult);
31 WinMergePluginBase(const std::wstring& sEvent, const std::wstring& sDescription = L"",
32 const std::wstring& sFileFilters = L"", const std::wstring& sUnpackedFileExtension = L"",
33 const std::wstring& sExtendedProperties = L"", const std::wstring& sArguments = L"",
34 bool bIsAutomatic = true)
37 , m_sDescription(sDescription)
38 , m_sFileFilters(sFileFilters)
39 , m_sUnpackedFileExtension(sUnpackedFileExtension)
40 , m_sExtendedProperties(sExtendedProperties)
41 , m_sArguments(sArguments)
42 , m_bIsAutomatic(bIsAutomatic)
44 static PARAMDATA paramData_Prediff[] =
45 { {L"fileSrc", VT_BSTR}, {L"fileDst", VT_BSTR}, {L"pbChanged", VT_BOOL | VT_BYREF}, };
46 static PARAMDATA paramData_UnpackFile[] =
47 { {L"fileSrc", VT_BSTR}, {L"fileDst", VT_BSTR}, {L"pbChanged", VT_BOOL | VT_BYREF}, {L"pSubcode", VT_I4 | VT_BYREF}, };
48 static PARAMDATA paramData_PackFile[] =
49 { {L"fileSrc", VT_BSTR}, {L"fileDst", VT_BSTR}, {L"pbChanged", VT_BOOL | VT_BYREF}, {L"subcode", VT_I4}, };
50 static PARAMDATA paramData_IsFolder[] =
51 { {L"fileSrc", VT_BSTR}, };
52 static PARAMDATA paramData_Arguments[] =
53 { {L"args", VT_BSTR}, };
54 static PARAMDATA paramData_Variables[] =
55 { {L"vars", VT_BSTR}, };
56 static PARAMDATA paramData_UnpackFolder[] =
57 { {L"fileSrc", VT_BSTR}, {L"folderDst", VT_BSTR}, {L"pbChanged", VT_BOOL | VT_BYREF}, {L"pSubcode", VT_I4 | VT_BYREF}, };
58 static PARAMDATA paramData_PackFolder[] =
59 { {L"folderSrc", VT_BSTR}, {L"fileDst", VT_BSTR}, {L"pbChanged", VT_BOOL | VT_BYREF}, {L"subcode", VT_I4}, };
60 static METHODDATA methodData_FILE_PREDIFF[] =
62 { L"PluginEvent", nullptr, DISPID_PluginEvent, 0, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
63 { L"PluginDescription", nullptr, DISPID_PluginDescription, 1, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
64 { L"PluginIsAutomatic", nullptr, DISPID_PluginIsAutomatic, 2, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BOOL },
65 { L"PluginFileFilters", nullptr, DISPID_PluginFileFilters, 3, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
66 { L"PluginExtendedProperties", nullptr, DISPID_PluginExtendedProperties, 4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
67 { L"PluginArguments", nullptr, DISPID_PluginArguments, 5, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
68 { L"PluginArguments", paramData_Arguments, DISPID_PluginArguments, 5, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
69 { L"PluginVariables", nullptr, DISPID_PluginVariables, 6, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
70 { L"PluginVariables", paramData_Variables, DISPID_PluginVariables, 6, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
71 { L"PrediffFile", paramData_Prediff, DISPID_PrediffFile, 7, CC_STDCALL, 3, DISPATCH_METHOD, VT_BOOL },
72 { L"ShowSettingsDialog", nullptr, DISPID_ShowSettingsDialog, 8, CC_STDCALL, 0, DISPATCH_METHOD, VT_VOID },
74 static METHODDATA methodData_FILE_PACK_UNPACK[] =
76 { L"PluginEvent", nullptr, DISPID_PluginEvent, 0, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
77 { L"PluginDescription", nullptr, DISPID_PluginDescription, 1, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
78 { L"PluginIsAutomatic", nullptr, DISPID_PluginIsAutomatic, 2, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BOOL },
79 { L"PluginFileFilters", nullptr, DISPID_PluginFileFilters, 3, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
80 { L"PluginExtendedProperties", nullptr, DISPID_PluginExtendedProperties, 4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
81 { L"PluginUnpackedFileExtension", nullptr, DISPID_PluginUnpackedFileExtension, 5, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
82 { L"PluginArguments", nullptr, DISPID_PluginArguments, 6, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
83 { L"PluginArguments", paramData_Arguments, DISPID_PluginArguments, 6, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
84 { L"PluginVariables", nullptr, DISPID_PluginVariables, 7, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
85 { L"PluginVariables", paramData_Variables, DISPID_PluginVariables, 7, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
86 { L"UnpackFile", paramData_UnpackFile, DISPID_UnpackFile, 8, CC_STDCALL, 4, DISPATCH_METHOD, VT_BOOL },
87 { L"PackFile", paramData_PackFile, DISPID_PackFile , 9, CC_STDCALL, 4, DISPATCH_METHOD, VT_BOOL },
88 { L"ShowSettingsDialog", nullptr, DISPID_ShowSettingsDialog, 10, CC_STDCALL, 0, DISPATCH_METHOD, VT_VOID },
90 static METHODDATA methodData_FILE_FOLDER_PACK_UNPACK[] =
92 { L"PluginEvent", nullptr, DISPID_PluginEvent, 0, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
93 { L"PluginDescription", nullptr, DISPID_PluginDescription, 1, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
94 { L"PluginIsAutomatic", nullptr, DISPID_PluginIsAutomatic, 2, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BOOL },
95 { L"PluginFileFilters", nullptr, DISPID_PluginFileFilters, 3, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
96 { L"PluginExtendedProperties", nullptr, DISPID_PluginExtendedProperties, 4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
97 { L"PluginUnpackedFileExtension", nullptr, DISPID_PluginUnpackedFileExtension, 5, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
98 { L"PluginArguments", nullptr, DISPID_PluginArguments, 6, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
99 { L"PluginArguments", paramData_Arguments, DISPID_PluginArguments, 6, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
100 { L"PluginVariables", nullptr, DISPID_PluginVariables, 7, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
101 { L"PluginVariables", paramData_Variables, DISPID_PluginVariables, 7, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
102 { L"UnpackFile", paramData_UnpackFile, DISPID_UnpackFile, 8, CC_STDCALL, 4, DISPATCH_METHOD, VT_BOOL },
103 { L"PackFile", paramData_PackFile, DISPID_PackFile , 9, CC_STDCALL, 4, DISPATCH_METHOD, VT_BOOL },
104 { L"IsFolder", paramData_IsFolder, DISPID_IsFolder, 10, CC_STDCALL, 1, DISPATCH_METHOD, VT_BOOL },
105 { L"UnpackFolder", paramData_UnpackFolder, DISPID_UnpackFolder, 11, CC_STDCALL, 4, DISPATCH_METHOD, VT_BOOL },
106 { L"PackFolder", paramData_PackFolder, DISPID_PackFolder, 12, CC_STDCALL, 4, DISPATCH_METHOD, VT_BOOL },
107 { L"ShowSettingsDialog", nullptr, DISPID_ShowSettingsDialog, 13, CC_STDCALL, 0, DISPATCH_METHOD, VT_VOID },
109 static METHODDATA methodData_EDITOR_SCRIPT[] =
111 { L"PluginEvent", nullptr, DISPID_PluginEvent, 0, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
112 { L"PluginDescription", nullptr, DISPID_PluginDescription, 1, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
113 { L"PluginFileFilters", nullptr, DISPID_PluginFileFilters, 2, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
114 { L"PluginExtendedProperties", nullptr, DISPID_PluginExtendedProperties, 3, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
115 { L"PluginArguments", nullptr, DISPID_PluginArguments, 4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
116 { L"PluginArguments", paramData_Arguments, DISPID_PluginArguments, 4, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
117 { L"PluginVariables", nullptr, DISPID_PluginVariables, 5, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
118 { L"PluginVariables", paramData_Variables, DISPID_PluginVariables, 5, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
120 const METHODDATA* pMethodData;
121 size_t methodDataCount = 0;
122 if (sEvent == L"FILE_PREDIFF")
124 methodDataCount = sizeof(methodData_FILE_PREDIFF) / sizeof(methodData_FILE_PREDIFF[0]);
125 pMethodData = methodData_FILE_PREDIFF;
127 else if (sEvent == L"FILE_PACK_UNPACK")
129 methodDataCount = sizeof(methodData_FILE_PACK_UNPACK) / sizeof(methodData_FILE_PACK_UNPACK[0]);
130 pMethodData = methodData_FILE_PACK_UNPACK;
132 else if (sEvent == L"FILE_FOLDER_PACK_UNPACK" || sEvent == L"URL_PACK_UNPACK")
134 methodDataCount = sizeof(methodData_FILE_FOLDER_PACK_UNPACK) / sizeof(methodData_FILE_FOLDER_PACK_UNPACK[0]);
135 pMethodData = methodData_FILE_FOLDER_PACK_UNPACK;
139 methodDataCount = sizeof(methodData_EDITOR_SCRIPT) / sizeof(methodData_EDITOR_SCRIPT[0]);
140 pMethodData = methodData_EDITOR_SCRIPT;
142 for (size_t i = 0; i < methodDataCount; ++i)
144 auto& methodData = pMethodData[i];
145 m_mapNameToIndex.insert_or_assign(methodData.szName, static_cast<int>(m_methodData.size()));
146 m_mapDispIdToIndex.insert_or_assign(methodData.dispid, static_cast<int>(m_methodData.size()));
147 m_methodData.push_back(methodData);
151 virtual ~WinMergePluginBase() {}
153 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override
158 ULONG STDMETHODCALLTYPE AddRef(void) override
163 ULONG STDMETHODCALLTYPE Release(void) override
173 HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo) override
179 HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) override
182 (*ppTInfo)->AddRef();
186 HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) override
188 for (unsigned i = 0; i < cNames; ++i)
190 auto it = m_mapNameToIndex.find(rgszNames[i]);
191 if (it == m_mapNameToIndex.end())
192 return DISP_E_UNKNOWNNAME;
193 rgDispId[i] = m_methodData[it->second].dispid;
198 HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) override
201 return DISP_E_BADVARTYPE;
202 HRESULT hr = E_NOTIMPL;
203 if (wFlags & DISPATCH_METHOD)
205 switch (dispIdMember)
207 case DISPID_PrediffFile:
209 BSTR fileSrc = pDispParams->rgvarg[2].bstrVal;
210 BSTR fileDst = pDispParams->rgvarg[1].bstrVal;
211 VARIANT_BOOL* pbChanged = pDispParams->rgvarg[0].pboolVal;
212 VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
213 hr = PrediffFile(fileSrc, fileDst, pbChanged, pbSuccess);
216 case DISPID_UnpackFile:
218 BSTR fileSrc = pDispParams->rgvarg[3].bstrVal;
219 BSTR fileDst = pDispParams->rgvarg[2].bstrVal;
220 VARIANT_BOOL* pbChanged = pDispParams->rgvarg[1].pboolVal;
221 INT* pSubcode = pDispParams->rgvarg[0].pintVal;
222 VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
223 hr = UnpackFile(fileSrc, fileDst, pbChanged, pSubcode, pbSuccess);
226 case DISPID_PackFile:
228 BSTR fileSrc = pDispParams->rgvarg[3].bstrVal;
229 BSTR fileDst = pDispParams->rgvarg[2].bstrVal;
230 VARIANT_BOOL* pbChanged = pDispParams->rgvarg[1].pboolVal;
231 INT subcode = pDispParams->rgvarg[0].intVal;
232 VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
233 hr = PackFile(fileSrc, fileDst, pbChanged, subcode, pbSuccess);
236 case DISPID_IsFolder:
238 BSTR file = pDispParams->rgvarg[0].bstrVal;
239 VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
240 hr = IsFolder(file, pbSuccess);
243 case DISPID_UnpackFolder:
245 BSTR fileSrc = pDispParams->rgvarg[3].bstrVal;
246 BSTR folderDst = pDispParams->rgvarg[2].bstrVal;
247 VARIANT_BOOL* pbChanged = pDispParams->rgvarg[1].pboolVal;
248 INT* pSubcode = pDispParams->rgvarg[0].pintVal;
249 VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
250 hr = UnpackFolder(fileSrc, folderDst, pbChanged, pSubcode, pbSuccess);
253 case DISPID_PackFolder:
255 BSTR folderSrc = pDispParams->rgvarg[3].bstrVal;
256 BSTR fileDst = pDispParams->rgvarg[2].bstrVal;
257 VARIANT_BOOL* pbChanged = pDispParams->rgvarg[1].pboolVal;
258 INT subcode = pDispParams->rgvarg[0].intVal;
259 VARIANT_BOOL* pbSuccess = &pVarResult->boolVal;
260 hr = PackFolder(folderSrc, fileDst, pbChanged, subcode, pbSuccess);
263 case DISPID_ShowSettingsDialog:
264 hr = ShowSettingsDialog(&pVarResult->boolVal);
267 if (m_mapDispIdToIndex.find(dispIdMember) != m_mapDispIdToIndex.end())
269 BSTR bstrText = pDispParams->rgvarg[0].bstrVal;
270 pVarResult->vt = VT_BSTR;
271 BSTR* pbstrResult = &pVarResult->bstrVal;
272 hr = m_mapScriptFuncs[dispIdMember].second(this, bstrText, pbstrResult);
277 else if (wFlags & DISPATCH_PROPERTYGET)
279 switch (dispIdMember)
281 case DISPID_PluginEvent:
282 pVarResult->vt = VT_BSTR;
283 hr = get_PluginEvent(&pVarResult->bstrVal);
285 case DISPID_PluginDescription:
286 pVarResult->vt = VT_BSTR;
287 hr = get_PluginDescription(&pVarResult->bstrVal);
289 case DISPID_PluginIsAutomatic:
290 pVarResult->vt = VT_BOOL;
291 hr = get_PluginIsAutomatic(&pVarResult->boolVal);
293 case DISPID_PluginFileFilters:
294 pVarResult->vt = VT_BSTR;
295 hr = get_PluginFileFilters(&pVarResult->bstrVal);
297 case DISPID_PluginUnpackedFileExtension:
298 pVarResult->vt = VT_BSTR;
299 hr = get_PluginUnpackedFileExtension(&pVarResult->bstrVal);
301 case DISPID_PluginExtendedProperties:
302 pVarResult->vt = VT_BSTR;
303 hr = get_PluginExtendedProperties(&pVarResult->bstrVal);
305 case DISPID_PluginArguments:
306 pVarResult->vt = VT_BSTR;
307 hr = get_PluginArguments(&pVarResult->bstrVal);
309 case DISPID_PluginVariables:
310 pVarResult->vt = VT_BSTR;
311 hr = get_PluginVariables(&pVarResult->bstrVal);
315 else if (wFlags & DISPATCH_PROPERTYPUT)
317 switch (dispIdMember)
319 case DISPID_PluginArguments:
321 BSTR bstrArgs = pDispParams->rgvarg[0].bstrVal;
322 hr = put_PluginArguments(bstrArgs);
325 case DISPID_PluginVariables:
327 BSTR bstrVars = pDispParams->rgvarg[0].bstrVal;
328 hr = put_PluginVariables(bstrVars);
333 if (hr == DISP_E_EXCEPTION && pExcepInfo)
335 IErrorInfo* pErrorInfo = nullptr;
336 if (SUCCEEDED(GetErrorInfo(0, &pErrorInfo)))
338 pErrorInfo->GetDescription(&pExcepInfo->bstrDescription);
339 pErrorInfo->GetSource(&pExcepInfo->bstrSource);
345 HRESULT STDMETHODCALLTYPE GetTypeAttr(TYPEATTR** ppTypeAttr) override
347 auto* pTypeAttr = new TYPEATTR();
348 pTypeAttr->cFuncs = static_cast<WORD>(m_methodData.size());
349 pTypeAttr->typekind = TKIND_DISPATCH;
350 pTypeAttr->cbAlignment = 8;
351 *ppTypeAttr = pTypeAttr;
355 HRESULT STDMETHODCALLTYPE GetTypeComp(ITypeComp** ppTComp) override
360 HRESULT STDMETHODCALLTYPE GetFuncDesc(UINT index, FUNCDESC** ppFuncDesc) override
362 if (index >= m_methodData.size())
364 auto* pFuncDesc = new FUNCDESC();
365 const METHODDATA& methodData = m_methodData[index];
366 pFuncDesc->funckind = FUNC_DISPATCH;
367 pFuncDesc->invkind = static_cast<INVOKEKIND>(methodData.wFlags);
368 pFuncDesc->wFuncFlags = 0;
369 pFuncDesc->cParams = static_cast<short>(methodData.cArgs);
370 pFuncDesc->memid = methodData.dispid;
371 pFuncDesc->callconv = methodData.cc;
372 if (methodData.cArgs > 0)
374 pFuncDesc->lprgelemdescParam = new ELEMDESC[methodData.cArgs];
375 for (int i = 0; i < methodData.cArgs; ++i)
376 pFuncDesc->lprgelemdescParam[i].tdesc.vt = methodData.ppdata[i].vt;
378 pFuncDesc->elemdescFunc.tdesc.vt = methodData.vtReturn;
379 *ppFuncDesc = pFuncDesc;
383 HRESULT STDMETHODCALLTYPE GetVarDesc(UINT index, VARDESC** ppVarDesc) override
388 HRESULT STDMETHODCALLTYPE GetNames(MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) override
390 if (m_mapDispIdToIndex.find(memid) == m_mapDispIdToIndex.end())
392 const METHODDATA& methodData = m_methodData[m_mapDispIdToIndex[memid]];
393 for (int i = 0; i < cMaxNames && i < methodData.cArgs + 1; i++)
396 rgBstrNames[i] = SysAllocString(methodData.szName);
398 rgBstrNames[i] = SysAllocString(methodData.ppdata[i - 1].szName);
404 HRESULT STDMETHODCALLTYPE GetRefTypeOfImplType(UINT index, HREFTYPE *pRefType) override
409 HRESULT STDMETHODCALLTYPE GetImplTypeFlags(UINT index, INT *pImplTypeFlags) override
414 HRESULT STDMETHODCALLTYPE GetIDsOfNames(LPOLESTR* rgszNames, UINT cNames, MEMBERID* pMemId) override
416 return GetIDsOfNames(IID_NULL, rgszNames, cNames, 0, pMemId);
419 HRESULT STDMETHODCALLTYPE Invoke(PVOID pvInstance, MEMBERID memid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) override
421 return reinterpret_cast<IDispatch*>(pvInstance)->Invoke(memid, IID_NULL, 0, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
424 HRESULT STDMETHODCALLTYPE GetDocumentation(MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile) override
429 HRESULT STDMETHODCALLTYPE GetDllEntry(MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
434 HRESULT STDMETHODCALLTYPE GetRefTypeInfo(HREFTYPE hRefType, ITypeInfo **ppTInfo) override
439 HRESULT STDMETHODCALLTYPE AddressOfMember(MEMBERID memid, INVOKEKIND invKind, PVOID *ppv) override
444 HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, REFIID riid, PVOID *ppvObj) override
449 HRESULT STDMETHODCALLTYPE GetMops(MEMBERID memid, BSTR *pBstrMops) override
454 HRESULT STDMETHODCALLTYPE GetContainingTypeLib(ITypeLib **ppTLib, UINT *pIndex) override
459 void STDMETHODCALLTYPE ReleaseTypeAttr(TYPEATTR *pTypeAttr) override
464 void STDMETHODCALLTYPE ReleaseFuncDesc(FUNCDESC *pFuncDesc) override
466 delete[] pFuncDesc->lprgelemdescParam;
470 void STDMETHODCALLTYPE ReleaseVarDesc(VARDESC *pVarDesc) override
474 virtual HRESULT STDMETHODCALLTYPE PrediffFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, VARIANT_BOOL* pbSuccess)
476 *pbSuccess = VARIANT_FALSE;
480 virtual HRESULT STDMETHODCALLTYPE PackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT subcode, VARIANT_BOOL* pbSuccess)
482 *pbSuccess = VARIANT_FALSE;
486 virtual HRESULT STDMETHODCALLTYPE UnpackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT* pSubcode, VARIANT_BOOL* pbSuccess)
488 *pbSuccess = VARIANT_FALSE;
492 virtual HRESULT STDMETHODCALLTYPE IsFolder(BSTR file, VARIANT_BOOL* pbFolder)
494 *pbFolder = VARIANT_FALSE;
498 virtual HRESULT STDMETHODCALLTYPE PackFolder(BSTR folderSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT subcode, VARIANT_BOOL* pbSuccess)
500 *pbSuccess = VARIANT_FALSE;
504 virtual HRESULT STDMETHODCALLTYPE UnpackFolder(BSTR fileSrc, BSTR folderDst, VARIANT_BOOL* pbChanged, INT* pSubcode, VARIANT_BOOL* pbSuccess)
506 *pbSuccess = VARIANT_FALSE;
510 virtual HRESULT STDMETHODCALLTYPE ShowSettingsDialog(VARIANT_BOOL* pbHandled)
512 *pbHandled = VARIANT_FALSE;
516 virtual HRESULT STDMETHODCALLTYPE get_PluginEvent(BSTR* pVal)
518 *pVal = SysAllocString(m_sEvent.c_str());
522 virtual HRESULT STDMETHODCALLTYPE get_PluginDescription(BSTR* pVal)
524 *pVal = SysAllocString(m_sDescription.c_str());
528 virtual HRESULT STDMETHODCALLTYPE get_PluginIsAutomatic(VARIANT_BOOL* pVal)
530 *pVal = m_bIsAutomatic ? -1 : 0;
534 virtual HRESULT STDMETHODCALLTYPE get_PluginFileFilters(BSTR* pVal)
536 *pVal = SysAllocString(m_sFileFilters.c_str());
540 virtual HRESULT STDMETHODCALLTYPE get_PluginUnpackedFileExtension(BSTR* pVal)
542 *pVal = SysAllocString(m_sUnpackedFileExtension.c_str());
546 virtual HRESULT STDMETHODCALLTYPE get_PluginExtendedProperties(BSTR* pVal)
548 *pVal = SysAllocString(m_sExtendedProperties.c_str());
552 virtual HRESULT STDMETHODCALLTYPE get_PluginArguments(BSTR* pVal)
554 *pVal = SysAllocString(m_sArguments.c_str());
558 virtual HRESULT STDMETHODCALLTYPE put_PluginArguments(BSTR val)
560 m_sArguments = std::wstring{ val, SysStringLen(val) };
564 virtual HRESULT STDMETHODCALLTYPE get_PluginVariables(BSTR* pVal)
566 *pVal = SysAllocString(m_sVariables.c_str());
570 virtual HRESULT STDMETHODCALLTYPE put_PluginVariables(BSTR val)
572 m_sVariables = std::wstring{ val, SysStringLen(val) };
576 bool AddFunction(const std::wstring& name, ScriptFuncPtr pFunc)
578 static PARAMDATA paramData_ScriptFunc[] =
579 { {L"text", VT_BSTR} };
580 unsigned index = static_cast<int>(m_methodData.size());
581 DISPID dispid = static_cast<DISPID>(m_methodData.size()) + 100;
582 m_mapNameToIndex.insert_or_assign(name, index);
583 m_mapDispIdToIndex.insert_or_assign(dispid, index);
584 m_mapScriptFuncs.insert_or_assign(dispid, std::pair{name, pFunc});
585 METHODDATA methodData =
587 const_cast<OLECHAR *>(m_mapScriptFuncs[dispid].first.c_str()), paramData_ScriptFunc, dispid, index, CC_STDCALL, 1, DISPATCH_METHOD, VT_BSTR
589 m_methodData.emplace_back(methodData);
595 std::map<std::wstring, int> m_mapNameToIndex;
596 std::map<DISPID, int> m_mapDispIdToIndex;
597 std::vector<METHODDATA> m_methodData;
598 std::map<DISPID, std::pair<std::wstring, ScriptFuncPtr>> m_mapScriptFuncs;
599 std::wstring m_sEvent;
600 std::wstring m_sDescription;
601 std::wstring m_sFileFilters;
602 std::wstring m_sUnpackedFileExtension;
603 std::wstring m_sExtendedProperties;
604 std::wstring m_sArguments;
605 std::wstring m_sVariables;