VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDEnumFormat.cpp@ 95960

Last change on this file since 95960 was 95960, checked in by vboxsync, 3 years ago

Additions/VBoxTray: More logging cleanups: don't define default stuff which is already defined by default; include files reordering (IPRT/ first, VBox/ second).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1/* $Id: VBoxDnDEnumFormat.cpp 95960 2022-08-01 13:54:40Z vboxsync $ */
2/** @file
3 * VBoxDnDEnumFormat.cpp - IEnumFORMATETC ("Format et cetera") implementation.
4 */
5
6/*
7 * Copyright (C) 2013-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <iprt/win/windows.h>
23#include <new> /* For bad_alloc. */
24
25#include "VBoxTray.h"
26#include "VBoxHelpers.h"
27#include "VBoxDnD.h"
28
29
30VBoxDnDEnumFormatEtc::VBoxDnDEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal)
31 : m_cRefs(1)
32 , m_uIdxCur(0)
33 , m_cFormats(0)
34 , m_paFormatEtc(NULL)
35
36{
37 int rc2 = Init(pFormatEtc, uIdx, cToCopy, cTotal);
38 AssertRC(rc2);
39}
40
41VBoxDnDEnumFormatEtc::~VBoxDnDEnumFormatEtc(void)
42{
43 if (m_paFormatEtc)
44 {
45 for (ULONG i = 0; i < m_cFormats; i++)
46 if (m_paFormatEtc[i].ptd)
47 {
48 CoTaskMemFree(m_paFormatEtc[i].ptd);
49 m_paFormatEtc[i].ptd = NULL;
50 }
51
52 RTMemFree(m_paFormatEtc);
53 m_paFormatEtc = NULL;
54 }
55
56 LogFlowFunc(("m_lRefCount=%RI32\n", m_cRefs));
57}
58
59/**
60 * Initializes the class by copying the required formats.
61 *
62 * @returns VBox status code.
63 * @param pFormatEtc Format Etc to use for initialization.
64 * @param uIdx Index (zero-based) of format
65 * @param cToCopy Number of formats \a pFormatEtc to copy, starting from \a uIdx.
66 * @param cTotal Number of total formats \a pFormatEtc holds.
67 */
68int VBoxDnDEnumFormatEtc::Init(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal)
69{
70 AssertPtrReturn(pFormatEtc, VERR_INVALID_POINTER);
71 AssertReturn(uIdx <= cTotal, VERR_INVALID_PARAMETER);
72 AssertReturn(uIdx + cToCopy <= cTotal, VERR_INVALID_PARAMETER);
73 /* cFormats can be 0. */
74
75 if (!cToCopy)
76 return VINF_SUCCESS;
77
78 AssertReturn(m_paFormatEtc == NULL && m_cFormats == 0, VERR_WRONG_ORDER);
79
80 int rc = VINF_SUCCESS;
81
82 m_paFormatEtc = (LPFORMATETC)RTMemAllocZ(sizeof(FORMATETC) * cToCopy);
83 if (m_paFormatEtc)
84 {
85 for (ULONG i = 0; i < cToCopy; i++)
86 {
87 LPFORMATETC const pFormatCur = &pFormatEtc[uIdx + i];
88
89 LogFlowFunc(("Format %RU32 (index %RU32): cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n",
90 i, uIdx + i, pFormatCur->cfFormat, VBoxDnDDataObject::ClipboardFormatToString(pFormatCur->cfFormat),
91 pFormatCur->tymed, pFormatCur->dwAspect));
92 VBoxDnDEnumFormatEtc::CopyFormat(&m_paFormatEtc[i], pFormatCur);
93 }
94
95 m_cFormats = cToCopy;
96 }
97 else
98 rc = VERR_NO_MEMORY;
99 return rc;
100}
101
102/*
103 * IUnknown methods.
104 */
105
106STDMETHODIMP_(ULONG) VBoxDnDEnumFormatEtc::AddRef(void)
107{
108 return InterlockedIncrement(&m_cRefs);
109}
110
111STDMETHODIMP_(ULONG) VBoxDnDEnumFormatEtc::Release(void)
112{
113 LONG lCount = InterlockedDecrement(&m_cRefs);
114 if (lCount == 0)
115 {
116 delete this;
117 return 0;
118 }
119
120 return lCount;
121}
122
123STDMETHODIMP VBoxDnDEnumFormatEtc::QueryInterface(REFIID iid, void **ppvObject)
124{
125 if ( iid == IID_IEnumFORMATETC
126 || iid == IID_IUnknown)
127 {
128 AddRef();
129 *ppvObject = this;
130 return S_OK;
131 }
132
133 *ppvObject = 0;
134 return E_NOINTERFACE;
135}
136
137STDMETHODIMP VBoxDnDEnumFormatEtc::Next(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched)
138{
139 ULONG ulCopied = 0;
140
141 if(cFormats == 0 || pFormatEtc == 0)
142 return E_INVALIDARG;
143
144 while ( m_uIdxCur < m_cFormats
145 && ulCopied < cFormats)
146 {
147 VBoxDnDEnumFormatEtc::CopyFormat(&pFormatEtc[ulCopied],
148 &m_paFormatEtc[m_uIdxCur]);
149 ulCopied++;
150 m_uIdxCur++;
151 }
152
153 if (pcFetched)
154 *pcFetched = ulCopied;
155
156 return (ulCopied == cFormats) ? S_OK : S_FALSE;
157}
158
159STDMETHODIMP VBoxDnDEnumFormatEtc::Skip(ULONG cFormats)
160{
161 m_uIdxCur += cFormats;
162 return (m_uIdxCur <= m_cFormats) ? S_OK : S_FALSE;
163}
164
165STDMETHODIMP VBoxDnDEnumFormatEtc::Reset(void)
166{
167 m_uIdxCur = 0;
168 return S_OK;
169}
170
171STDMETHODIMP VBoxDnDEnumFormatEtc::Clone(IEnumFORMATETC **ppEnumFormatEtc)
172{
173 HRESULT hrc = CreateEnumFormatEtc(m_cFormats, m_paFormatEtc, ppEnumFormatEtc);
174
175 if (hrc == S_OK)
176 ((VBoxDnDEnumFormatEtc *) *ppEnumFormatEtc)->m_uIdxCur = m_uIdxCur;
177
178 return hrc;
179}
180
181/**
182 * Copies a format etc from \a pSource to \a aDest (deep copy).
183 *
184 * @returns VBox status code.
185 * @param pDest Where to copy \a pSource to.
186 * @param pSource Source to copy.
187 */
188/* static */
189int VBoxDnDEnumFormatEtc::CopyFormat(LPFORMATETC pDest, LPFORMATETC pSource)
190{
191 AssertPtrReturn(pDest , VERR_INVALID_POINTER);
192 AssertPtrReturn(pSource, VERR_INVALID_POINTER);
193
194 *pDest = *pSource;
195
196 if (pSource->ptd)
197 {
198 pDest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
199 AssertPtrReturn(pDest->ptd, VERR_NO_MEMORY);
200 *(pDest->ptd) = *(pSource->ptd);
201 }
202
203 return VINF_SUCCESS;
204}
205
206/**
207 * Creates an IEnumFormatEtc interface from a given format etc structure.
208 *
209 * @returns HRESULT
210 * @param nNumFormats Number of formats to copy from \a pFormatEtc.
211 * @param pFormatEtc Format etc to use for creation.
212 * @param ppEnumFormatEtc Where to return the created IEnumFormatEtc interface on success.
213 */
214/* static */
215HRESULT VBoxDnDEnumFormatEtc::CreateEnumFormatEtc(UINT nNumFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc)
216{
217 /* cNumFormats can be 0. */
218 AssertPtrReturn(pFormatEtc, E_INVALIDARG);
219 AssertPtrReturn(ppEnumFormatEtc, E_INVALIDARG);
220
221#ifdef RT_EXCEPTIONS_ENABLED
222 try { *ppEnumFormatEtc = new VBoxDnDEnumFormatEtc(pFormatEtc,
223 0 /* uIdx */, nNumFormats /* cToCopy */, nNumFormats /* cTotal */); }
224 catch (std::bad_alloc &)
225#else
226 *ppEnumFormatEtc = new VBoxDnDEnumFormatEtc(pFormatEtc,
227 0 /* uIdx */, nNumFormats /* cToCopy */, nNumFormats /* cTotal */);
228 if (!*ppEnumFormatEtc)
229#endif
230 {
231 return E_OUTOFMEMORY;
232 }
233
234 return S_OK;
235}
236
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette