aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2021-12-27 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2022-03-18 15:35:13 +0500
commitf19f813537c7aea1c20749c914e756b54a9c3cf5 (patch)
tree816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /CPP/7zip/UI/FileManager/EnumFormatEtc.cpp
parent98e06a519b63b81986abe76d28887f6984a7732b (diff)
download7zip-21.07.tar.gz
7zip-21.07.tar.bz2
7zip-21.07.zip
'21.07'21.07
Diffstat (limited to 'CPP/7zip/UI/FileManager/EnumFormatEtc.cpp')
-rw-r--r--CPP/7zip/UI/FileManager/EnumFormatEtc.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp b/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp
new file mode 100644
index 0000000..389aa3e
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp
@@ -0,0 +1,108 @@
1// EnumFormatEtc.cpp
2
3#include "StdAfx.h"
4
5#include "EnumFormatEtc.h"
6#include "MyCom2.h"
7
8class CEnumFormatEtc :
9public IEnumFORMATETC,
10public CMyUnknownImp
11{
12public:
13 MY_UNKNOWN_IMP1_MT(IEnumFORMATETC)
14
15 STDMETHOD(Next)(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched);
16 STDMETHOD(Skip)(ULONG celt);
17 STDMETHOD(Reset)(void);
18 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
19
20 CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats);
21 ~CEnumFormatEtc();
22
23private:
24 LONG m_RefCount;
25 ULONG m_NumFormats;
26 FORMATETC *m_Formats;
27 ULONG m_Index;
28};
29
30static void DeepCopyFormatEtc(FORMATETC *dest, const FORMATETC *src)
31{
32 *dest = *src;
33 if (src->ptd)
34 {
35 dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
36 *(dest->ptd) = *(src->ptd);
37 }
38}
39
40CEnumFormatEtc::CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats)
41{
42 m_RefCount = 1;
43 m_Index = 0;
44 m_NumFormats = 0;
45 m_Formats = new FORMATETC[numFormats];
46 // if (m_Formats)
47 {
48 m_NumFormats = numFormats;
49 for (ULONG i = 0; i < numFormats; i++)
50 DeepCopyFormatEtc(&m_Formats[i], &pFormatEtc[i]);
51 }
52}
53
54CEnumFormatEtc::~CEnumFormatEtc()
55{
56 if (m_Formats)
57 {
58 for (ULONG i = 0; i < m_NumFormats; i++)
59 if (m_Formats[i].ptd)
60 CoTaskMemFree(m_Formats[i].ptd);
61 delete []m_Formats;
62 }
63}
64
65STDMETHODIMP CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched)
66{
67 ULONG copied = 0;
68 if (celt == 0 || pFormatEtc == 0)
69 return E_INVALIDARG;
70 while (m_Index < m_NumFormats && copied < celt)
71 {
72 DeepCopyFormatEtc(&pFormatEtc[copied], &m_Formats[m_Index]);
73 copied++;
74 m_Index++;
75 }
76 if (pceltFetched != 0)
77 *pceltFetched = copied;
78 return (copied == celt) ? S_OK : S_FALSE;
79}
80
81STDMETHODIMP CEnumFormatEtc::Skip(ULONG celt)
82{
83 m_Index += celt;
84 return (m_Index <= m_NumFormats) ? S_OK : S_FALSE;
85}
86
87STDMETHODIMP CEnumFormatEtc::Reset(void)
88{
89 m_Index = 0;
90 return S_OK;
91}
92
93STDMETHODIMP CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc)
94{
95 HRESULT hResult = CreateEnumFormatEtc(m_NumFormats, m_Formats, ppEnumFormatEtc);
96 if (hResult == S_OK)
97 ((CEnumFormatEtc *)*ppEnumFormatEtc)->m_Index = m_Index;
98 return hResult;
99}
100
101// replacement for SHCreateStdEnumFmtEtc
102HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat)
103{
104 if (numFormats == 0 || formats == 0 || enumFormat == 0)
105 return E_INVALIDARG;
106 *enumFormat = new CEnumFormatEtc(formats, numFormats);
107 return (*enumFormat) ? S_OK : E_OUTOFMEMORY;
108}