VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDEnumFormat_win.cpp

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.8 KB
Line 
1/* $Id: UIDnDEnumFormat_win.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIDnDEnumFormat class implementation. This class implements the
4 * IEnumFORMATETC ("Format et cetera") interface.
5 */
6
7/*
8 * Copyright (C) 2014-2024 Oracle and/or its affiliates.
9 *
10 * This file is part of VirtualBox base platform packages, as
11 * available from https://www.virtualbox.org.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation, in version 3 of the
16 * License.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <https://www.gnu.org/licenses>.
25 *
26 * SPDX-License-Identifier: GPL-3.0-only
27 */
28
29#define LOG_GROUP LOG_GROUP_GUEST_DND
30#include <VBox/log.h>
31
32#include <iprt/win/windows.h>
33#include <new> /* For bad_alloc. */
34
35#include "UIDnDEnumFormat_win.h"
36#include "UIDnDDataObject_win.h"
37
38
39UIDnDEnumFormatEtc::UIDnDEnumFormatEtc(FORMATETC *pFormatEtc, ULONG cFormats)
40 : m_lRefCount(1),
41 m_nIndex(0)
42{
43 HRESULT hr;
44
45 try
46 {
47 LogFlowFunc(("pFormatEtc=%p, cFormats=%RU32\n", pFormatEtc, cFormats));
48 if (cFormats)
49 m_pFormatEtc = new FORMATETC[cFormats];
50
51 for (ULONG i = 0; i < cFormats; i++)
52 {
53 LogFlowFunc(("Format %RU32: cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n",
54 i, pFormatEtc[i].cfFormat, UIDnDDataObject::ClipboardFormatToString(pFormatEtc[i].cfFormat),
55 pFormatEtc[i].tymed, pFormatEtc[i].dwAspect));
56 UIDnDEnumFormatEtc::CopyFormat(&m_pFormatEtc[i], &pFormatEtc[i]);
57 }
58
59 m_nNumFormats = cFormats;
60 hr = S_OK;
61 }
62 catch (std::bad_alloc &)
63 {
64 hr = E_OUTOFMEMORY;
65 }
66
67 LogFlowFunc(("hr=%Rhrc\n", hr));
68}
69
70UIDnDEnumFormatEtc::~UIDnDEnumFormatEtc(void)
71{
72 if (m_pFormatEtc)
73 {
74 for (ULONG i = 0; i < m_nNumFormats; i++)
75 {
76 if(m_pFormatEtc[i].ptd)
77 CoTaskMemFree(m_pFormatEtc[i].ptd);
78 }
79
80 delete[] m_pFormatEtc;
81 m_pFormatEtc = NULL;
82 }
83
84 LogFlowFunc(("m_lRefCount=%RI32\n", m_lRefCount));
85}
86
87/*
88 * IUnknown methods.
89 */
90
91STDMETHODIMP_(ULONG) UIDnDEnumFormatEtc::AddRef(void)
92{
93 return InterlockedIncrement(&m_lRefCount);
94}
95
96STDMETHODIMP_(ULONG) UIDnDEnumFormatEtc::Release(void)
97{
98 LONG lCount = InterlockedDecrement(&m_lRefCount);
99 if (lCount == 0)
100 {
101 delete this;
102 return 0;
103 }
104
105 return lCount;
106}
107
108STDMETHODIMP UIDnDEnumFormatEtc::QueryInterface(REFIID iid, void **ppvObject)
109{
110 if ( iid == IID_IEnumFORMATETC
111 || iid == IID_IUnknown)
112 {
113 AddRef();
114 *ppvObject = this;
115 return S_OK;
116 }
117
118 *ppvObject = 0;
119 return E_NOINTERFACE;
120}
121
122STDMETHODIMP UIDnDEnumFormatEtc::Next(ULONG cFormats, FORMATETC *pFormatEtc, ULONG *pcFetched)
123{
124 ULONG ulCopied = 0;
125
126 if(cFormats == 0 || pFormatEtc == 0)
127 return E_INVALIDARG;
128
129 while ( m_nIndex < m_nNumFormats
130 && ulCopied < cFormats)
131 {
132 UIDnDEnumFormatEtc::CopyFormat(&pFormatEtc[ulCopied],
133 &m_pFormatEtc[m_nIndex]);
134 ulCopied++;
135 m_nIndex++;
136 }
137
138 if (pcFetched)
139 *pcFetched = ulCopied;
140
141 return (ulCopied == cFormats) ? S_OK : S_FALSE;
142}
143
144STDMETHODIMP UIDnDEnumFormatEtc::Skip(ULONG cFormats)
145{
146 m_nIndex += cFormats;
147 return (m_nIndex <= m_nNumFormats) ? S_OK : S_FALSE;
148}
149
150STDMETHODIMP UIDnDEnumFormatEtc::Reset(void)
151{
152 m_nIndex = 0;
153 return S_OK;
154}
155
156STDMETHODIMP UIDnDEnumFormatEtc::Clone(IEnumFORMATETC **ppEnumFormatEtc)
157{
158 HRESULT hResult =
159 CreateEnumFormatEtc(m_nNumFormats, m_pFormatEtc, ppEnumFormatEtc);
160
161 if (hResult == S_OK)
162 ((UIDnDEnumFormatEtc *) *ppEnumFormatEtc)->m_nIndex = m_nIndex;
163
164 return hResult;
165}
166
167/* static */
168void UIDnDEnumFormatEtc::CopyFormat(FORMATETC *pDest, FORMATETC *pSource)
169{
170 AssertPtrReturnVoid(pDest);
171 AssertPtrReturnVoid(pSource);
172
173 *pDest = *pSource;
174
175 if (pSource->ptd)
176 {
177 pDest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
178 *(pDest->ptd) = *(pSource->ptd);
179 }
180}
181
182/* static */
183HRESULT UIDnDEnumFormatEtc::CreateEnumFormatEtc(UINT nNumFormats, FORMATETC *pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc)
184{
185 AssertPtrReturn(pFormatEtc, E_INVALIDARG);
186 AssertPtrReturn(ppEnumFormatEtc, E_INVALIDARG);
187
188 HRESULT hr;
189 try
190 {
191 *ppEnumFormatEtc = new UIDnDEnumFormatEtc(pFormatEtc, nNumFormats);
192 hr = S_OK;
193 }
194 catch(std::bad_alloc &)
195 {
196 hr = E_OUTOFMEMORY;
197 }
198
199 return hr;
200}
201
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