1 // EnumFormatEtc.cpp
2
3 #include "StdAfx.h"
4
5 #include "EnumFormatEtc.h"
6 #include "../../IDecl.h"
7 #include "MyCom2.h"
8
9 class CEnumFormatEtc Z7_final:
10 public IEnumFORMATETC,
11 public CMyUnknownImp
12 {
13 Z7_COM_UNKNOWN_IMP_1_MT(IEnumFORMATETC)
14
15 STDMETHOD(Next)(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) Z7_override;
16 STDMETHOD(Skip)(ULONG celt) Z7_override;
17 STDMETHOD(Reset)(void) Z7_override;
18 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc) Z7_override;
19
20 LONG m_RefCount;
21 ULONG m_NumFormats;
22 FORMATETC *m_Formats;
23 ULONG m_Index;
24 public:
25 CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats);
26 ~CEnumFormatEtc();
27 };
28
DeepCopyFormatEtc(FORMATETC * dest,const FORMATETC * src)29 static void DeepCopyFormatEtc(FORMATETC *dest, const FORMATETC *src)
30 {
31 *dest = *src;
32 if (src->ptd)
33 {
34 dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
35 *(dest->ptd) = *(src->ptd);
36 }
37 }
38
CEnumFormatEtc(const FORMATETC * pFormatEtc,ULONG numFormats)39 CEnumFormatEtc::CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats)
40 {
41 m_RefCount = 1;
42 m_Index = 0;
43 m_NumFormats = 0;
44 m_Formats = new FORMATETC[numFormats];
45 // if (m_Formats)
46 {
47 m_NumFormats = numFormats;
48 for (ULONG i = 0; i < numFormats; i++)
49 DeepCopyFormatEtc(&m_Formats[i], &pFormatEtc[i]);
50 }
51 }
52
~CEnumFormatEtc()53 CEnumFormatEtc::~CEnumFormatEtc()
54 {
55 if (m_Formats)
56 {
57 for (ULONG i = 0; i < m_NumFormats; i++)
58 if (m_Formats[i].ptd)
59 CoTaskMemFree(m_Formats[i].ptd);
60 delete []m_Formats;
61 }
62 }
63
Next(ULONG celt,FORMATETC * pFormatEtc,ULONG * pceltFetched)64 Z7_COMWF_B CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched)
65 {
66 ULONG copied = 0;
67 if (celt == 0 || !pFormatEtc)
68 return E_INVALIDARG;
69 while (m_Index < m_NumFormats && copied < celt)
70 {
71 DeepCopyFormatEtc(&pFormatEtc[copied], &m_Formats[m_Index]);
72 copied++;
73 m_Index++;
74 }
75 if (pceltFetched)
76 *pceltFetched = copied;
77 return (copied == celt) ? S_OK : S_FALSE;
78 }
79
Skip(ULONG celt)80 Z7_COMWF_B CEnumFormatEtc::Skip(ULONG celt)
81 {
82 m_Index += celt;
83 return (m_Index <= m_NumFormats) ? S_OK : S_FALSE;
84 }
85
Reset(void)86 Z7_COMWF_B CEnumFormatEtc::Reset(void)
87 {
88 m_Index = 0;
89 return S_OK;
90 }
91
Clone(IEnumFORMATETC ** ppEnumFormatEtc)92 Z7_COMWF_B CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc)
93 {
94 HRESULT hResult = CreateEnumFormatEtc(m_NumFormats, m_Formats, ppEnumFormatEtc);
95 if (hResult == S_OK)
96 ((CEnumFormatEtc *)*ppEnumFormatEtc)->m_Index = m_Index;
97 return hResult;
98 }
99
100 // replacement for SHCreateStdEnumFmtEtc
CreateEnumFormatEtc(UINT numFormats,const FORMATETC * formats,IEnumFORMATETC ** enumFormat)101 HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat)
102 {
103 if (numFormats == 0 || !formats || !enumFormat)
104 return E_INVALIDARG;
105 *enumFormat = new CEnumFormatEtc(formats, numFormats);
106 return (*enumFormat) ? S_OK : E_OUTOFMEMORY;
107 }
108