summaryrefslogtreecommitdiff
path: root/libs/mTextControl/src/dataobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/mTextControl/src/dataobject.cpp')
-rw-r--r--libs/mTextControl/src/dataobject.cpp276
1 files changed, 276 insertions, 0 deletions
diff --git a/libs/mTextControl/src/dataobject.cpp b/libs/mTextControl/src/dataobject.cpp
new file mode 100644
index 0000000000..1d14d28afb
--- /dev/null
+++ b/libs/mTextControl/src/dataobject.cpp
@@ -0,0 +1,276 @@
+//
+// DATAOBJECT.CPP
+//
+// Implementation of the IDataObject COM interface
+//
+// By J Brown 2004
+//
+// www.catch22.net
+//
+
+//#define STRICT
+
+#include "stdafx.h"
+
+const ULONG MAX_FORMATS = 100;
+
+HRESULT CreateEnumFormatEtc(UINT nNumFormats, FORMATETC *pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
+
+class CDataObject : public IDataObject
+{
+public:
+ //
+ // IUnknown members
+ //
+ HRESULT __stdcall QueryInterface(REFIID iid, void ** ppvObject);
+ ULONG __stdcall AddRef(void);
+ ULONG __stdcall Release(void);
+
+ //
+ // IDataObject members
+ //
+ HRESULT __stdcall GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium);
+ HRESULT __stdcall GetDataHere(FORMATETC *pFormatEtc, STGMEDIUM *pMedium);
+ HRESULT __stdcall QueryGetData(FORMATETC *pFormatEtc);
+ HRESULT __stdcall GetCanonicalFormatEtc(FORMATETC *pFormatEct, FORMATETC *pFormatEtcOut);
+ HRESULT __stdcall SetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium, BOOL fRelease);
+ HRESULT __stdcall EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
+ HRESULT __stdcall DAdvise(FORMATETC *pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
+ HRESULT __stdcall DUnadvise(DWORD dwConnection);
+ HRESULT __stdcall EnumDAdvise(IEnumSTATDATA **ppEnumAdvise);
+
+ //
+ // Constructor / Destructor
+ //
+ CDataObject(const FORMATETC *fmt, const STGMEDIUM *stgmed, int count);
+ ~CDataObject();
+
+private:
+
+ int LookupFormatEtc(FORMATETC *pFormatEtc);
+
+ //
+ // any private members and functions
+ //
+ LONG m_lRefCount;
+
+ FORMATETC *m_pFormatEtc;
+ STGMEDIUM *m_pStgMedium;
+ LONG m_nNumFormats;
+
+};
+
+//
+// Constructor
+//
+CDataObject::CDataObject(const FORMATETC *fmtetc, const STGMEDIUM *stgmed, int count)
+{
+ m_lRefCount = 1;
+ m_nNumFormats = count;
+
+ m_pFormatEtc = new FORMATETC[count];
+ m_pStgMedium = new STGMEDIUM[count];
+
+ for (int i = 0; i < count; i++) {
+ m_pFormatEtc[i] = fmtetc[i];
+ m_pStgMedium[i] = stgmed[i];
+ }
+}
+
+//
+// Destructor
+//
+CDataObject::~CDataObject()
+{
+ // cleanup
+ for (int i = 0; i < m_nNumFormats; i++) {
+ // ReleaseStgMedium(&m_pStgMedium[i]);
+ }
+
+ if (m_pFormatEtc) delete[] m_pFormatEtc;
+ if (m_pStgMedium) delete[] m_pStgMedium;
+}
+
+//
+// IUnknown::AddRef
+//
+ULONG __stdcall CDataObject::AddRef(void)
+{
+ // increment object reference count
+ return InterlockedIncrement(&m_lRefCount);
+}
+
+//
+// IUnknown::Release
+//
+ULONG __stdcall CDataObject::Release(void)
+{
+ // decrement object reference count
+ LONG count = InterlockedDecrement(&m_lRefCount);
+
+ if (count == 0) {
+ delete this;
+ return 0;
+ }
+
+ return count;
+}
+
+//
+// IUnknown::QueryInterface
+//
+HRESULT __stdcall CDataObject::QueryInterface(REFIID iid, void **ppvObject)
+{
+ // check to see what interface has been requested
+ if (iid == IID_IDataObject || iid == IID_IUnknown) {
+ AddRef();
+ *ppvObject = this;
+ return S_OK;
+ }
+
+ *ppvObject = nullptr;
+ return E_NOINTERFACE;
+}
+
+int CDataObject::LookupFormatEtc(FORMATETC *pFormatEtc)
+{
+ for (int i = 0; i < m_nNumFormats; i++) {
+ if ((pFormatEtc->tymed & m_pFormatEtc[i].tymed) &&
+ pFormatEtc->cfFormat == m_pFormatEtc[i].cfFormat &&
+ pFormatEtc->dwAspect == m_pFormatEtc[i].dwAspect) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+//
+// IDataObject::GetData
+//
+HRESULT __stdcall CDataObject::GetData(FORMATETC *pFormatEtc, STGMEDIUM *pMedium)
+{
+ int idx;
+
+ //
+ // try to match the requested FORMATETC with one of our supported formats
+ //
+ if ((idx = LookupFormatEtc(pFormatEtc)) == -1) {
+ return DV_E_FORMATETC;
+ }
+
+ //
+ // found a match! transfer the data into the supplied storage-medium
+ //
+ pMedium->tymed = m_pFormatEtc[idx].tymed;
+ pMedium->pUnkForRelease = nullptr;
+
+ switch (pMedium->tymed) {
+ case TYMED_HGLOBAL:
+ case TYMED_GDI:
+ case TYMED_ENHMF:
+ // pMedium->hBitmap = (HBITMAP)OleDuplicateData(m_pStgMedium[idx].hBitmap, pFormatEtc->cfFormat, 0);
+ pMedium->hBitmap = m_pStgMedium[idx].hBitmap;
+ break;
+
+ default:
+ return DV_E_FORMATETC;
+ }
+ if (pMedium->hBitmap == nullptr) return STG_E_MEDIUMFULL;
+
+ return S_OK;
+}
+
+//
+// IDataObject::GetDataHere
+//
+HRESULT __stdcall CDataObject::GetDataHere(FORMATETC *, STGMEDIUM *)
+{
+ // GetDataHere is only required for IStream and IStorage mediums
+ // It is an error to call GetDataHere for things like HGLOBAL and other clipboard formats
+ //
+ // OleFlushClipboard
+ //
+ return DATA_E_FORMATETC;
+}
+
+//
+// IDataObject::QueryGetData
+//
+// Called to see if the IDataObject supports the specified format of data
+//
+HRESULT __stdcall CDataObject::QueryGetData(FORMATETC *pFormatEtc)
+{
+ return (LookupFormatEtc(pFormatEtc) == -1) ? DV_E_FORMATETC : S_OK;
+}
+
+//
+// IDataObject::GetCanonicalFormatEtc
+//
+HRESULT __stdcall CDataObject::GetCanonicalFormatEtc(FORMATETC *, FORMATETC *pFormatEtcOut)
+{
+ // Apparently we have to set this field to NULL even though we don't do anything else
+ pFormatEtcOut->ptd = nullptr;
+ return E_NOTIMPL;
+}
+
+//
+// IDataObject::SetData
+//
+HRESULT __stdcall CDataObject::SetData(FORMATETC *, STGMEDIUM *, BOOL)
+{
+ return E_NOTIMPL;
+}
+
+//
+// IDataObject::EnumFormatEtc
+//
+HRESULT __stdcall CDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc)
+{
+ if (dwDirection == DATADIR_GET) {
+ // for Win2k+ you can use the SHCreateStdEnumFmtEtc API call, however
+ // to support all Windows platforms we need to implement IEnumFormatEtc ourselves.
+ return CreateEnumFormatEtc(m_nNumFormats, m_pFormatEtc, ppEnumFormatEtc);
+ }
+ else {
+ // the direction specified is not support for drag+drop
+ return E_NOTIMPL;
+ }
+}
+
+//
+// IDataObject::DAdvise
+//
+HRESULT __stdcall CDataObject::DAdvise(FORMATETC *, DWORD, IAdviseSink *, DWORD *)
+{
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+//
+// IDataObject::DUnadvise
+//
+HRESULT __stdcall CDataObject::DUnadvise(DWORD)
+{
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+//
+// IDataObject::EnumDAdvise
+//
+HRESULT __stdcall CDataObject::EnumDAdvise(IEnumSTATDATA **)
+{
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+//
+// Helper function
+//
+HRESULT CreateDataObject(const FORMATETC *fmtetc, const STGMEDIUM *stgmeds, UINT count, IDataObject **ppDataObject)
+{
+ if (ppDataObject == nullptr)
+ return E_INVALIDARG;
+
+ *ppDataObject = new CDataObject(fmtetc, stgmeds, count);
+
+ return (*ppDataObject) ? S_OK : E_OUTOFMEMORY;
+}