Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwindowsole.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qwindowsole.h"
8\
9#include<QtGui/qevent.h>
10#include <QtGui/qwindow.h>
11#include <QtGui/qpainter.h>
12#include <QtGui/qcursor.h>
13#include <QtGui/qguiapplication.h>
14
15#include <QtCore/qmimedata.h>
16#include <QtCore/qdebug.h>
17
18#include <shlobj.h>
19
21
22/*!
23 \class QWindowsOleDataObject
24 \brief OLE data container
25
26 The following methods are NOT supported for data transfer using the
27 clipboard or drag-drop:
28 \list
29 \li IDataObject::SetData -- return E_NOTIMPL
30 \li IDataObject::DAdvise -- return OLE_E_ADVISENOTSUPPORTED
31 \li ::DUnadvise
32 \li ::EnumDAdvise
33 \li IDataObject::GetCanonicalFormatEtc -- return E_NOTIMPL
34 (NOTE: must set pformatetcOut->ptd = NULL)
35 \endlist
36
37 \internal
38*/
39
41 data(mimeData),
42 CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT))
43{
44 qCDebug(lcQpaMime) << __FUNCTION__ << mimeData->formats();
45}
46
48
50{
51 data = nullptr;
52}
53
55{
56 return data.data();
57}
58
60{
61 return performedEffect;
62}
63
65QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium) noexcept
66{
67 HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
68
69 if (data) {
71 if (auto converter = mc.converterFromMime(*pformatetc, data))
72 if (converter->convertFromMime(*pformatetc, data, pmedium))
73 hr = ResultFromScode(S_OK);
74 }
75
76 if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled())
77 qCDebug(lcQpaMime) <<__FUNCTION__ << *pformatetc << "returns" << Qt::hex << Qt::showbase << quint64(hr);
78
79 return hr;
80}
81
84{
85 return ResultFromScode(DATA_E_FORMATETC);
86}
87
89QWindowsOleDataObject::QueryGetData(LPFORMATETC pformatetc) noexcept
90{
91 HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
92
94 qCDebug(lcQpaMime) << __FUNCTION__;
95
96 if (data) {
98 hr = mc.converterFromMime(*pformatetc, data) ?
99 ResultFromScode(S_OK) : ResultFromScode(S_FALSE);
100 }
101 if (QWindowsContext::verbose > 1)
102 qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << Qt::hex << int(hr);
103 return hr;
104}
105
107QWindowsOleDataObject::GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC pformatetcOut) noexcept
108{
109 pformatetcOut->ptd = nullptr;
110 return ResultFromScode(E_NOTIMPL);
111}
112
113STDMETHODIMP
114QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL fRelease) noexcept
115{
117 qCDebug(lcQpaMime) << __FUNCTION__;
118
119 HRESULT hr = ResultFromScode(E_NOTIMPL);
120
121 if (pFormatetc->cfFormat == CF_PERFORMEDDROPEFFECT && pMedium->tymed == TYMED_HGLOBAL) {
122 auto * val = (DWORD*)GlobalLock(pMedium->hGlobal);
123 performedEffect = *val;
124 GlobalUnlock(pMedium->hGlobal);
125 if (fRelease)
126 ReleaseStgMedium(pMedium);
127 hr = ResultFromScode(S_OK);
128 }
129 if (QWindowsContext::verbose > 1)
130 qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << Qt::hex << int(hr);
131 return hr;
132}
133
134
136QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc) noexcept
137{
139 qCDebug(lcQpaMime) << __FUNCTION__ << "dwDirection=" << dwDirection;
140
141 if (!data)
142 return ResultFromScode(DATA_E_FORMATETC);
143
144 SCODE sc = S_OK;
145
146 QList<FORMATETC> fmtetcs;
147 if (dwDirection == DATADIR_GET) {
149 fmtetcs = mc.allFormatsForMime(data);
150 } else {
151 FORMATETC formatetc;
152 formatetc.cfFormat = CLIPFORMAT(CF_PERFORMEDDROPEFFECT);
153 formatetc.dwAspect = DVASPECT_CONTENT;
154 formatetc.lindex = -1;
155 formatetc.ptd = nullptr;
156 formatetc.tymed = TYMED_HGLOBAL;
157 fmtetcs.append(formatetc);
158 }
159
160 auto *enumFmtEtc = new QWindowsOleEnumFmtEtc(fmtetcs);
161 *ppenumFormatEtc = enumFmtEtc;
162 if (enumFmtEtc->isNull()) {
163 delete enumFmtEtc;
164 *ppenumFormatEtc = nullptr;
165 sc = E_OUTOFMEMORY;
166 }
167
168 return ResultFromScode(sc);
169}
170
172QWindowsOleDataObject::DAdvise(FORMATETC FAR*, DWORD,
173 LPADVISESINK, DWORD FAR*) noexcept
174{
175 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
176}
177
178
181{
182 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
183}
184
186QWindowsOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*) noexcept
187{
188 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
189}
190
191/*!
192 \class QWindowsOleEnumFmtEtc
193 \brief Enumerates the FORMATETC structures supported by QWindowsOleDataObject.
194 \internal
195*/
196
197QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QList<FORMATETC> &fmtetcs)
198{
200 qCDebug(lcQpaMime) << __FUNCTION__ << fmtetcs;
201 m_lpfmtetcs.reserve(fmtetcs.count());
202 for (int idx = 0; idx < fmtetcs.count(); ++idx) {
203 auto destetc = new FORMATETC();
204 if (copyFormatEtc(destetc, &(fmtetcs.at(idx)))) {
205 m_lpfmtetcs.append(destetc);
206 } else {
207 m_isNull = true;
208 delete destetc;
209 break;
210 }
211 }
212}
213
214QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QList<LPFORMATETC> &lpfmtetcs)
215{
217 qCDebug(lcQpaMime) << __FUNCTION__;
218 m_lpfmtetcs.reserve(lpfmtetcs.count());
219 for (int idx = 0; idx < lpfmtetcs.count(); ++idx) {
220 LPFORMATETC srcetc = lpfmtetcs.at(idx);
221 auto destetc = new FORMATETC();
222 if (copyFormatEtc(destetc, srcetc)) {
223 m_lpfmtetcs.append(destetc);
224 } else {
225 m_isNull = true;
226 delete destetc;
227 break;
228 }
229 }
230}
231
233{
234 LPMALLOC pmalloc;
235
236 if (CoGetMalloc(MEMCTX_TASK, &pmalloc) == NOERROR) {
237 for (int idx = 0; idx < m_lpfmtetcs.count(); ++idx) {
238 LPFORMATETC tmpetc = m_lpfmtetcs.at(idx);
239 if (tmpetc->ptd)
240 pmalloc->Free(tmpetc->ptd);
241 delete tmpetc;
242 }
243
244 pmalloc->Release();
245 }
246 m_lpfmtetcs.clear();
247}
248
250{
251 return m_isNull;
252}
253
254// IEnumFORMATETC methods
256QWindowsOleEnumFmtEtc::Next(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched) noexcept
257{
258 ULONG i=0;
259 ULONG nOffset;
260
261 if (rgelt == nullptr)
262 return ResultFromScode(E_INVALIDARG);
263
264 while (i < celt) {
265 nOffset = m_nIndex + i;
266
267 if (nOffset < ULONG(m_lpfmtetcs.count())) {
268 copyFormatEtc(rgelt + i, m_lpfmtetcs.at(int(nOffset)));
269 i++;
270 } else {
271 break;
272 }
273 }
274
275 m_nIndex += i;
276
277 if (pceltFetched != nullptr)
278 *pceltFetched = i;
279
280 if (i != celt)
281 return ResultFromScode(S_FALSE);
282
283 return NOERROR;
284}
285
287QWindowsOleEnumFmtEtc::Skip(ULONG celt) noexcept
288{
289 ULONG i=0;
290 ULONG nOffset;
291
292 while (i < celt) {
293 nOffset = m_nIndex + i;
294
295 if (nOffset < ULONG(m_lpfmtetcs.count())) {
296 i++;
297 } else {
298 break;
299 }
300 }
301
302 m_nIndex += i;
303
304 if (i != celt)
305 return ResultFromScode(S_FALSE);
306
307 return NOERROR;
308}
309
312{
313 m_nIndex = 0;
314 return NOERROR;
315}
316
318QWindowsOleEnumFmtEtc::Clone(LPENUMFORMATETC FAR* newEnum) noexcept
319{
320 if (newEnum == nullptr)
321 return ResultFromScode(E_INVALIDARG);
322
323 auto *result = new QWindowsOleEnumFmtEtc(m_lpfmtetcs);
324 result->m_nIndex = m_nIndex;
325
326 if (result->isNull()) {
327 delete result;
328 return ResultFromScode(E_OUTOFMEMORY);
329 }
330
331 *newEnum = result;
332 return NOERROR;
333}
334
335bool QWindowsOleEnumFmtEtc::copyFormatEtc(LPFORMATETC dest, const FORMATETC *src) const
336{
337 if (dest == nullptr || src == nullptr)
338 return false;
339
340 *dest = *src;
341
342 if (src->ptd) {
343 LPMALLOC pmalloc;
344
345 if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR)
346 return false;
347
348 pmalloc->Alloc(src->ptd->tdSize);
349 memcpy(dest->ptd, src->ptd, size_t(src->ptd->tdSize));
350
351 pmalloc->Release();
352 }
353
354 return true;
355}
356
357QT_END_NAMESPACE
\inmodule QtCore
Definition qmimedata.h:17
Singleton container for all relevant information.
QWindowsMimeRegistry & mimeConverter() const
static QWindowsContext * instance()
Manages the list of QWindowsMimeConverter instances.
OLE data container.
Definition qwindowsole.h:23
STDMETHOD GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium) noexcept override
~QWindowsOleDataObject() override
FORMATETC FAR * pFormatetc
Definition qwindowsole.h:40
STDMETHOD QueryGetData(LPFORMATETC pformatetc) noexcept override
STDMETHOD DUnadvise(DWORD dwConnection) noexcept override
QMimeData * mimeData() const
STDMETHOD EnumDAdvise(LPENUMSTATDATA FAR *ppenumAdvise) noexcept override
STDMETHOD EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR *ppenumFormatEtc) noexcept override
DWORD reportedPerformedEffect() const
STDMETHOD GetCanonicalFormatEtc(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut) noexcept override
STDMETHOD GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium) noexcept override
Enumerates the FORMATETC structures supported by QWindowsOleDataObject.
Definition qwindowsole.h:52
~QWindowsOleEnumFmtEtc() override
STDMETHOD Skip(ULONG celt) noexcept override
STDMETHOD Reset(void) noexcept override
STDMETHOD Next(ULONG celt, LPFORMATETC rgelt, ULONG FAR *pceltFetched) noexcept override
STDMETHOD Clone(LPENUMFORMATETC FAR *newEnum) noexcept override
QWindowsOleEnumFmtEtc(const QList< FORMATETC > &fmtetcs)
Combined button and popup list for selecting options.