VirtualBox

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

Last change on this file since 95961 was 95961, checked in by vboxsync, 22 months ago

Additions/VBoxTray: Got rid of VBoxDisplay.h (renamed to VBoxTrayInternal.h, more stuff added later), as I also tripped over this several times in the past already, log include fixes.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use