Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
4#include "qwindowsole.h"
6#include "qwindowscontext.h"
7\
8#include <QtGui/qevent.h>
9#include <QtGui/qwindow.h>
10#include <QtGui/qpainter.h>
11#include <QtGui/qcursor.h>
12#include <QtGui/qguiapplication.h>
13
14#include <QtCore/qmimedata.h>
15#include <QtCore/qdebug.h>
16
17#include <shlobj.h>
18
20
41 CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT))
42{
43 qCDebug(lcQpaMime) << __FUNCTION__ << mimeData->formats();
44}
45
47
49{
50 data = nullptr;
51}
52
54{
55 return data.data();
56}
57
59{
60 return performedEffect;
61}
62
63STDMETHODIMP
64QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
65{
66 HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
67
68 if (data) {
69 const QWindowsMimeRegistry &mc = QWindowsContext::instance()->mimeConverter();
70 if (auto converter = mc.converterFromMime(*pformatetc, data))
71 if (converter->convertFromMime(*pformatetc, data, pmedium))
72 hr = ResultFromScode(S_OK);
73 }
74
75 if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled())
76 qCDebug(lcQpaMime) <<__FUNCTION__ << *pformatetc << "returns" << Qt::hex << Qt::showbase << quint64(hr);
77
78 return hr;
79}
80
81STDMETHODIMP
82QWindowsOleDataObject::GetDataHere(LPFORMATETC, LPSTGMEDIUM)
83{
84 return ResultFromScode(DATA_E_FORMATETC);
85}
86
87STDMETHODIMP
89{
90 HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
91
93 qCDebug(lcQpaMime) << __FUNCTION__;
94
95 if (data) {
96 const QWindowsMimeRegistry &mc = QWindowsContext::instance()->mimeConverter();
97 hr = mc.converterFromMime(*pformatetc, data) ?
98 ResultFromScode(S_OK) : ResultFromScode(S_FALSE);
99 }
101 qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << Qt::hex << int(hr);
102 return hr;
103}
104
105STDMETHODIMP
106QWindowsOleDataObject::GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC pformatetcOut)
107{
108 pformatetcOut->ptd = nullptr;
109 return ResultFromScode(E_NOTIMPL);
110}
111
112STDMETHODIMP
113QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL fRelease)
114{
116 qCDebug(lcQpaMime) << __FUNCTION__;
117
118 HRESULT hr = ResultFromScode(E_NOTIMPL);
119
120 if (pFormatetc->cfFormat == CF_PERFORMEDDROPEFFECT && pMedium->tymed == TYMED_HGLOBAL) {
121 auto * val = (DWORD*)GlobalLock(pMedium->hGlobal);
122 performedEffect = *val;
123 GlobalUnlock(pMedium->hGlobal);
124 if (fRelease)
125 ReleaseStgMedium(pMedium);
126 hr = ResultFromScode(S_OK);
127 }
129 qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << Qt::hex << int(hr);
130 return hr;
131}
132
133
134STDMETHODIMP
135QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
136{
138 qCDebug(lcQpaMime) << __FUNCTION__ << "dwDirection=" << dwDirection;
139
140 if (!data)
141 return ResultFromScode(DATA_E_FORMATETC);
142
143 SCODE sc = S_OK;
144
145 QList<FORMATETC> fmtetcs;
146 if (dwDirection == DATADIR_GET) {
147 QWindowsMimeRegistry &mc = QWindowsContext::instance()->mimeConverter();
148 fmtetcs = mc.allFormatsForMime(data);
149 } else {
150 FORMATETC formatetc;
151 formatetc.cfFormat = CLIPFORMAT(CF_PERFORMEDDROPEFFECT);
152 formatetc.dwAspect = DVASPECT_CONTENT;
153 formatetc.lindex = -1;
154 formatetc.ptd = nullptr;
155 formatetc.tymed = TYMED_HGLOBAL;
156 fmtetcs.append(formatetc);
157 }
158
159 auto *enumFmtEtc = new QWindowsOleEnumFmtEtc(fmtetcs);
160 *ppenumFormatEtc = enumFmtEtc;
161 if (enumFmtEtc->isNull()) {
162 delete enumFmtEtc;
163 *ppenumFormatEtc = nullptr;
164 sc = E_OUTOFMEMORY;
165 }
166
167 return ResultFromScode(sc);
168}
169
170STDMETHODIMP
171QWindowsOleDataObject::DAdvise(FORMATETC FAR*, DWORD,
172 LPADVISESINK, DWORD FAR*)
173{
174 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
175}
176
177
178STDMETHODIMP
180{
181 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
182}
183
184STDMETHODIMP
186{
187 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
188}
189
196QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QList<FORMATETC> &fmtetcs)
197{
199 qCDebug(lcQpaMime) << __FUNCTION__ << fmtetcs;
200 m_lpfmtetcs.reserve(fmtetcs.count());
201 for (int idx = 0; idx < fmtetcs.count(); ++idx) {
202 auto destetc = new FORMATETC();
203 if (copyFormatEtc(destetc, &(fmtetcs.at(idx)))) {
204 m_lpfmtetcs.append(destetc);
205 } else {
206 m_isNull = true;
207 delete destetc;
208 break;
209 }
210 }
211}
212
213QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QList<LPFORMATETC> &lpfmtetcs)
214{
216 qCDebug(lcQpaMime) << __FUNCTION__;
217 m_lpfmtetcs.reserve(lpfmtetcs.count());
218 for (int idx = 0; idx < lpfmtetcs.count(); ++idx) {
219 LPFORMATETC srcetc = lpfmtetcs.at(idx);
220 auto destetc = new FORMATETC();
221 if (copyFormatEtc(destetc, srcetc)) {
222 m_lpfmtetcs.append(destetc);
223 } else {
224 m_isNull = true;
225 delete destetc;
226 break;
227 }
228 }
229}
230
232{
233 LPMALLOC pmalloc;
234
235 if (CoGetMalloc(MEMCTX_TASK, &pmalloc) == NOERROR) {
236 for (int idx = 0; idx < m_lpfmtetcs.count(); ++idx) {
237 LPFORMATETC tmpetc = m_lpfmtetcs.at(idx);
238 if (tmpetc->ptd)
239 pmalloc->Free(tmpetc->ptd);
240 delete tmpetc;
241 }
242
243 pmalloc->Release();
244 }
245 m_lpfmtetcs.clear();
246}
247
249{
250 return m_isNull;
251}
252
253// IEnumFORMATETC methods
254STDMETHODIMP
255QWindowsOleEnumFmtEtc::Next(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched)
256{
257 ULONG i=0;
258 ULONG nOffset;
259
260 if (rgelt == nullptr)
261 return ResultFromScode(E_INVALIDARG);
262
263 while (i < celt) {
264 nOffset = m_nIndex + i;
265
266 if (nOffset < ULONG(m_lpfmtetcs.count())) {
267 copyFormatEtc(rgelt + i, m_lpfmtetcs.at(int(nOffset)));
268 i++;
269 } else {
270 break;
271 }
272 }
273
274 m_nIndex += i;
275
276 if (pceltFetched != nullptr)
277 *pceltFetched = i;
278
279 if (i != celt)
280 return ResultFromScode(S_FALSE);
281
282 return NOERROR;
283}
284
285STDMETHODIMP
287{
288 ULONG i=0;
289 ULONG nOffset;
290
291 while (i < celt) {
292 nOffset = m_nIndex + i;
293
294 if (nOffset < ULONG(m_lpfmtetcs.count())) {
295 i++;
296 } else {
297 break;
298 }
299 }
300
301 m_nIndex += i;
302
303 if (i != celt)
304 return ResultFromScode(S_FALSE);
305
306 return NOERROR;
307}
308
309STDMETHODIMP
311{
312 m_nIndex = 0;
313 return NOERROR;
314}
315
316STDMETHODIMP
317QWindowsOleEnumFmtEtc::Clone(LPENUMFORMATETC FAR* newEnum)
318{
319 if (newEnum == nullptr)
320 return ResultFromScode(E_INVALIDARG);
321
322 auto *result = new QWindowsOleEnumFmtEtc(m_lpfmtetcs);
323 result->m_nIndex = m_nIndex;
324
325 if (result->isNull()) {
326 delete result;
327 return ResultFromScode(E_OUTOFMEMORY);
328 }
329
330 *newEnum = result;
331 return NOERROR;
332}
333
334bool QWindowsOleEnumFmtEtc::copyFormatEtc(LPFORMATETC dest, const FORMATETC *src) const
335{
336 if (dest == nullptr || src == nullptr)
337 return false;
338
339 *dest = *src;
340
341 if (src->ptd) {
342 LPMALLOC pmalloc;
343
344 if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR)
345 return false;
346
347 pmalloc->Alloc(src->ptd->tdSize);
348 memcpy(dest->ptd, src->ptd, size_t(src->ptd->tdSize));
349
350 pmalloc->Release();
351 }
352
353 return true;
354}
355
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
qsizetype count() const noexcept
Definition qlist.h:398
void reserve(qsizetype size)
Definition qlist.h:753
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
\inmodule QtCore
Definition qmimedata.h:16
QByteArray data(const QString &mimetype) const
Returns the data stored in the object in the format described by the MIME type specified by mimeType.
virtual QStringList formats() const
Returns a list of formats supported by the object.
static QWindowsContext * instance()
Manages the list of QWindowsMimeConverter instances.
QWindowsMimeConverter * converterFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
QList< FORMATETC > allFormatsForMime(const QMimeData *mimeData) const
~QWindowsOleDataObject() override
FORMATETC FAR * pFormatetc
Definition qwindowsole.h:39
STDMETHOD SetData(LPFORMATETC pformatetc, STGMEDIUM FAR *pmedium, BOOL fRelease) override
QWindowsOleDataObject(QMimeData *mimeData)
STDMETHOD GetCanonicalFormatEtc(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut) override
STDMETHOD EnumDAdvise(LPENUMSTATDATA FAR *ppenumAdvise) override
QMimeData * mimeData() const
STDMETHOD QueryGetData(LPFORMATETC pformatetc) override
DWORD reportedPerformedEffect() const
STDMETHOD GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium) override
STDMETHOD GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium) override
STDMETHOD EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR *ppenumFormatEtc) override
STDMETHOD DUnadvise(DWORD dwConnection) override
Enumerates the FORMATETC structures supported by QWindowsOleDataObject.
Definition qwindowsole.h:51
~QWindowsOleEnumFmtEtc() override
STDMETHOD Reset(void) override
QWindowsOleEnumFmtEtc(const QList< FORMATETC > &fmtetcs)
STDMETHOD Next(ULONG celt, LPFORMATETC rgelt, ULONG FAR *pceltFetched) override
STDMETHOD Clone(LPENUMFORMATETC FAR *newEnum) override
STDMETHOD Skip(ULONG celt) override
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
QTextStream & showbase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::ShowBase) on stream and r...
#define qCDebug(category,...)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum src
GLuint GLfloat * val
GLuint64EXT * result
[6]
unsigned long long quint64
Definition qtypes.h:61
long HRESULT
tagSTGMEDIUM STGMEDIUM
tagFORMATETC FORMATETC
QMimeData * mimeData