diff options
author | Zufu Liu <unknown> | 2023-04-09 09:55:01 +1000 |
---|---|---|
committer | Zufu Liu <unknown> | 2023-04-09 09:55:01 +1000 |
commit | 378ed7a5b2cf2f479aadeb4dd4238c798bd25c1f (patch) | |
tree | adbc7de72307866e2bc4eb52fe3e42d9f94df789 | |
parent | 9a8adc7fe7d845b1a8b1350436d2c012662db08a (diff) | |
download | scintilla-mirror-378ed7a5b2cf2f479aadeb4dd4238c798bd25c1f.tar.gz |
Feature [feature-requests:#1485] Change COM class implementation from C to C++.
-rw-r--r-- | win32/ScintillaWin.cxx | 305 |
1 files changed, 139 insertions, 166 deletions
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 42927433f..9a26cf5b7 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -167,44 +167,82 @@ constexpr bool KeyboardIsNumericKeypadFunction(uptr_t wParam, sptr_t lParam) { } } -typedef void VFunction(void); - /** */ -class FormatEnumerator { +class FormatEnumerator final : public IEnumFORMATETC { public: - VFunction **vtbl; ULONG ref; ULONG pos; std::vector<CLIPFORMAT> formats; FormatEnumerator(ULONG pos_, const CLIPFORMAT formats_[], size_t formatsLen_); + + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv) override; + STDMETHODIMP_(ULONG)AddRef() override; + STDMETHODIMP_(ULONG)Release() override; + + // IEnumFORMATETC + STDMETHODIMP Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) override; + STDMETHODIMP Skip(ULONG celt) override; + STDMETHODIMP Reset() override; + STDMETHODIMP Clone(IEnumFORMATETC **ppenum) override; }; /** */ -class DropSource { +class DropSource final : public IDropSource { public: - VFunction **vtbl; - ScintillaWin *sci; - DropSource() noexcept; + ScintillaWin *sci = nullptr; + + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv) override; + STDMETHODIMP_(ULONG)AddRef() override; + STDMETHODIMP_(ULONG)Release() override; + + // IDropSource + STDMETHODIMP QueryContinueDrag(BOOL fEsc, DWORD grfKeyState) override; + STDMETHODIMP GiveFeedback(DWORD) override; }; /** */ -class DataObject { +class DataObject final : public IDataObject { public: - VFunction **vtbl; - ScintillaWin *sci; - DataObject() noexcept; + ScintillaWin *sci = nullptr; + + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv) override; + STDMETHODIMP_(ULONG)AddRef() override; + STDMETHODIMP_(ULONG)Release() override; + + // IDataObject + STDMETHODIMP GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM) override; + STDMETHODIMP GetDataHere(FORMATETC *, STGMEDIUM *) override; + STDMETHODIMP QueryGetData(FORMATETC *pFE) override; + STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *, FORMATETC *pFEOut) override; + STDMETHODIMP SetData(FORMATETC *, STGMEDIUM *, BOOL) override; + STDMETHODIMP EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnum) override; + STDMETHODIMP DAdvise(FORMATETC *, DWORD, IAdviseSink *, PDWORD) override; + STDMETHODIMP DUnadvise(DWORD) override; + STDMETHODIMP EnumDAdvise(IEnumSTATDATA **) override; }; /** */ -class DropTarget { +class DropTarget final : public IDropTarget { public: - VFunction **vtbl; - ScintillaWin *sci; - DropTarget() noexcept; + ScintillaWin *sci = nullptr; + + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv) override; + STDMETHODIMP_(ULONG)AddRef() override; + STDMETHODIMP_(ULONG)Release() override; + + // IDropTarget + STDMETHODIMP DragEnter(LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) override; + STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) override; + STDMETHODIMP DragLeave() override; + STDMETHODIMP Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) override; }; class IMContext { @@ -749,8 +787,8 @@ void ScintillaWin::StartDrag() { inDragDrop = DragDrop::dragging; DWORD dwEffect = 0; dropWentOutside = true; - IDataObject *pDataObject = reinterpret_cast<IDataObject *>(&dob); - IDropSource *pDropSource = reinterpret_cast<IDropSource *>(&ds); + IDataObject *pDataObject = &dob; + IDropSource *pDropSource = &ds; //Platform::DebugPrintf("About to DoDragDrop %x %x\n", pDataObject, pDropSource); const HRESULT hr = ::DoDragDrop( pDataObject, @@ -1964,7 +2002,7 @@ sptr_t ScintillaWin::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) { UpdateBaseElements(); // Get Intellimouse scroll line parameters GetIntelliMouseParameters(); - ::RegisterDragDrop(MainHWND(), reinterpret_cast<IDropTarget *>(&dt)); + ::RegisterDragDrop(MainHWND(), &dt); break; case WM_COMMAND: @@ -2741,97 +2779,82 @@ void ScintillaWin::ClaimSelection() { } /// Implement IUnknown - -STDMETHODIMP_(ULONG)FormatEnumerator_AddRef(FormatEnumerator *fe); -STDMETHODIMP FormatEnumerator_QueryInterface(FormatEnumerator *fe, REFIID riid, PVOID *ppv) { +STDMETHODIMP FormatEnumerator::QueryInterface(REFIID riid, PVOID *ppv) { //Platform::DebugPrintf("EFE QI"); *ppv = nullptr; - if (riid == IID_IUnknown) - *ppv = reinterpret_cast<IEnumFORMATETC *>(fe); - if (riid == IID_IEnumFORMATETC) - *ppv = reinterpret_cast<IEnumFORMATETC *>(fe); - if (!*ppv) + if (riid == IID_IUnknown || riid == IID_IEnumFORMATETC) { + *ppv = this; + } else { return E_NOINTERFACE; - FormatEnumerator_AddRef(fe); + } + AddRef(); return S_OK; } -STDMETHODIMP_(ULONG)FormatEnumerator_AddRef(FormatEnumerator *fe) { - return ++fe->ref; +STDMETHODIMP_(ULONG)FormatEnumerator::AddRef() { + return ++ref; } -STDMETHODIMP_(ULONG)FormatEnumerator_Release(FormatEnumerator *fe) { - fe->ref--; - if (fe->ref > 0) - return fe->ref; - delete fe; - return 0; +STDMETHODIMP_(ULONG)FormatEnumerator::Release() { + const ULONG refs = --ref; + if (refs == 0) { + delete this; + } + return refs; } /// Implement IEnumFORMATETC -STDMETHODIMP FormatEnumerator_Next(FormatEnumerator *fe, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) { +STDMETHODIMP FormatEnumerator::Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) { if (!rgelt) return E_POINTER; ULONG putPos = 0; - while ((fe->pos < fe->formats.size()) && (putPos < celt)) { - rgelt->cfFormat = fe->formats[fe->pos]; + while ((pos < formats.size()) && (putPos < celt)) { + rgelt->cfFormat = formats[pos]; rgelt->ptd = nullptr; rgelt->dwAspect = DVASPECT_CONTENT; rgelt->lindex = -1; rgelt->tymed = TYMED_HGLOBAL; rgelt++; - fe->pos++; + pos++; putPos++; } if (pceltFetched) *pceltFetched = putPos; return putPos ? S_OK : S_FALSE; } -STDMETHODIMP FormatEnumerator_Skip(FormatEnumerator *fe, ULONG celt) { - fe->pos += celt; +STDMETHODIMP FormatEnumerator::Skip(ULONG celt) { + pos += celt; return S_OK; } -STDMETHODIMP FormatEnumerator_Reset(FormatEnumerator *fe) { - fe->pos = 0; +STDMETHODIMP FormatEnumerator::Reset() { + pos = 0; return S_OK; } -STDMETHODIMP FormatEnumerator_Clone(FormatEnumerator *fe, IEnumFORMATETC **ppenum) { +STDMETHODIMP FormatEnumerator::Clone(IEnumFORMATETC **ppenum) { FormatEnumerator *pfe; try { - pfe = new FormatEnumerator(fe->pos, &fe->formats[0], fe->formats.size()); + pfe = new FormatEnumerator(pos, &formats[0], formats.size()); } catch (...) { return E_OUTOFMEMORY; } - return FormatEnumerator_QueryInterface(pfe, IID_IEnumFORMATETC, - reinterpret_cast<void **>(ppenum)); + return pfe->QueryInterface(IID_IEnumFORMATETC, reinterpret_cast<void **>(ppenum)); } -static VFunction *vtFormatEnumerator[] = { - (VFunction *)(FormatEnumerator_QueryInterface), - (VFunction *)(FormatEnumerator_AddRef), - (VFunction *)(FormatEnumerator_Release), - (VFunction *)(FormatEnumerator_Next), - (VFunction *)(FormatEnumerator_Skip), - (VFunction *)(FormatEnumerator_Reset), - (VFunction *)(FormatEnumerator_Clone) -}; - FormatEnumerator::FormatEnumerator(ULONG pos_, const CLIPFORMAT formats_[], size_t formatsLen_) { - vtbl = vtFormatEnumerator; ref = 0; // First QI adds first reference... pos = pos_; formats.insert(formats.begin(), formats_, formats_+formatsLen_); } /// Implement IUnknown -STDMETHODIMP DropSource_QueryInterface(DropSource *ds, REFIID riid, PVOID *ppv) { - return ds->sci->QueryInterface(riid, ppv); +STDMETHODIMP DropSource::QueryInterface(REFIID riid, PVOID *ppv) { + return sci->QueryInterface(riid, ppv); } -STDMETHODIMP_(ULONG)DropSource_AddRef(DropSource *ds) { - return ds->sci->AddRef(); +STDMETHODIMP_(ULONG)DropSource::AddRef() { + return sci->AddRef(); } -STDMETHODIMP_(ULONG)DropSource_Release(DropSource *ds) { - return ds->sci->Release(); +STDMETHODIMP_(ULONG)DropSource::Release() { + return sci->Release(); } /// Implement IDropSource -STDMETHODIMP DropSource_QueryContinueDrag(DropSource *, BOOL fEsc, DWORD grfKeyState) { +STDMETHODIMP DropSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState) { if (fEsc) return DRAGDROP_S_CANCEL; if (!(grfKeyState & MK_LBUTTON)) @@ -2839,46 +2862,33 @@ STDMETHODIMP DropSource_QueryContinueDrag(DropSource *, BOOL fEsc, DWORD grfKeyS return S_OK; } -STDMETHODIMP DropSource_GiveFeedback(DropSource *, DWORD) { +STDMETHODIMP DropSource::GiveFeedback(DWORD) { return DRAGDROP_S_USEDEFAULTCURSORS; } -static VFunction *vtDropSource[] = { - (VFunction *)(DropSource_QueryInterface), - (VFunction *)(DropSource_AddRef), - (VFunction *)(DropSource_Release), - (VFunction *)(DropSource_QueryContinueDrag), - (VFunction *)(DropSource_GiveFeedback) -}; - -DropSource::DropSource() noexcept { - vtbl = vtDropSource; - sci = nullptr; -} - /// Implement IUnkown -STDMETHODIMP DataObject_QueryInterface(DataObject *pd, REFIID riid, PVOID *ppv) { - //Platform::DebugPrintf("DO QI %x\n", pd); - return pd->sci->QueryInterface(riid, ppv); +STDMETHODIMP DataObject::QueryInterface(REFIID riid, PVOID *ppv) { + //Platform::DebugPrintf("DO QI %p\n", this); + return sci->QueryInterface(riid, ppv); } -STDMETHODIMP_(ULONG)DataObject_AddRef(DataObject *pd) { - return pd->sci->AddRef(); +STDMETHODIMP_(ULONG)DataObject::AddRef() { + return sci->AddRef(); } -STDMETHODIMP_(ULONG)DataObject_Release(DataObject *pd) { - return pd->sci->Release(); +STDMETHODIMP_(ULONG)DataObject::Release() { + return sci->Release(); } /// Implement IDataObject -STDMETHODIMP DataObject_GetData(DataObject *pd, FORMATETC *pFEIn, STGMEDIUM *pSTM) { - return pd->sci->GetData(pFEIn, pSTM); +STDMETHODIMP DataObject::GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM) { + return sci->GetData(pFEIn, pSTM); } -STDMETHODIMP DataObject_GetDataHere(DataObject *, FORMATETC *, STGMEDIUM *) { +STDMETHODIMP DataObject::GetDataHere(FORMATETC *, STGMEDIUM *) { //Platform::DebugPrintf("DOB GetDataHere\n"); return E_NOTIMPL; } -STDMETHODIMP DataObject_QueryGetData(DataObject *pd, FORMATETC *pFE) { - if (pd->sci->DragIsRectangularOK(pFE->cfFormat) && IsValidFormatEtc(pFE)) { +STDMETHODIMP DataObject::QueryGetData(FORMATETC *pFE) { + if (sci->DragIsRectangularOK(pFE->cfFormat) && IsValidFormatEtc(pFE)) { return S_OK; } @@ -2889,7 +2899,7 @@ STDMETHODIMP DataObject_QueryGetData(DataObject *pd, FORMATETC *pFE) { } } -STDMETHODIMP DataObject_GetCanonicalFormatEtc(DataObject *, FORMATETC *, FORMATETC *pFEOut) { +STDMETHODIMP DataObject::GetCanonicalFormatEtc(FORMATETC *, FORMATETC *pFEOut) { //Platform::DebugPrintf("DOB GetCanon\n"); pFEOut->cfFormat = CF_UNICODETEXT; pFEOut->ptd = nullptr; @@ -2899,12 +2909,12 @@ STDMETHODIMP DataObject_GetCanonicalFormatEtc(DataObject *, FORMATETC *, FORMATE return S_OK; } -STDMETHODIMP DataObject_SetData(DataObject *, FORMATETC *, STGMEDIUM *, BOOL) { +STDMETHODIMP DataObject::SetData(FORMATETC *, STGMEDIUM *, BOOL) { //Platform::DebugPrintf("DOB SetData\n"); return E_FAIL; } -STDMETHODIMP DataObject_EnumFormatEtc(DataObject *pd, DWORD dwDirection, IEnumFORMATETC **ppEnum) { +STDMETHODIMP DataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnum) { try { //Platform::DebugPrintf("DOB EnumFormatEtc %d\n", dwDirection); if (dwDirection != DATADIR_GET) { @@ -2914,115 +2924,77 @@ STDMETHODIMP DataObject_EnumFormatEtc(DataObject *pd, DWORD dwDirection, IEnumFO const CLIPFORMAT formats[] = {CF_UNICODETEXT}; FormatEnumerator *pfe = new FormatEnumerator(0, formats, std::size(formats)); - return FormatEnumerator_QueryInterface(pfe, IID_IEnumFORMATETC, - reinterpret_cast<void **>(ppEnum)); + return pfe->QueryInterface(IID_IEnumFORMATETC, reinterpret_cast<void **>(ppEnum)); } catch (std::bad_alloc &) { - pd->sci->errorStatus = Status::BadAlloc; + sci->errorStatus = Status::BadAlloc; return E_OUTOFMEMORY; } catch (...) { - pd->sci->errorStatus = Status::Failure; + sci->errorStatus = Status::Failure; return E_FAIL; } } -STDMETHODIMP DataObject_DAdvise(DataObject *, FORMATETC *, DWORD, IAdviseSink *, PDWORD) { +STDMETHODIMP DataObject::DAdvise(FORMATETC *, DWORD, IAdviseSink *, PDWORD) { //Platform::DebugPrintf("DOB DAdvise\n"); return E_FAIL; } -STDMETHODIMP DataObject_DUnadvise(DataObject *, DWORD) { +STDMETHODIMP DataObject::DUnadvise(DWORD) { //Platform::DebugPrintf("DOB DUnadvise\n"); return E_FAIL; } -STDMETHODIMP DataObject_EnumDAdvise(DataObject *, IEnumSTATDATA **) { +STDMETHODIMP DataObject::EnumDAdvise(IEnumSTATDATA **) { //Platform::DebugPrintf("DOB EnumDAdvise\n"); return E_FAIL; } -static VFunction *vtDataObject[] = { - (VFunction *)(DataObject_QueryInterface), - (VFunction *)(DataObject_AddRef), - (VFunction *)(DataObject_Release), - (VFunction *)(DataObject_GetData), - (VFunction *)(DataObject_GetDataHere), - (VFunction *)(DataObject_QueryGetData), - (VFunction *)(DataObject_GetCanonicalFormatEtc), - (VFunction *)(DataObject_SetData), - (VFunction *)(DataObject_EnumFormatEtc), - (VFunction *)(DataObject_DAdvise), - (VFunction *)(DataObject_DUnadvise), - (VFunction *)(DataObject_EnumDAdvise) -}; - -DataObject::DataObject() noexcept { - vtbl = vtDataObject; - sci = nullptr; -} - /// Implement IUnknown -STDMETHODIMP DropTarget_QueryInterface(DropTarget *dt, REFIID riid, PVOID *ppv) { - //Platform::DebugPrintf("DT QI %x\n", dt); - return dt->sci->QueryInterface(riid, ppv); +STDMETHODIMP DropTarget::QueryInterface(REFIID riid, PVOID *ppv) { + //Platform::DebugPrintf("DT QI %p\n", this); + return sci->QueryInterface(riid, ppv); } -STDMETHODIMP_(ULONG)DropTarget_AddRef(DropTarget *dt) { - return dt->sci->AddRef(); +STDMETHODIMP_(ULONG)DropTarget::AddRef() { + return sci->AddRef(); } -STDMETHODIMP_(ULONG)DropTarget_Release(DropTarget *dt) { - return dt->sci->Release(); +STDMETHODIMP_(ULONG)DropTarget::Release() { + return sci->Release(); } /// Implement IDropTarget by forwarding to Scintilla -STDMETHODIMP DropTarget_DragEnter(DropTarget *dt, LPDATAOBJECT pIDataSource, DWORD grfKeyState, - POINTL pt, PDWORD pdwEffect) { +STDMETHODIMP DropTarget::DragEnter(LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) { try { - return dt->sci->DragEnter(pIDataSource, grfKeyState, pt, pdwEffect); + return sci->DragEnter(pIDataSource, grfKeyState, pt, pdwEffect); } catch (...) { - dt->sci->errorStatus = Status::Failure; + sci->errorStatus = Status::Failure; } return E_FAIL; } -STDMETHODIMP DropTarget_DragOver(DropTarget *dt, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) { +STDMETHODIMP DropTarget::DragOver(DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) { try { - return dt->sci->DragOver(grfKeyState, pt, pdwEffect); + return sci->DragOver(grfKeyState, pt, pdwEffect); } catch (...) { - dt->sci->errorStatus = Status::Failure; + sci->errorStatus = Status::Failure; } return E_FAIL; } -STDMETHODIMP DropTarget_DragLeave(DropTarget *dt) { +STDMETHODIMP DropTarget::DragLeave() { try { - return dt->sci->DragLeave(); + return sci->DragLeave(); } catch (...) { - dt->sci->errorStatus = Status::Failure; + sci->errorStatus = Status::Failure; } return E_FAIL; } -STDMETHODIMP DropTarget_Drop(DropTarget *dt, LPDATAOBJECT pIDataSource, DWORD grfKeyState, - POINTL pt, PDWORD pdwEffect) { +STDMETHODIMP DropTarget::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) { try { - return dt->sci->Drop(pIDataSource, grfKeyState, pt, pdwEffect); + return sci->Drop(pIDataSource, grfKeyState, pt, pdwEffect); } catch (...) { - dt->sci->errorStatus = Status::Failure; + sci->errorStatus = Status::Failure; } return E_FAIL; } -static VFunction *vtDropTarget[] = { - (VFunction *)(DropTarget_QueryInterface), - (VFunction *)(DropTarget_AddRef), - (VFunction *)(DropTarget_Release), - (VFunction *)(DropTarget_DragEnter), - (VFunction *)(DropTarget_DragOver), - (VFunction *)(DropTarget_DragLeave), - (VFunction *)(DropTarget_Drop) -}; - -DropTarget::DropTarget() noexcept { - vtbl = vtDropTarget; - sci = nullptr; -} - /** * DBCS: support Input Method Editor (IME). * Called when IME Window opened. @@ -3350,14 +3322,15 @@ DWORD ScintillaWin::EffectFromState(DWORD grfKeyState) const noexcept { /// Implement IUnknown STDMETHODIMP ScintillaWin::QueryInterface(REFIID riid, PVOID *ppv) { *ppv = nullptr; - if (riid == IID_IUnknown) - *ppv = reinterpret_cast<IDropTarget *>(&dt); - if (riid == IID_IDropSource) - *ppv = reinterpret_cast<IDropSource *>(&ds); - if (riid == IID_IDropTarget) - *ppv = reinterpret_cast<IDropTarget *>(&dt); - if (riid == IID_IDataObject) - *ppv = reinterpret_cast<IDataObject *>(&dob); + if (riid == IID_IUnknown) { + *ppv = &dt; + } else if (riid == IID_IDropSource) { + *ppv = &ds; + } else if (riid == IID_IDropTarget) { + *ppv = &dt; + } else if (riid == IID_IDataObject) { + *ppv = &dob; + } if (!*ppv) return E_NOINTERFACE; return S_OK; |