diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2021-12-27 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2022-03-18 15:35:13 +0500 |
commit | f19f813537c7aea1c20749c914e756b54a9c3cf5 (patch) | |
tree | 816ba62ca7c0fa19f2eb46d9e9d6f7dd7c3a744d /CPP/7zip/UI/FileManager/EnumFormatEtc.cpp | |
parent | 98e06a519b63b81986abe76d28887f6984a7732b (diff) | |
download | 7zip-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.cpp | 108 |
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 | |||
8 | class CEnumFormatEtc : | ||
9 | public IEnumFORMATETC, | ||
10 | public CMyUnknownImp | ||
11 | { | ||
12 | public: | ||
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 | |||
23 | private: | ||
24 | LONG m_RefCount; | ||
25 | ULONG m_NumFormats; | ||
26 | FORMATETC *m_Formats; | ||
27 | ULONG m_Index; | ||
28 | }; | ||
29 | |||
30 | static 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 | |||
40 | CEnumFormatEtc::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 | |||
54 | CEnumFormatEtc::~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 | |||
65 | STDMETHODIMP 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 | |||
81 | STDMETHODIMP CEnumFormatEtc::Skip(ULONG celt) | ||
82 | { | ||
83 | m_Index += celt; | ||
84 | return (m_Index <= m_NumFormats) ? S_OK : S_FALSE; | ||
85 | } | ||
86 | |||
87 | STDMETHODIMP CEnumFormatEtc::Reset(void) | ||
88 | { | ||
89 | m_Index = 0; | ||
90 | return S_OK; | ||
91 | } | ||
92 | |||
93 | STDMETHODIMP 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 | ||
102 | HRESULT 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 | } | ||