8#include <QtGui/qguiapplication.h>
9#include <QtGui/qclipboard.h>
10#include <QtGui/qcolor.h>
11#include <QtGui/qimage.h>
13#include <QtCore/qdebug.h>
14#include <QtCore/qmimedata.h>
15#include <QtCore/qstringlist.h>
16#include <QtCore/qthread.h>
17#include <QtCore/qvariant.h>
18#include <QtCore/qurl.h>
19#include <QtCore/private/qsystemerror_p.h>
21#include <QtGui/private/qwindowsguieventdispatcher_p.h>
40#ifndef QT_NO_DEBUG_STREAM
48 d <<
"formats=" <<
formats.join(u
", ");
80 enum :
int { attempts = 3 };
81 IDataObject * pDataObj =
nullptr;
83 for (
int i = 1;
i <= attempts; ++
i) {
84 if (SUCCEEDED(OleGetClipboard(&pDataObj))) {
86 qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj;
90 ?
"Unable to obtain clipboard."
91 :
"Retrying to obtain clipboard.");
100 dataObject->Release();
109 return DefWindowProc(hwnd,
message, wParam, lParam);
126 QWindowsClipboard::m_instance =
this;
133 QWindowsClipboard::m_instance =
nullptr;
142void QWindowsClipboard::releaseIData()
158 m_formatListenerRegistered = AddClipboardFormatListener(m_clipboardViewer);
159 if (!m_formatListenerRegistered)
162 if (!m_formatListenerRegistered)
163 m_nextClipboardViewer = SetClipboardViewer(m_clipboardViewer);
165 qCDebug(lcQpaMime) << __FUNCTION__ <<
"m_clipboardViewer:" << m_clipboardViewer
166 <<
"format listener:" << m_formatListenerRegistered
167 <<
"next:" << m_nextClipboardViewer;
170void QWindowsClipboard::unregisterViewer()
172 if (m_clipboardViewer) {
173 if (m_formatListenerRegistered) {
174 RemoveClipboardFormatListener(m_clipboardViewer);
175 m_formatListenerRegistered =
false;
177 ChangeClipboardChain(m_clipboardViewer, m_nextClipboardViewer);
178 m_nextClipboardViewer =
nullptr;
180 DestroyWindow(m_clipboardViewer);
181 m_clipboardViewer =
nullptr;
191 if (!GetWindowThreadProcessId(hwnd, &pid) || !pid)
193 const HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
196 BOOL debugged = FALSE;
197 CheckRemoteDebuggerPresent(processHandle, &debugged);
198 CloseHandle(processHandle);
199 return debugged != FALSE;
202void QWindowsClipboard::propagateClipboardMessage(UINT
message, WPARAM wParam, LPARAM lParam)
const
204 if (!m_nextClipboardViewer)
208 if (IsHungAppWindow(m_nextClipboardViewer)) {
209 qWarning(
"Cowardly refusing to send clipboard message to hung application...");
215 PostMessage(m_nextClipboardViewer,
message, wParam, lParam);
217 SendMessage(m_nextClipboardViewer,
message, wParam, lParam);
227 enum { wMClipboardUpdate = 0x031D };
234 case WM_CHANGECBCHAIN: {
235 const HWND toBeRemoved =
reinterpret_cast<HWND
>(wParam);
236 if (toBeRemoved == m_nextClipboardViewer) {
237 m_nextClipboardViewer =
reinterpret_cast<HWND
>(lParam);
239 propagateClipboardMessage(
message, wParam, lParam);
243 case wMClipboardUpdate:
244 case WM_DRAWCLIPBOARD: {
245 const bool owned = ownsClipboard();
246 qCDebug(lcQpaMime) <<
"Clipboard changed owned " << owned;
249 if (!owned && m_data)
251 if (!m_formatListenerRegistered)
252 propagateClipboardMessage(
message, wParam, lParam);
257 if (ownsClipboard()) {
258 qCDebug(lcQpaMime) <<
"Clipboard owner on shutdown, releasing.";
274 return &m_retrievalData;
292 for (; attempts < 3; ++attempts) {
293 src = OleSetClipboard(m_data);
302 qErrnoWarning(
"OleSetClipboard: Failed to set mime data (%s) on clipboard: %s",
310void QWindowsClipboard::clear()
314 qErrnoWarning(
"OleSetClipboard: Failed to clear the clipboard: 0x%lx",
src);
323bool QWindowsClipboard::ownsClipboard()
const
325 return m_data && OleIsCurrentClipboard(m_data) == S_OK;
331 ownsClipboard() :
false;
Mode
\keyword clipboard mode
bool hasUrls() const
Returns true if the object can return a list of urls; otherwise returns false.
QVariant colorData() const
Returns a color if the data stored in the object represents a color (MIME type application/x-color); ...
QVariant imageData() const
Returns a QVariant storing a QImage if the object can return an image; otherwise returns a null varia...
bool hasHtml() const
Returns true if the object can return HTML (MIME type text/html); otherwise returns false.
bool hasImage() const
Returns true if the object can return an image; otherwise returns false.
bool hasText() const
Returns true if the object can return plain text (MIME type text/plain); otherwise returns false.
QString html() const
Returns a string if the data stored in the object is HTML (MIME type text/html); otherwise returns an...
QList< QUrl > urls() const
Returns a list of URLs contained within the MIME data object.
bool hasColor() const
Returns true if the object can return a color (MIME type application/x-color); otherwise returns fals...
virtual QStringList formats() const
Returns a list of formats supported by the object.
QString text() const
Returns a plain text (MIME type text/plain) representation of the data.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static void msleep(unsigned long)
void releaseDataObject(IDataObject *) const override
IDataObject * retrieveDataObject() const override
Clipboard implementation.
void setMimeData(QMimeData *data, QClipboard::Mode mode=QClipboard::Clipboard) override
bool supportsMode(QClipboard::Mode mode) const override
QMimeData * mimeData(QClipboard::Mode mode=QClipboard::Clipboard) override
~QWindowsClipboard() override
bool ownsMode(QClipboard::Mode mode) const override
static QWindowsClipboard * instance()
bool clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
Windows procedure of the clipboard viewer.
ULONG STDMETHODCALLTYPE Release() override
static bool isSessionLocked()
static QWindowsContext * instance()
static const char * windowsMessageName(UINT msg)
QMimeData * mimeData() const
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
void qAddPostRoutine(QtCleanUpFunction p)
static Window createDummyWindow(Display *dpy, XVisualInfo *visualInfo, int screenNumber, Window rootWin)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLuint GLsizei const GLchar * message
#define qPrintable(string)
#define QStringLiteral(str)
LRESULT QT_WIN_CALLBACK qClipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
static bool isProcessBeingDebugged(HWND hwnd)
static void cleanClipboardPostRoutine()
static QDebug operator<<(QDebug d, const QMimeData *mimeData)