Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_win32 / ecore_win32_dnd_enumformatetc.cpp
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 }