OSDN Git Service

6f03b1be81ea45e322e52a5a8b8003284f2492f9
[winmerge-jp/winmerge-jp.git] / Src / WinMergePluginBase.h
1 #include <oleauto.h>
2 #include <string>
3 #include <map>
4
5 class WinMergePluginBase : public IDispatch, public ITypeInfo
6 {
7 public:
8         enum
9         {
10                 DISPID_UnpackFile,
11                 DISPID_PackFile,
12                 DISPID_ShowSettingsDialog,
13                 DISPID_PluginFileFilters,
14                 DISPID_PluginIsAutomatic,
15                 DISPID_PluginDescription,
16                 DISPID_PluginEvent,
17         };
18         struct MemberInfo { std::wstring name; DISPID id; int flags; };
19
20         WinMergePluginBase() : m_nRef(0)
21         {
22                 static const MemberInfo memberInfo[] =
23                 {
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 },
31                 };
32                 for (auto item : memberInfo)
33                 {
34                         m_memberInfo.push_back(item);
35                         m_mapNameToIndex.emplace(item.name, item.id);
36                 }
37         }
38
39         virtual ~WinMergePluginBase() {}
40
41         HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override
42         {
43                 return E_NOTIMPL;
44         }
45
46         ULONG STDMETHODCALLTYPE AddRef(void) override
47         {
48                 return ++m_nRef;
49         }
50
51         ULONG STDMETHODCALLTYPE Release(void) override
52         {
53                 if (--m_nRef == 0)
54                 {
55                         delete this;
56                         return 0;
57                 }
58                 return m_nRef;
59         }
60
61         HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT* pctinfo) override
62         {
63                 *pctinfo = static_cast<UINT>(m_memberInfo.size());
64                 return S_OK;
65         }
66
67         HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) override
68         {
69                 *ppTInfo = this;
70                 (*ppTInfo)->AddRef();
71                 return S_OK;
72         }
73
74         HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) override
75         {
76                 for (unsigned i = 0; i < cNames; ++i)
77                 {
78                         auto it = m_mapNameToIndex.find(rgszNames[i]);
79                         if (it == m_mapNameToIndex.end())
80                                 return DISP_E_UNKNOWNNAME;
81                         rgDispId[i] = it->second;
82                 }
83                 return S_OK;
84         }
85
86         HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) override
87         {
88                 if (!pDispParams)
89                         return DISP_E_BADVARTYPE;
90                 HRESULT hr = E_NOTIMPL;
91                 if (wFlags == DISPATCH_METHOD)
92                 {
93                         switch (dispIdMember)
94                         {
95                         case DISPID_UnpackFile:
96                         {
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);
103                                 break;
104                         }
105                         case DISPID_PackFile:
106                         {
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);
113                                 break;
114                         }
115                         case DISPID_ShowSettingsDialog:
116                                 hr = ShowSettingsDialog(&pVarResult->boolVal);
117                                 break;
118                         }
119                 }
120                 else if (wFlags == DISPATCH_PROPERTYGET)
121                 {
122                         switch (dispIdMember)
123                         {
124                         case DISPID_PluginFileFilters:
125                                 pVarResult->vt = VT_BSTR;
126                                 hr = get_PluginFileFilters(&pVarResult->bstrVal);
127                                 break;
128                         case DISPID_PluginIsAutomatic:
129                                 pVarResult->vt = VT_BOOL;
130                                 hr = get_PluginIsAutomatic(&pVarResult->boolVal);
131                                 break;
132                         case DISPID_PluginDescription:
133                                 pVarResult->vt = VT_BSTR;
134                                 hr = get_PluginDescription(&pVarResult->bstrVal);
135                                 break;
136                         case DISPID_PluginEvent:
137                                 pVarResult->vt = VT_BSTR;
138                                 hr = get_PluginEvent(&pVarResult->bstrVal);
139                                 break;
140                         }
141                 }
142                 return hr;
143         }
144
145         HRESULT STDMETHODCALLTYPE GetTypeAttr(TYPEATTR** ppTypeAttr) override
146         {
147                 auto* pTypeAttr = new TYPEATTR();
148                 pTypeAttr->cFuncs = static_cast<WORD>(m_memberInfo.size());
149                 *ppTypeAttr = pTypeAttr;
150                 return S_OK;
151         }
152         
153         HRESULT STDMETHODCALLTYPE GetTypeComp(ITypeComp** ppTComp) override
154         {
155                 return E_NOTIMPL;
156         }
157         
158         HRESULT STDMETHODCALLTYPE GetFuncDesc(UINT index, FUNCDESC** ppFuncDesc) override
159         {
160                 if (index >= m_memberInfo.size())
161                         return E_INVALIDARG;
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;
167                 return S_OK;
168         }
169         
170         HRESULT STDMETHODCALLTYPE GetVarDesc(UINT index, VARDESC** ppVarDesc) override
171         {
172                 return E_NOTIMPL;
173         }
174         
175         HRESULT STDMETHODCALLTYPE GetNames(MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) override
176         {
177                 if (memid >= m_memberInfo.size())
178                         return E_INVALIDARG;
179                 *rgBstrNames = SysAllocString(m_memberInfo[memid].name.c_str());
180                 *pcNames = 1;
181                 return S_OK;
182         }
183         
184         HRESULT STDMETHODCALLTYPE GetRefTypeOfImplType(UINT index, HREFTYPE *pRefType) override
185         {
186                 return E_NOTIMPL;
187         }
188
189         HRESULT STDMETHODCALLTYPE GetImplTypeFlags(UINT index, INT *pImplTypeFlags) override
190         {
191                 return E_NOTIMPL;
192         }
193         
194         HRESULT STDMETHODCALLTYPE GetIDsOfNames(LPOLESTR* rgszNames, UINT cNames, MEMBERID* pMemId) override
195         {
196                 return GetIDsOfNames(IID_NULL, rgszNames, cNames, 0, pMemId);
197         }
198         
199         HRESULT STDMETHODCALLTYPE Invoke(PVOID pvInstance, MEMBERID memid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) override
200         {
201                 return reinterpret_cast<IDispatch*>(pvInstance)->Invoke(memid, IID_NULL, 0, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
202         }
203         
204         HRESULT STDMETHODCALLTYPE GetDocumentation(MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile) override
205         {
206                 return E_NOTIMPL;
207         }
208         
209         HRESULT STDMETHODCALLTYPE GetDllEntry(MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
210         {
211                 return E_NOTIMPL;
212         }
213         
214         HRESULT STDMETHODCALLTYPE GetRefTypeInfo(HREFTYPE hRefType, ITypeInfo **ppTInfo) override
215         {
216                 return E_NOTIMPL;
217         }
218         
219         HRESULT STDMETHODCALLTYPE AddressOfMember(MEMBERID memid, INVOKEKIND invKind, PVOID *ppv) override
220         {
221                 return E_NOTIMPL;
222         }
223         
224         HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, REFIID riid, PVOID *ppvObj) override
225         {
226                 return E_NOTIMPL;
227         }
228         
229         HRESULT STDMETHODCALLTYPE GetMops(MEMBERID memid, BSTR *pBstrMops) override
230         {
231                 return E_NOTIMPL;
232         }
233         
234         HRESULT STDMETHODCALLTYPE GetContainingTypeLib(ITypeLib **ppTLib, UINT *pIndex) override
235         {
236                 return E_NOTIMPL;
237         }
238         
239         void STDMETHODCALLTYPE ReleaseTypeAttr(TYPEATTR *pTypeAttr) override
240         {
241                 delete pTypeAttr;
242         }
243         
244         void STDMETHODCALLTYPE ReleaseFuncDesc(FUNCDESC *pFuncDesc) override
245         {
246                 delete pFuncDesc;
247         }
248         
249         void STDMETHODCALLTYPE ReleaseVarDesc(VARDESC *pVarDesc) override
250         {
251         }
252         
253         virtual HRESULT STDMETHODCALLTYPE PackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT subcode, VARIANT_BOOL* pbSuccess)
254         {
255                 *pbSuccess = VARIANT_FALSE;
256                 return E_NOTIMPL;
257         }
258
259         virtual HRESULT STDMETHODCALLTYPE UnpackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT* pSubcode, VARIANT_BOOL* pbSuccess)
260         {
261                 *pbSuccess = VARIANT_FALSE;
262                 return E_NOTIMPL;
263         }
264
265         virtual HRESULT STDMETHODCALLTYPE ShowSettingsDialog(VARIANT_BOOL* pbHandled)
266         {
267                 *pbHandled = VARIANT_FALSE;
268                 return E_NOTIMPL;
269         }
270
271         virtual HRESULT STDMETHODCALLTYPE get_PluginIsAutomatic(VARIANT_BOOL* pVal)
272         {
273                 *pVal = m_bIsAutomatic ? -1 : 0;
274                 return S_OK;
275         }
276
277         virtual HRESULT STDMETHODCALLTYPE get_PluginFileFilters(BSTR* pVal)
278         {
279                 *pVal = SysAllocString(m_sFileFilters.c_str());
280                 return S_OK;
281         }
282
283         virtual HRESULT STDMETHODCALLTYPE get_PluginDescription(BSTR* pVal)
284         {
285                 *pVal = SysAllocString(m_sDescription.c_str());
286                 return S_OK;
287         }
288
289         virtual HRESULT STDMETHODCALLTYPE get_PluginEvent(BSTR* pVal)
290         {
291                 *pVal = SysAllocString(m_sEvent.c_str());
292                 return S_OK;
293         }
294
295 protected:
296         int m_nRef;
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;
302         bool m_bIsAutomatic;
303 };
304