From: Takashi Sawanaka Date: Tue, 11 May 2021 14:45:09 +0000 (+0900) Subject: Add WinMergePluginBase.h (2) X-Git-Tag: v2.16.13~48 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=4ba0fcf4d535a93ec2f2049066676e4ee17b5d85;hp=8267621f227c5b743a97287f63c61ea9dee877aa;p=winmerge-jp%2Fwinmerge-jp.git Add WinMergePluginBase.h (2) --- diff --git a/Src/Plugins.cpp b/Src/Plugins.cpp index 90c617ff8..efb900384 100644 --- a/Src/Plugins.cpp +++ b/Src/Plugins.cpp @@ -379,18 +379,20 @@ static String GetCustomFilters(const String& name, const String& filtersTextDefa class UnpackerGeneratedFromEditorScript: public WinMergePluginBase { public: - UnpackerGeneratedFromEditorScript(IDispatch *pDispatch, const std::wstring funcname, int id) : m_pDispatch(pDispatch), m_funcid(id) + UnpackerGeneratedFromEditorScript(IDispatch *pDispatch, const std::wstring funcname, int id) + : WinMergePluginBase( + L"FILE_PACK_UNPACK", + strutils::format_string1(_T("Unpacker to execute %1 script (automatically generated)") , funcname), + _T(".")) + , m_pDispatch(pDispatch) + , m_funcid(id) { - m_sDescription = - strutils::format_string1(_T("Unpacker to execute %1 script (automatically generated)") , funcname); - m_sFileFilters = _T("."); - m_bIsAutomatic = true; - m_sEvent = L"FILE_PACK_UNPACK"; m_pDispatch->AddRef(); } virtual ~UnpackerGeneratedFromEditorScript() { + m_pDispatch->Release(); } static HRESULT ReadFile(const String& path, String& text) diff --git a/Src/WinMergePluginBase.h b/Src/WinMergePluginBase.h index 6f03b1be8..8990d6cf2 100644 --- a/Src/WinMergePluginBase.h +++ b/Src/WinMergePluginBase.h @@ -7,32 +7,48 @@ class WinMergePluginBase : public IDispatch, public ITypeInfo public: enum { + DISPID_PluginEvent = 1, + DISPID_PluginDescription, + DISPID_PluginIsAutomatic, + DISPID_PluginFileFilters, DISPID_UnpackFile, DISPID_PackFile, DISPID_ShowSettingsDialog, - DISPID_PluginFileFilters, - DISPID_PluginIsAutomatic, - DISPID_PluginDescription, - DISPID_PluginEvent, }; - struct MemberInfo { std::wstring name; DISPID id; int flags; }; + struct MemberInfo + { + std::wstring name; + DISPID id; + short params; + short flags; + HRESULT (STDMETHODCALLTYPE *pFunc)(IDispatch *pDispatch, BSTR bstrText, BSTR* pbstrResult); + }; - WinMergePluginBase() : m_nRef(0) + WinMergePluginBase(const std::wstring& sEvent, const std::wstring& sDescription = L"", + const std::wstring& sFileFilters = L"", bool bIsAutomatic = true) + : m_nRef(0) + , m_sEvent(sEvent) + , m_sDescription(sDescription) + , m_sFileFilters(sFileFilters) + , m_bIsAutomatic(bIsAutomatic) { static const MemberInfo memberInfo[] = { - { L"UnpackFile", DISPID_UnpackFile, DISPATCH_METHOD }, - { L"PackFile", DISPID_PackFile , DISPATCH_METHOD }, - { L"ShowSettingsDialog", DISPID_ShowSettingsDialog, DISPATCH_METHOD }, - { L"PluginFileFilters", DISPID_PluginFileFilters, DISPATCH_PROPERTYGET }, - { L"PluginIsAutomatic", DISPID_PluginIsAutomatic, DISPATCH_PROPERTYGET }, - { L"PluginDescription", DISPID_PluginDescription, DISPATCH_PROPERTYGET }, - { L"PluginEvent", DISPID_PluginEvent, DISPATCH_PROPERTYGET }, + { L"PluginEvent", DISPID_PluginEvent, 0, DISPATCH_PROPERTYGET }, + { L"PluginDescription", DISPID_PluginDescription, 0, DISPATCH_PROPERTYGET }, + { L"PluginIsAutomatic", DISPID_PluginIsAutomatic, 0, DISPATCH_PROPERTYGET }, + { L"PluginFileFilters", DISPID_PluginFileFilters, 0, DISPATCH_PROPERTYGET }, + { L"UnpackFile", DISPID_UnpackFile, 4, DISPATCH_METHOD }, + { L"PackFile", DISPID_PackFile , 4, DISPATCH_METHOD }, + { L"ShowSettingsDialog", DISPID_ShowSettingsDialog, 0, DISPATCH_METHOD }, }; for (auto item : memberInfo) { + if (item.id == DISPID_PluginIsAutomatic && sEvent == _T("EDITOR_SCRIPT")) + break; + m_mapNameToIndex.insert_or_assign(item.name, static_cast(m_memberInfo.size())); + m_mapDispIdToIndex.insert_or_assign(item.id, static_cast(m_memberInfo.size())); m_memberInfo.push_back(item); - m_mapNameToIndex.emplace(item.name, item.id); } } @@ -78,7 +94,7 @@ public: auto it = m_mapNameToIndex.find(rgszNames[i]); if (it == m_mapNameToIndex.end()) return DISP_E_UNKNOWNNAME; - rgDispId[i] = it->second; + rgDispId[i] = m_memberInfo[it->second].id; } return S_OK; } @@ -115,6 +131,15 @@ public: case DISPID_ShowSettingsDialog: hr = ShowSettingsDialog(&pVarResult->boolVal); break; + default: + if (m_mapDispIdToIndex.find(dispIdMember) != m_mapDispIdToIndex.end()) + { + BSTR bstrText = pDispParams->rgvarg[0].bstrVal; + pVarResult->vt = VT_BSTR; + BSTR* pbstrResult = &pVarResult->bstrVal; + hr = m_memberInfo[m_mapDispIdToIndex[dispIdMember]].pFunc(this, bstrText, pbstrResult); + } + break; } } else if (wFlags == DISPATCH_PROPERTYGET) @@ -160,9 +185,12 @@ public: if (index >= m_memberInfo.size()) return E_INVALIDARG; auto* pFuncDesc = new FUNCDESC(); + pFuncDesc->funckind = FUNC_DISPATCH; pFuncDesc->invkind = static_cast(m_memberInfo[index].flags); pFuncDesc->wFuncFlags = 0; - pFuncDesc->memid = index; + pFuncDesc->cParams = m_memberInfo[index].params; + pFuncDesc->memid = m_memberInfo[index].id; + pFuncDesc->callconv = CC_STDCALL; *ppFuncDesc = pFuncDesc; return S_OK; } @@ -174,9 +202,9 @@ public: HRESULT STDMETHODCALLTYPE GetNames(MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) override { - if (memid >= m_memberInfo.size()) + if (m_mapDispIdToIndex.find(memid) == m_mapDispIdToIndex.end()) return E_INVALIDARG; - *rgBstrNames = SysAllocString(m_memberInfo[memid].name.c_str()); + *rgBstrNames = SysAllocString(m_memberInfo[m_mapDispIdToIndex[memid]].name.c_str()); *pcNames = 1; return S_OK; } @@ -292,9 +320,19 @@ public: return S_OK; } + bool AddFunction(const std::wstring& name, HRESULT(STDMETHODCALLTYPE* pFunc)(IDispatch *pDispatch, BSTR bstrText, BSTR* pbstrResult)) + { + DISPID dispid = static_cast(m_memberInfo.size()) + 100; + m_mapNameToIndex.insert_or_assign(name, static_cast(m_memberInfo.size())); + m_mapDispIdToIndex.insert_or_assign(dispid, static_cast(m_memberInfo.size())); + m_memberInfo.emplace_back(MemberInfo{ name, dispid, 1, DISPATCH_METHOD, pFunc }); + return true; + } + protected: int m_nRef; std::map m_mapNameToIndex; + std::map m_mapDispIdToIndex; std::vector m_memberInfo; std::wstring m_sEvent; std::wstring m_sDescription;