diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp b/libraries/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp new file mode 100644 index 0000000..a3858bc --- /dev/null +++ b/libraries/ecore/src/lib/ecore_win32/ecore_win32_dnd_enumformatetc.cpp | |||
@@ -0,0 +1,157 @@ | |||
1 | |||
2 | #include <ole2.h> | ||
3 | |||
4 | #include "ecore_win32_dnd_enumformatetc.h" | ||
5 | |||
6 | |||
7 | // structors | ||
8 | |||
9 | CEnumFormatEtc::CEnumFormatEtc(FORMATETC *format_etc, int formats_num) | ||
10 | : ref_count_(1) | ||
11 | , index_(0) | ||
12 | , formats_num_(formats_num) | ||
13 | , format_etc_(new FORMATETC[formats_num]) | ||
14 | { | ||
15 | // make a new copy of each FORMATETC structure | ||
16 | for (unsigned int i = 0; i < formats_num_; i++) | ||
17 | { | ||
18 | DeepCopyFormatEtc(&format_etc_[i], &format_etc[i]); | ||
19 | } | ||
20 | } | ||
21 | |||
22 | CEnumFormatEtc::~CEnumFormatEtc() | ||
23 | { | ||
24 | if (format_etc_) | ||
25 | { | ||
26 | // first free any DVTARGETDEVICE structures | ||
27 | for (ULONG i = 0; i < formats_num_; i++) | ||
28 | { | ||
29 | if (format_etc_[i].ptd) | ||
30 | CoTaskMemFree(format_etc_[i].ptd); | ||
31 | } | ||
32 | |||
33 | // now free the main array | ||
34 | delete[] format_etc_; | ||
35 | } | ||
36 | } | ||
37 | |||
38 | // IUnknown | ||
39 | |||
40 | ULONG __stdcall CEnumFormatEtc::AddRef(void) | ||
41 | { | ||
42 | // increment object reference count | ||
43 | return InterlockedIncrement(&ref_count_); | ||
44 | } | ||
45 | |||
46 | ULONG __stdcall CEnumFormatEtc::Release(void) | ||
47 | { | ||
48 | // decrement object reference count | ||
49 | LONG count = InterlockedDecrement(&ref_count_); | ||
50 | |||
51 | if (count == 0) | ||
52 | { | ||
53 | delete this; | ||
54 | return 0; | ||
55 | } | ||
56 | else | ||
57 | { | ||
58 | return count; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | HRESULT __stdcall CEnumFormatEtc::QueryInterface(REFIID iid, void **ppvObject) | ||
63 | { | ||
64 | // check to see what interface has been requested | ||
65 | if ((iid == IID_IEnumFORMATETC) || (iid == IID_IUnknown)) | ||
66 | { | ||
67 | AddRef(); | ||
68 | *ppvObject = this; | ||
69 | return S_OK; | ||
70 | } | ||
71 | else | ||
72 | { | ||
73 | *ppvObject = 0; | ||
74 | return E_NOINTERFACE; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | // IEnumFormatEtc | ||
79 | |||
80 | HRESULT CEnumFormatEtc::Reset(void) | ||
81 | { | ||
82 | index_ = 0; | ||
83 | return S_OK; | ||
84 | } | ||
85 | |||
86 | HRESULT CEnumFormatEtc::Skip(ULONG celt) | ||
87 | { | ||
88 | index_ += celt; | ||
89 | return (index_ <= formats_num_) ? S_OK : S_FALSE; | ||
90 | } | ||
91 | |||
92 | HRESULT CEnumFormatEtc::Clone(IEnumFORMATETC **ppEnumFormatEtc) | ||
93 | { | ||
94 | HRESULT hResult; | ||
95 | |||
96 | // make a duplicate enumerator | ||
97 | hResult = CreateEnumFormatEtc(formats_num_, format_etc_, ppEnumFormatEtc); | ||
98 | |||
99 | if (hResult == S_OK) | ||
100 | { | ||
101 | // manually set the index state | ||
102 | ((CEnumFormatEtc *)*ppEnumFormatEtc)->index_ = index_; | ||
103 | } | ||
104 | |||
105 | return hResult; | ||
106 | } | ||
107 | |||
108 | HRESULT CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched) | ||
109 | { | ||
110 | ULONG copied = 0; | ||
111 | |||
112 | // validate arguments | ||
113 | if ((celt == 0) || (pFormatEtc == 0)) | ||
114 | return E_INVALIDARG; | ||
115 | |||
116 | // copy the FORMATETC structures into the caller's buffer | ||
117 | while (index_ < formats_num_ && copied < celt) | ||
118 | { | ||
119 | DeepCopyFormatEtc(&pFormatEtc[copied], &format_etc_[index_]); | ||
120 | copied++; | ||
121 | index_++; | ||
122 | } | ||
123 | |||
124 | // store result | ||
125 | if (pceltFetched != 0) | ||
126 | *pceltFetched = copied; | ||
127 | |||
128 | // did we copy all that was requested? | ||
129 | return (copied == celt) ? S_OK : S_FALSE; | ||
130 | } | ||
131 | |||
132 | // external functions | ||
133 | |||
134 | void DeepCopyFormatEtc(FORMATETC *dest, FORMATETC *source) | ||
135 | { | ||
136 | // copy the source FORMATETC into dest | ||
137 | *dest = *source; | ||
138 | |||
139 | if (source->ptd) | ||
140 | { | ||
141 | // allocate memory for the DVTARGETDEVICE if necessary | ||
142 | dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE)); | ||
143 | |||
144 | // copy the contents of the source DVTARGETDEVICE into dest->ptd | ||
145 | *(dest->ptd) = *(source->ptd); | ||
146 | } | ||
147 | } | ||
148 | |||
149 | HRESULT CreateEnumFormatEtc(UINT cfmt, FORMATETC *afmt, IEnumFORMATETC **ppEnumFormatEtc) | ||
150 | { | ||
151 | if((cfmt == 0) || (afmt == 0) || (ppEnumFormatEtc == 0)) | ||
152 | return E_INVALIDARG; | ||
153 | |||
154 | *ppEnumFormatEtc = new CEnumFormatEtc(afmt, cfmt); | ||
155 | |||
156 | return (*ppEnumFormatEtc) ? S_OK : E_OUTOFMEMORY; | ||
157 | } | ||