1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
4 ** Copyright (C) 2016 The Qt Company Ltd.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 #include "qcoreapplication.h"
42 #include "qcoreapplication_p.h"
43 #include "qstringlist.h"
44 #include "qvector.h"
45 #include "qfileinfo.h"
46 #include "qcorecmdlineargs_p.h"
47 #ifndef QT_NO_QOBJECT
48 #include "qmutex.h"
49 #include <private/qthread_p.h>
50 #include <private/qlocking_p.h>
51 #endif
52 #include "qtextstream.h"
53 #include <ctype.h>
54 #include <qt_windows.h>
55
56 #ifdef Q_OS_WINRT
57 #include <qfunctions_winrt.h>
58 #include <wrl.h>
59 #include <Windows.ApplicationModel.core.h>
60 #include <windows.foundation.h>
61 using namespace ABI::Windows::ApplicationModel;
62 using namespace Microsoft::WRL;
63 using namespace Microsoft::WRL::Wrappers;
64 #endif
65
66 QT_BEGIN_NAMESPACE
67
qAppFileName()68 Q_CORE_EXPORT QString qAppFileName() // get application file name
69 {
70 /*
71 GetModuleFileName() returns the length of the module name, when it has
72 space to store it and 0-terminate; this return is necessarily smaller than
73 the buffer size, as it doesn't include the terminator. When it lacks
74 space, the function returns the full size of the buffer and fills the
75 buffer, truncating the full path to make it fit. We have reports that
76 GetModuleFileName sometimes doesn't set the error number to
77 ERROR_INSUFFICIENT_BUFFER, as claimed by the MSDN documentation; so we
78 only trust the answer when the return is actually less than the buffer
79 size we pass in. (When truncating, except on XP, it does so by enough to
80 still have space to 0-terminate; in either case, it fills the claimed
81 space and returns the size of the space. While XP might thus give us the
82 full name, without a 0 terminator, and return its actual length, we can
83 never be sure that's what's happened until a later call with bigger buffer
84 confirms it by returning less than its buffer size.)
85 */
86 // Full path may be longer than MAX_PATH - expand until we have enough space:
87 QVarLengthArray<wchar_t, MAX_PATH + 1> space;
88 DWORD v;
89 size_t size = 1;
90 do {
91 size += MAX_PATH;
92 space.resize(int(size));
93 v = GetModuleFileName(NULL, space.data(), DWORD(space.size()));
94 } while (Q_UNLIKELY(v >= size));
95
96 return QString::fromWCharArray(space.data(), v);
97 }
98
appName() const99 QString QCoreApplicationPrivate::appName() const
100 {
101 return QFileInfo(qAppFileName()).baseName();
102 }
103
appVersion() const104 QString QCoreApplicationPrivate::appVersion() const
105 {
106 QString applicationVersion;
107 #ifndef QT_BOOTSTRAPPED
108 # ifdef Q_OS_WINRT
109 HRESULT hr;
110
111 ComPtr<IPackageStatics> packageFactory;
112 hr = RoGetActivationFactory(
113 HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Package).Get(),
114 IID_PPV_ARGS(&packageFactory));
115 RETURN_IF_FAILED("Failed to create package instance", return QString());
116
117 ComPtr<IPackage> package;
118 packageFactory->get_Current(&package);
119 RETURN_IF_FAILED("Failed to get current application package", return QString());
120
121 ComPtr<IPackageId> packageId;
122 package->get_Id(&packageId);
123 RETURN_IF_FAILED("Failed to get current application package ID", return QString());
124
125 PackageVersion version;
126 packageId->get_Version(&version);
127 RETURN_IF_FAILED("Failed to get current application package version", return QString());
128
129 applicationVersion = QStringLiteral("%1.%2.%3.%4")
130 .arg(version.Major)
131 .arg(version.Minor)
132 .arg(version.Build)
133 .arg(version.Revision);
134 # else
135 const QString appFileName = qAppFileName();
136 QVarLengthArray<wchar_t> buffer(appFileName.size() + 1);
137 buffer[appFileName.toWCharArray(buffer.data())] = 0;
138
139 DWORD versionInfoSize = GetFileVersionInfoSize(buffer.data(), nullptr);
140 if (versionInfoSize) {
141 QVarLengthArray<BYTE> info(static_cast<int>(versionInfoSize));
142 if (GetFileVersionInfo(buffer.data(), 0, versionInfoSize, info.data())) {
143 UINT size;
144 DWORD *fi;
145
146 if (VerQueryValue(info.data(), __TEXT("\\"),
147 reinterpret_cast<void **>(&fi), &size) && size) {
148 const VS_FIXEDFILEINFO *verInfo = reinterpret_cast<const VS_FIXEDFILEINFO *>(fi);
149 applicationVersion = QStringLiteral("%1.%2.%3.%4")
150 .arg(HIWORD(verInfo->dwProductVersionMS))
151 .arg(LOWORD(verInfo->dwProductVersionMS))
152 .arg(HIWORD(verInfo->dwProductVersionLS))
153 .arg(LOWORD(verInfo->dwProductVersionLS));
154 }
155 }
156 }
157 # endif
158 #endif
159 return applicationVersion;
160 }
161
162 #ifndef Q_OS_WINRT
163
164 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
qWinAppInst()165 Q_CORE_EXPORT HINSTANCE qWinAppInst() // get Windows app handle
166 {
167 return GetModuleHandle(0);
168 }
169
qWinAppPrevInst()170 Q_CORE_EXPORT HINSTANCE qWinAppPrevInst() // get Windows prev app handle
171 {
172 return 0;
173 }
174
qWinAppCmdShow()175 Q_CORE_EXPORT int qWinAppCmdShow() // get main window show command
176 {
177 STARTUPINFO startupInfo;
178 GetStartupInfo(&startupInfo);
179
180 return (startupInfo.dwFlags & STARTF_USESHOWWINDOW)
181 ? startupInfo.wShowWindow
182 : SW_SHOWDEFAULT;
183 }
184 #endif
185
186 #ifndef QT_NO_QOBJECT
187
188 #if defined(Q_OS_WIN) && !defined(QT_NO_DEBUG_STREAM)
189 /*****************************************************************************
190 Convenience functions for convert WM_* messages into human readable strings,
191 including a nifty QDebug operator<< for simple QDebug() << msg output.
192 *****************************************************************************/
193 QT_BEGIN_INCLUDE_NAMESPACE
194 #include <windowsx.h>
195 #include "qdebug.h"
196 QT_END_INCLUDE_NAMESPACE
197
198 #if !defined(GET_X_LPARAM)
199 # define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
200 # define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
201 #endif
202
203 // The values below should never change. Note that none of the usual
204 // WM_...FIRST & WM_...LAST values are in the list, as they normally have other
205 // WM_... representations
206
207 template <class IntType>
208 struct QWinMessageMapping {
209 IntType value;
210 const char *name;
211 };
212
213 #define FLAG_ENTRY(x) {x, #x} // for populating arrays
214
215 // Looks up a value in a list of QWinMessageMapping
216 template <class IntType>
findWinMessageMapping(const QWinMessageMapping<IntType> * haystack,size_t haystackSize,IntType needle)217 static const char *findWinMessageMapping(const QWinMessageMapping<IntType> *haystack,
218 size_t haystackSize,
219 IntType needle)
220 {
221 for (auto p = haystack, end = haystack + haystackSize; p < end; ++p) {
222 if (p->value == needle)
223 return p->name;
224 }
225 return nullptr;
226 }
227
228 // Format flags using a mapping as "Flag1 | Flag2"...
229 template <class IntType>
flagsValue(const QWinMessageMapping<IntType> * haystack,size_t haystackSize,IntType value)230 static QString flagsValue(const QWinMessageMapping<IntType> *haystack,
231 size_t haystackSize, IntType value)
232 {
233 QString result;
234 for (auto p = haystack, end = haystack + haystackSize; p < end; ++p) {
235 if ((p->value & value) == p->value) {
236 if (!result.isEmpty())
237 result += QLatin1String(" | ");
238 result += QLatin1String(p->name);
239 }
240 }
241 return result;
242 }
243
244 // Looks up the WM_ message in the table inside
findWMstr(uint msg)245 static const char *findWMstr(uint msg)
246 {
247 static const QWinMessageMapping<uint> knownWM[] =
248 {{ 0x0000, "WM_NULL" },
249 { 0x0001, "WM_CREATE" },
250 { 0x0002, "WM_DESTROY" },
251 { 0x0003, "WM_MOVE" },
252 { 0x0005, "WM_SIZE" },
253 { 0x0006, "WM_ACTIVATE" },
254 { 0x0007, "WM_SETFOCUS" },
255 { 0x0008, "WM_KILLFOCUS" },
256 { 0x000A, "WM_ENABLE" },
257 { 0x000B, "WM_SETREDRAW" },
258 { 0x000C, "WM_SETTEXT" },
259 { 0x000D, "WM_GETTEXT" },
260 { 0x000E, "WM_GETTEXTLENGTH" },
261 { 0x000F, "WM_PAINT" },
262 { 0x0010, "WM_CLOSE" },
263 { 0x0011, "WM_QUERYENDSESSION" },
264 { 0x0013, "WM_QUERYOPEN" },
265 { 0x0016, "WM_ENDSESSION" },
266 { 0x0012, "WM_QUIT" },
267 { 0x0014, "WM_ERASEBKGND" },
268 { 0x0015, "WM_SYSCOLORCHANGE" },
269 { 0x0018, "WM_SHOWWINDOW" },
270 { 0x001A, "WM_WININICHANGE" },
271 { 0x001B, "WM_DEVMODECHANGE" },
272 { 0x001C, "WM_ACTIVATEAPP" },
273 { 0x001D, "WM_FONTCHANGE" },
274 { 0x001E, "WM_TIMECHANGE" },
275 { 0x001F, "WM_CANCELMODE" },
276 { 0x0020, "WM_SETCURSOR" },
277 { 0x0021, "WM_MOUSEACTIVATE" },
278 { 0x0022, "WM_CHILDACTIVATE" },
279 { 0x0023, "WM_QUEUESYNC" },
280 { 0x0024, "WM_GETMINMAXINFO" },
281 { 0x0026, "WM_PAINTICON" },
282 { 0x0027, "WM_ICONERASEBKGND" },
283 { 0x0028, "WM_NEXTDLGCTL" },
284 { 0x002A, "WM_SPOOLERSTATUS" },
285 { 0x002B, "WM_DRAWITEM" },
286 { 0x002C, "WM_MEASUREITEM" },
287 { 0x002D, "WM_DELETEITEM" },
288 { 0x002E, "WM_VKEYTOITEM" },
289 { 0x002F, "WM_CHARTOITEM" },
290 { 0x0030, "WM_SETFONT" },
291 { 0x0031, "WM_GETFONT" },
292 { 0x0032, "WM_SETHOTKEY" },
293 { 0x0033, "WM_GETHOTKEY" },
294 { 0x0037, "WM_QUERYDRAGICON" },
295 { 0x0039, "WM_COMPAREITEM" },
296 { 0x003D, "WM_GETOBJECT" },
297 { 0x0041, "WM_COMPACTING" },
298 { 0x0044, "WM_COMMNOTIFY" },
299 { 0x0046, "WM_WINDOWPOSCHANGING" },
300 { 0x0047, "WM_WINDOWPOSCHANGED" },
301 { 0x0048, "WM_POWER" },
302 { 0x004A, "WM_COPYDATA" },
303 { 0x004B, "WM_CANCELJOURNAL" },
304 { 0x004E, "WM_NOTIFY" },
305 { 0x0050, "WM_INPUTLANGCHANGEREQUEST" },
306 { 0x0051, "WM_INPUTLANGCHANGE" },
307 { 0x0052, "WM_TCARD" },
308 { 0x0053, "WM_HELP" },
309 { 0x0054, "WM_USERCHANGED" },
310 { 0x0055, "WM_NOTIFYFORMAT" },
311 { 0x007B, "WM_CONTEXTMENU" },
312 { 0x007C, "WM_STYLECHANGING" },
313 { 0x007D, "WM_STYLECHANGED" },
314 { 0x007E, "WM_DISPLAYCHANGE" },
315 { 0x007F, "WM_GETICON" },
316 { 0x0080, "WM_SETICON" },
317 { 0x0081, "WM_NCCREATE" },
318 { 0x0082, "WM_NCDESTROY" },
319 { 0x0083, "WM_NCCALCSIZE" },
320 { 0x0084, "WM_NCHITTEST" },
321 { 0x0085, "WM_NCPAINT" },
322 { 0x0086, "WM_NCACTIVATE" },
323 { 0x0087, "WM_GETDLGCODE" },
324 { 0x0088, "WM_SYNCPAINT" },
325 { 0x00A0, "WM_NCMOUSEMOVE" },
326 { 0x00A1, "WM_NCLBUTTONDOWN" },
327 { 0x00A2, "WM_NCLBUTTONUP" },
328 { 0x00A3, "WM_NCLBUTTONDBLCLK" },
329 { 0x00A4, "WM_NCRBUTTONDOWN" },
330 { 0x00A5, "WM_NCRBUTTONUP" },
331 { 0x00A6, "WM_NCRBUTTONDBLCLK" },
332 { 0x00A7, "WM_NCMBUTTONDOWN" },
333 { 0x00A8, "WM_NCMBUTTONUP" },
334 { 0x00A9, "WM_NCMBUTTONDBLCLK" },
335 { 0x00AB, "WM_NCXBUTTONDOWN" },
336 { 0x00AC, "WM_NCXBUTTONUP" },
337 { 0x00AD, "WM_NCXBUTTONDBLCLK" },
338 { 0x00FF, "WM_INPUT" },
339 { 0x0100, "WM_KEYDOWN" },
340 { 0x0101, "WM_KEYUP" },
341 { 0x0102, "WM_CHAR" },
342 { 0x0103, "WM_DEADCHAR" },
343 { 0x0104, "WM_SYSKEYDOWN" },
344 { 0x0105, "WM_SYSKEYUP" },
345 { 0x0106, "WM_SYSCHAR" },
346 { 0x0107, "WM_SYSDEADCHAR" },
347 { 0x0109, "WM_UNICHAR" },
348 { 0x010D, "WM_IME_STARTCOMPOSITION" },
349 { 0x010E, "WM_IME_ENDCOMPOSITION" },
350 { 0x010F, "WM_IME_COMPOSITION" },
351 { 0x0110, "WM_INITDIALOG" },
352 { 0x0111, "WM_COMMAND" },
353 { 0x0112, "WM_SYSCOMMAND" },
354 { 0x0113, "WM_TIMER" },
355 { 0x0114, "WM_HSCROLL" },
356 { 0x0115, "WM_VSCROLL" },
357 { 0x0116, "WM_INITMENU" },
358 { 0x0117, "WM_INITMENUPOPUP" },
359 { 0x011F, "WM_MENUSELECT" },
360 { 0x0120, "WM_MENUCHAR" },
361 { 0x0121, "WM_ENTERIDLE" },
362 { 0x0122, "WM_MENURBUTTONUP" },
363 { 0x0123, "WM_MENUDRAG" },
364 { 0x0124, "WM_MENUGETOBJECT" },
365 { 0x0125, "WM_UNINITMENUPOPUP" },
366 { 0x0126, "WM_MENUCOMMAND" },
367 { 0x0127, "WM_CHANGEUISTATE" },
368 { 0x0128, "WM_UPDATEUISTATE" },
369 { 0x0129, "WM_QUERYUISTATE" },
370 { 0x0132, "WM_CTLCOLORMSGBOX" },
371 { 0x0133, "WM_CTLCOLOREDIT" },
372 { 0x0134, "WM_CTLCOLORLISTBOX" },
373 { 0x0135, "WM_CTLCOLORBTN" },
374 { 0x0136, "WM_CTLCOLORDLG" },
375 { 0x0137, "WM_CTLCOLORSCROLLBAR" },
376 { 0x0138, "WM_CTLCOLORSTATIC" },
377 { 0x0200, "WM_MOUSEMOVE" },
378 { 0x0201, "WM_LBUTTONDOWN" },
379 { 0x0202, "WM_LBUTTONUP" },
380 { 0x0203, "WM_LBUTTONDBLCLK" },
381 { 0x0204, "WM_RBUTTONDOWN" },
382 { 0x0205, "WM_RBUTTONUP" },
383 { 0x0206, "WM_RBUTTONDBLCLK" },
384 { 0x0207, "WM_MBUTTONDOWN" },
385 { 0x0208, "WM_MBUTTONUP" },
386 { 0x0209, "WM_MBUTTONDBLCLK" },
387 { 0x020A, "WM_MOUSEWHEEL" },
388 { 0x020B, "WM_XBUTTONDOWN" },
389 { 0x020C, "WM_XBUTTONUP" },
390 { 0x020D, "WM_XBUTTONDBLCLK" },
391 { 0x020E, "WM_MOUSEHWHEEL" },
392 { 0x0210, "WM_PARENTNOTIFY" },
393 { 0x0211, "WM_ENTERMENULOOP" },
394 { 0x0212, "WM_EXITMENULOOP" },
395 { 0x0213, "WM_NEXTMENU" },
396 { 0x0214, "WM_SIZING" },
397 { 0x0215, "WM_CAPTURECHANGED" },
398 { 0x0216, "WM_MOVING" },
399 { 0x0218, "WM_POWERBROADCAST" },
400 { 0x0219, "WM_DEVICECHANGE" },
401 { 0x0220, "WM_MDICREATE" },
402 { 0x0221, "WM_MDIDESTROY" },
403 { 0x0222, "WM_MDIACTIVATE" },
404 { 0x0223, "WM_MDIRESTORE" },
405 { 0x0224, "WM_MDINEXT" },
406 { 0x0225, "WM_MDIMAXIMIZE" },
407 { 0x0226, "WM_MDITILE" },
408 { 0x0227, "WM_MDICASCADE" },
409 { 0x0228, "WM_MDIICONARRANGE" },
410 { 0x0229, "WM_MDIGETACTIVE" },
411 { 0x0230, "WM_MDISETMENU" },
412 { 0x0231, "WM_ENTERSIZEMOVE" },
413 { 0x0232, "WM_EXITSIZEMOVE" },
414 { 0x0233, "WM_DROPFILES" },
415 { 0x0234, "WM_MDIREFRESHMENU" },
416 { 0x0241, "WM_NCPOINTERUPDATE"},
417 { 0x0242, "WM_NCPOINTERDOWN"},
418 { 0x0243, "WM_NCPOINTERUP"},
419 { 0x0245, "WM_POINTERUPDATE"},
420 { 0x0246, "WM_POINTERDOWN"},
421 { 0x0247, "WM_POINTERUP"},
422 { 0x0249, "WM_POINTERENTER"},
423 { 0x024A, "WM_POINTERLEAVE"},
424 { 0x0248, "WM_POINTERACTIVATE"},
425 { 0x024C, "WM_POINTERCAPTURECHANGED"},
426 { 0x024D, "WM_TOUCHHITTESTING"},
427 { 0x024E, "WM_POINTERWHEEL"},
428 { 0x024F, "WM_POINTERHWHEEL"},
429 { 0x0250, "DM_POINTERHITTEST"},
430 { 0x0251, "WM_POINTERROUTEDTO"},
431 { 0x0252, "WM_POINTERROUTEDAWAY"},
432 { 0x0253, "WM_POINTERROUTEDRELEASED"},
433 { 0x0281, "WM_IME_SETCONTEXT" },
434 { 0x0282, "WM_IME_NOTIFY" },
435 { 0x0283, "WM_IME_CONTROL" },
436 { 0x0284, "WM_IME_COMPOSITIONFULL" },
437 { 0x0285, "WM_IME_SELECT" },
438 { 0x0286, "WM_IME_CHAR" },
439 { 0x0288, "WM_IME_REQUEST" },
440 { 0x0290, "WM_IME_KEYDOWN" },
441 { 0x0291, "WM_IME_KEYUP" },
442 { 0x02A0, "WM_NCMOUSEHOVER" },
443 { 0x02A1, "WM_MOUSEHOVER" },
444 { 0x02A2, "WM_NCMOUSELEAVE" },
445 { 0x02A3, "WM_MOUSELEAVE" },
446 { 0x02B1, "WM_WTSSESSION_CHANGE" },
447 { 0x02C0, "WM_TABLET_FIRST" },
448 { 0x02C1, "WM_TABLET_FIRST + 1" },
449 { 0x02C2, "WM_TABLET_FIRST + 2" },
450 { 0x02C3, "WM_TABLET_FIRST + 3" },
451 { 0x02C4, "WM_TABLET_FIRST + 4" },
452 { 0x02C5, "WM_TABLET_FIRST + 5" },
453 { 0x02C6, "WM_TABLET_FIRST + 6" },
454 { 0x02C7, "WM_TABLET_FIRST + 7" },
455 { 0x02C8, "WM_TABLET_FIRST + 8" },
456 { 0x02C9, "WM_TABLET_FIRST + 9" },
457 { 0x02CA, "WM_TABLET_FIRST + 10" },
458 { 0x02CB, "WM_TABLET_FIRST + 11" },
459 { 0x02CC, "WM_TABLET_FIRST + 12" },
460 { 0x02CD, "WM_TABLET_FIRST + 13" },
461 { 0x02CE, "WM_TABLET_FIRST + 14" },
462 { 0x02CF, "WM_TABLET_FIRST + 15" },
463 { 0x02D0, "WM_TABLET_FIRST + 16" },
464 { 0x02D1, "WM_TABLET_FIRST + 17" },
465 { 0x02D2, "WM_TABLET_FIRST + 18" },
466 { 0x02D3, "WM_TABLET_FIRST + 19" },
467 { 0x02D4, "WM_TABLET_FIRST + 20" },
468 { 0x02D5, "WM_TABLET_FIRST + 21" },
469 { 0x02D6, "WM_TABLET_FIRST + 22" },
470 { 0x02D7, "WM_TABLET_FIRST + 23" },
471 { 0x02D8, "WM_TABLET_FIRST + 24" },
472 { 0x02D9, "WM_TABLET_FIRST + 25" },
473 { 0x02DA, "WM_TABLET_FIRST + 26" },
474 { 0x02DB, "WM_TABLET_FIRST + 27" },
475 { 0x02DC, "WM_TABLET_FIRST + 28" },
476 { 0x02DD, "WM_TABLET_FIRST + 29" },
477 { 0x02DE, "WM_TABLET_FIRST + 30" },
478 { 0x02DF, "WM_TABLET_LAST" },
479 { 0x02E0, "WM_DPICHANGED" },
480 { 0x0300, "WM_CUT" },
481 { 0x0301, "WM_COPY" },
482 { 0x0302, "WM_PASTE" },
483 { 0x0303, "WM_CLEAR" },
484 { 0x0304, "WM_UNDO" },
485 { 0x0305, "WM_RENDERFORMAT" },
486 { 0x0306, "WM_RENDERALLFORMATS" },
487 { 0x0307, "WM_DESTROYCLIPBOARD" },
488 { 0x0308, "WM_DRAWCLIPBOARD" },
489 { 0x0309, "WM_PAINTCLIPBOARD" },
490 { 0x030A, "WM_VSCROLLCLIPBOARD" },
491 { 0x030B, "WM_SIZECLIPBOARD" },
492 { 0x030C, "WM_ASKCBFORMATNAME" },
493 { 0x030D, "WM_CHANGECBCHAIN" },
494 { 0x030E, "WM_HSCROLLCLIPBOARD" },
495 { 0x030F, "WM_QUERYNEWPALETTE" },
496 { 0x0310, "WM_PALETTEISCHANGING" },
497 { 0x0311, "WM_PALETTECHANGED" },
498 { 0x0312, "WM_HOTKEY" },
499 { 0x0317, "WM_PRINT" },
500 { 0x0318, "WM_PRINTCLIENT" },
501 { 0x0319, "WM_APPCOMMAND" },
502 { 0x031A, "WM_THEMECHANGED" },
503 { 0x0358, "WM_HANDHELDFIRST" },
504 { 0x0359, "WM_HANDHELDFIRST + 1" },
505 { 0x035A, "WM_HANDHELDFIRST + 2" },
506 { 0x035B, "WM_HANDHELDFIRST + 3" },
507 { 0x035C, "WM_HANDHELDFIRST + 4" },
508 { 0x035D, "WM_HANDHELDFIRST + 5" },
509 { 0x035E, "WM_HANDHELDFIRST + 6" },
510 { 0x035F, "WM_HANDHELDLAST" },
511 { 0x0360, "WM_AFXFIRST" },
512 { 0x0361, "WM_AFXFIRST + 1" },
513 { 0x0362, "WM_AFXFIRST + 2" },
514 { 0x0363, "WM_AFXFIRST + 3" },
515 { 0x0364, "WM_AFXFIRST + 4" },
516 { 0x0365, "WM_AFXFIRST + 5" },
517 { 0x0366, "WM_AFXFIRST + 6" },
518 { 0x0367, "WM_AFXFIRST + 7" },
519 { 0x0368, "WM_AFXFIRST + 8" },
520 { 0x0369, "WM_AFXFIRST + 9" },
521 { 0x036A, "WM_AFXFIRST + 10" },
522 { 0x036B, "WM_AFXFIRST + 11" },
523 { 0x036C, "WM_AFXFIRST + 12" },
524 { 0x036D, "WM_AFXFIRST + 13" },
525 { 0x036E, "WM_AFXFIRST + 14" },
526 { 0x036F, "WM_AFXFIRST + 15" },
527 { 0x0370, "WM_AFXFIRST + 16" },
528 { 0x0371, "WM_AFXFIRST + 17" },
529 { 0x0372, "WM_AFXFIRST + 18" },
530 { 0x0373, "WM_AFXFIRST + 19" },
531 { 0x0374, "WM_AFXFIRST + 20" },
532 { 0x0375, "WM_AFXFIRST + 21" },
533 { 0x0376, "WM_AFXFIRST + 22" },
534 { 0x0377, "WM_AFXFIRST + 23" },
535 { 0x0378, "WM_AFXFIRST + 24" },
536 { 0x0379, "WM_AFXFIRST + 25" },
537 { 0x037A, "WM_AFXFIRST + 26" },
538 { 0x037B, "WM_AFXFIRST + 27" },
539 { 0x037C, "WM_AFXFIRST + 28" },
540 { 0x037D, "WM_AFXFIRST + 29" },
541 { 0x037E, "WM_AFXFIRST + 30" },
542 { 0x037F, "WM_AFXLAST" },
543 { 0x0380, "WM_PENWINFIRST" },
544 { 0x0381, "WM_PENWINFIRST + 1" },
545 { 0x0382, "WM_PENWINFIRST + 2" },
546 { 0x0383, "WM_PENWINFIRST + 3" },
547 { 0x0384, "WM_PENWINFIRST + 4" },
548 { 0x0385, "WM_PENWINFIRST + 5" },
549 { 0x0386, "WM_PENWINFIRST + 6" },
550 { 0x0387, "WM_PENWINFIRST + 7" },
551 { 0x0388, "WM_PENWINFIRST + 8" },
552 { 0x0389, "WM_PENWINFIRST + 9" },
553 { 0x038A, "WM_PENWINFIRST + 10" },
554 { 0x038B, "WM_PENWINFIRST + 11" },
555 { 0x038C, "WM_PENWINFIRST + 12" },
556 { 0x038D, "WM_PENWINFIRST + 13" },
557 { 0x038E, "WM_PENWINFIRST + 14" },
558 { 0x038F, "WM_PENWINLAST" },
559 { 0x0400, "WM_USER" },
560 { 0x8000, "WM_APP" }
561 };
562
563 return findWinMessageMapping(knownWM, sizeof(knownWM) / sizeof(knownWM[0]), msg);
564 }
565
activateParameter(uint p)566 static const char *activateParameter(uint p)
567 {
568 static const QWinMessageMapping<uint> activeEnum[] = {
569 {WA_ACTIVE, "Activate"}, {WA_INACTIVE, "Deactivate"},
570 {WA_CLICKACTIVE, "Activate by mouseclick"}
571 };
572
573 return findWinMessageMapping(activeEnum, sizeof(activeEnum) / sizeof(activeEnum[0]), p);
574 }
575
styleFlags(uint style)576 static QString styleFlags(uint style)
577 {
578 static const QWinMessageMapping<uint> styleFlags[] = {
579 FLAG_ENTRY(WS_BORDER), FLAG_ENTRY(WS_CAPTION), FLAG_ENTRY(WS_CHILD),
580 FLAG_ENTRY(WS_CLIPCHILDREN), FLAG_ENTRY(WS_CLIPSIBLINGS),
581 FLAG_ENTRY(WS_DISABLED), FLAG_ENTRY(WS_DLGFRAME), FLAG_ENTRY(WS_GROUP),
582 FLAG_ENTRY(WS_HSCROLL), FLAG_ENTRY(WS_OVERLAPPED),
583 FLAG_ENTRY(WS_OVERLAPPEDWINDOW), FLAG_ENTRY(WS_ICONIC),
584 FLAG_ENTRY(WS_MAXIMIZE), FLAG_ENTRY(WS_MAXIMIZEBOX),
585 FLAG_ENTRY(WS_MINIMIZE), FLAG_ENTRY(WS_MINIMIZEBOX),
586 FLAG_ENTRY(WS_OVERLAPPEDWINDOW), FLAG_ENTRY(WS_POPUP),
587 FLAG_ENTRY(WS_POPUPWINDOW), FLAG_ENTRY(WS_SIZEBOX),
588 FLAG_ENTRY(WS_SYSMENU), FLAG_ENTRY(WS_TABSTOP), FLAG_ENTRY(WS_THICKFRAME),
589 FLAG_ENTRY(WS_TILED), FLAG_ENTRY(WS_TILEDWINDOW), FLAG_ENTRY(WS_VISIBLE),
590 FLAG_ENTRY(WS_VSCROLL)
591 };
592
593 return flagsValue(styleFlags, sizeof(styleFlags) / sizeof(styleFlags[0]), style);
594 }
595
exStyleFlags(uint exStyle)596 static QString exStyleFlags(uint exStyle)
597 {
598 static const QWinMessageMapping<uint> exStyleFlags[] = {
599 FLAG_ENTRY(WS_EX_ACCEPTFILES), FLAG_ENTRY(WS_EX_APPWINDOW),
600 FLAG_ENTRY(WS_EX_CLIENTEDGE), FLAG_ENTRY(WS_EX_DLGMODALFRAME),
601 FLAG_ENTRY(WS_EX_LEFT), FLAG_ENTRY(WS_EX_LEFTSCROLLBAR),
602 FLAG_ENTRY(WS_EX_LTRREADING), FLAG_ENTRY(WS_EX_MDICHILD),
603 FLAG_ENTRY(WS_EX_NOACTIVATE), FLAG_ENTRY(WS_EX_NOPARENTNOTIFY),
604 FLAG_ENTRY(WS_EX_OVERLAPPEDWINDOW), FLAG_ENTRY(WS_EX_PALETTEWINDOW),
605 FLAG_ENTRY(WS_EX_RIGHT), FLAG_ENTRY(WS_EX_RIGHTSCROLLBAR),
606 FLAG_ENTRY(WS_EX_RTLREADING), FLAG_ENTRY(WS_EX_STATICEDGE),
607 FLAG_ENTRY(WS_EX_TOOLWINDOW), FLAG_ENTRY(WS_EX_TOPMOST),
608 FLAG_ENTRY(WS_EX_TRANSPARENT), FLAG_ENTRY(WS_EX_WINDOWEDGE)
609 };
610
611 return flagsValue(exStyleFlags, sizeof(exStyleFlags) / sizeof(exStyleFlags[0]), exStyle);
612 }
613
imeCommand(uint cmd)614 static const char *imeCommand(uint cmd)
615 {
616 static const QWinMessageMapping<uint> commands[] = {
617 FLAG_ENTRY(IMN_CHANGECANDIDATE), FLAG_ENTRY(IMN_CLOSECANDIDATE),
618 FLAG_ENTRY(IMN_CLOSESTATUSWINDOW), FLAG_ENTRY(IMN_GUIDELINE),
619 FLAG_ENTRY(IMN_OPENCANDIDATE), FLAG_ENTRY(IMN_OPENSTATUSWINDOW),
620 FLAG_ENTRY(IMN_SETCANDIDATEPOS), FLAG_ENTRY(IMN_SETCOMPOSITIONFONT),
621 FLAG_ENTRY(IMN_SETCOMPOSITIONWINDOW), FLAG_ENTRY(IMN_SETCONVERSIONMODE),
622 FLAG_ENTRY(IMN_SETOPENSTATUS), FLAG_ENTRY(IMN_SETSENTENCEMODE),
623 FLAG_ENTRY(IMN_SETSTATUSWINDOWPOS)
624 };
625
626 return findWinMessageMapping(commands, sizeof(commands) / sizeof(commands[0]), cmd);
627 }
628
imeShowFlags(uint flags)629 static QString imeShowFlags(uint flags)
630 {
631 static const QWinMessageMapping<uint> showFlags[] = {
632 FLAG_ENTRY(ISC_SHOWUICOMPOSITIONWINDOW),
633 FLAG_ENTRY(ISC_SHOWUICANDIDATEWINDOW),
634 FLAG_ENTRY(ISC_SHOWUICANDIDATEWINDOW << 1),
635 FLAG_ENTRY(ISC_SHOWUICANDIDATEWINDOW << 2),
636 FLAG_ENTRY(ISC_SHOWUICANDIDATEWINDOW << 3)
637 };
638
639 return flagsValue(showFlags, sizeof(showFlags) / sizeof(showFlags[0]), flags);
640 }
641
wmSizeParam(uint p)642 static const char *wmSizeParam(uint p)
643 {
644 static const QWinMessageMapping<uint> sizeParams[] = {
645 FLAG_ENTRY(SIZE_MAXHIDE), FLAG_ENTRY(SIZE_MAXIMIZED),
646 FLAG_ENTRY(SIZE_MAXSHOW), FLAG_ENTRY(SIZE_MINIMIZED),
647 FLAG_ENTRY(SIZE_RESTORED)
648 };
649
650 return findWinMessageMapping(sizeParams, sizeof(sizeParams) / sizeof(sizeParams[0]), p);
651 }
652
virtualKeys(uint vk)653 static QString virtualKeys(uint vk)
654 {
655 static const QWinMessageMapping<uint> keys[] = {
656 FLAG_ENTRY(MK_CONTROL), FLAG_ENTRY(MK_LBUTTON), FLAG_ENTRY(MK_MBUTTON),
657 FLAG_ENTRY(MK_RBUTTON), FLAG_ENTRY(MK_SHIFT), FLAG_ENTRY(MK_XBUTTON1),
658 FLAG_ENTRY(MK_XBUTTON2)
659 };
660
661 return flagsValue(keys, sizeof(keys) / sizeof(keys[0]), vk);
662 }
663
winPosFlags(uint f)664 static QString winPosFlags(uint f)
665 {
666 static const QWinMessageMapping<uint> winPosValues[] = {
667 FLAG_ENTRY(SWP_DRAWFRAME), FLAG_ENTRY(SWP_FRAMECHANGED),
668 FLAG_ENTRY(SWP_HIDEWINDOW), FLAG_ENTRY(SWP_NOACTIVATE),
669 FLAG_ENTRY(SWP_NOCOPYBITS), FLAG_ENTRY(SWP_NOMOVE),
670 FLAG_ENTRY(SWP_NOOWNERZORDER), FLAG_ENTRY(SWP_NOREDRAW),
671 FLAG_ENTRY(SWP_NOREPOSITION), FLAG_ENTRY(SWP_NOSENDCHANGING),
672 FLAG_ENTRY(SWP_NOSIZE), FLAG_ENTRY(SWP_NOZORDER),
673 FLAG_ENTRY(SWP_SHOWWINDOW)
674 };
675
676 return flagsValue(winPosValues, sizeof(winPosValues) / sizeof(winPosValues[0]), f);
677 }
678
winPosInsertAfter(quintptr h)679 static const char *winPosInsertAfter(quintptr h)
680 {
681 static const QWinMessageMapping<quintptr> insertAfterValues[] = {
682 {quintptr(HWND_BOTTOM), "HWND_BOTTOM"},
683 {quintptr(HWND_NOTOPMOST), "HWND_NOTOPMOST"},
684 {quintptr(HWND_TOP), "HWND_TOP"},
685 {quintptr(HWND_TOPMOST), "HWND_TOPMOST"}
686 };
687 return findWinMessageMapping(insertAfterValues, sizeof(insertAfterValues) / sizeof(insertAfterValues[0]), h);
688 }
689
sessionMgrLogOffOption(uint p)690 static const char *sessionMgrLogOffOption(uint p)
691 {
692 #ifndef ENDSESSION_CLOSEAPP
693 #define ENDSESSION_CLOSEAPP 0x00000001
694 #endif
695 #ifndef ENDSESSION_CRITICAL
696 #define ENDSESSION_CRITICAL 0x40000000
697 #endif
698 static const QWinMessageMapping<uint> values[] = {
699 {ENDSESSION_CLOSEAPP, "Close application"},
700 {ENDSESSION_CRITICAL, "Force application end"},
701 {ENDSESSION_LOGOFF, "User logoff"}
702 };
703
704 return findWinMessageMapping(values, sizeof(values) / sizeof(values[0]), p);
705 }
706
707 // Returns a "human readable" string representation of the MSG and the
708 // information it points to
decodeMSG(const MSG & msg)709 QString decodeMSG(const MSG& msg)
710 {
711 const WPARAM wParam = msg.wParam;
712 const LPARAM lParam = msg.lParam;
713
714 QString message;
715 // Custom WM_'s
716 if (msg.message > WM_APP)
717 message= QString::fromLatin1("WM_APP + %1").arg(msg.message - WM_APP);
718 else if (msg.message > WM_USER)
719 message = QString::fromLatin1("WM_USER + %1").arg(msg.message - WM_USER);
720 else if (const char *wmmsgC = findWMstr(msg.message))
721 message = QString::fromLatin1(wmmsgC);
722 else
723 message = QString::fromLatin1("WM_(0x%1)").arg(msg.message, 0, 16); // Unknown WM_, so use number
724
725 // Yes, we want to give the WM_ names 20 chars of space before showing the
726 // decoded message, since some of the common messages are quite long, and
727 // we don't want the decoded information to vary in output position
728 if (message.size() < 20)
729 message.prepend(QString(20 - message.size(), QLatin1Char(' ')));
730 message += QLatin1String(": ");
731
732 const QString hwndS = QString::asprintf("(%p)", reinterpret_cast<void *>(msg.hwnd));
733 const QString wParamS = QString::asprintf("(%p)", reinterpret_cast<void *>(wParam));
734 const QString lParamS = QString::asprintf("(%p)", reinterpret_cast<void *>(lParam));
735
736 QString parameters;
737 switch (msg.message) {
738 case WM_ACTIVATE:
739 if (const char *a = activateParameter(uint(wParam)))
740 parameters += QLatin1String(a);
741 parameters += QLatin1String(" Hwnd ") + hwndS;
742 break;
743 case WM_CAPTURECHANGED:
744 parameters = QLatin1String("Hwnd gaining capture ") + hwndS;
745 break;
746 case WM_CREATE:
747 {
748 auto lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
749 QString className;
750 if (lpcs->lpszClass != nullptr) {
751 className = HIWORD(lpcs->lpszClass) == 0
752 ? QString::number(LOWORD(lpcs->lpszClass), 16) // Atom
753 : QString::fromWCharArray(lpcs->lpszClass);
754 }
755
756 const QString windowName = lpcs->lpszName
757 ? QString::fromWCharArray(lpcs->lpszName) : QString();
758
759 parameters = QString::asprintf("x,y(%4d,%4d) w,h(%4d,%4d) className(%s) windowName(%s) parent(0x%p) style(%s) exStyle(%s)",
760 lpcs->x, lpcs->y, lpcs->cx, lpcs->cy,
761 className.toLatin1().constData(),
762 windowName.toLatin1().constData(),
763 reinterpret_cast<void *>(lpcs->hwndParent),
764 styleFlags(uint(lpcs->style)).toLatin1().constData(),
765 exStyleFlags(lpcs->dwExStyle).toLatin1().constData());
766 }
767 break;
768 case WM_DESTROY:
769 parameters = QLatin1String("Destroy hwnd ") + hwndS;
770 break;
771 case 0x02E0u: { // WM_DPICHANGED
772 auto rect = reinterpret_cast<const RECT *>(lParam);
773 QTextStream(¶meters) << "DPI: " << HIWORD(wParam) << ','
774 << LOWORD(wParam) << ' ' << (rect->right - rect->left) << 'x'
775 << (rect->bottom - rect->top) << Qt::forcesign << rect->left << rect->top;
776 }
777 break;
778 case WM_IME_NOTIFY:
779 {
780 parameters = QLatin1String("Command(");
781 if (const char *c = imeCommand(uint(wParam)))
782 parameters += QLatin1String(c);
783 parameters += QLatin1String(" : ") + lParamS;
784 }
785 break;
786 case WM_IME_SETCONTEXT:
787 parameters = QLatin1String("Input context(")
788 + QLatin1String(wParam == TRUE ? "Active" : "Inactive")
789 + QLatin1String(") Show flags(")
790 + imeShowFlags(DWORD(lParam)) + QLatin1Char(')');
791 break;
792 case WM_KILLFOCUS:
793 parameters = QLatin1String("Hwnd gaining keyboard focus ") + wParamS;
794 break;
795 case WM_CHAR:
796 case WM_IME_CHAR:
797 case WM_KEYDOWN:
798 case WM_KEYUP:
799 {
800 const int nVirtKey = int(wParam);
801 const long lKeyData = long(lParam);
802 int repCount = (lKeyData & 0xffff); // Bit 0-15
803 int scanCode = (lKeyData & 0xf0000) >> 16; // Bit 16-23
804 bool contextCode = !!(lKeyData & 0x20000000); // Bit 29
805 bool prevState = !!(lKeyData & 0x40000000); // Bit 30
806 bool transState = !!(lKeyData & 0x80000000); // Bit 31
807 parameters = QString::asprintf("Virtual-key(0x%x) Scancode(%d) Rep(%d) Contextcode(%d), Prev state(%d), Trans state(%d)",
808 nVirtKey, scanCode, repCount,
809 contextCode, prevState, transState);
810 }
811 break;
812 case WM_INPUTLANGCHANGE:
813 parameters = QStringLiteral("Keyboard layout changed");
814 break;
815 case WM_NCACTIVATE:
816 parameters = (msg.wParam? QLatin1String("Active Titlebar") : QLatin1String("Inactive Titlebar"));
817 break;
818 case WM_MOUSEACTIVATE:
819 {
820 const char *mouseMsg = findWMstr(HIWORD(lParam));
821 parameters = QString::asprintf("TLW(0x%p) HittestCode(0x%x) MouseMsg(%s)",
822 reinterpret_cast<void *>(wParam),
823 LOWORD(lParam), mouseMsg ? mouseMsg : "");
824 }
825 break;
826 case WM_MOUSELEAVE:
827 break; // wParam & lParam not used
828 case WM_MOUSEHOVER:
829 case WM_MOUSEWHEEL:
830 case WM_MOUSEHWHEEL:
831 case WM_LBUTTONDBLCLK:
832 case WM_LBUTTONDOWN:
833 case WM_LBUTTONUP:
834 case WM_MBUTTONDBLCLK:
835 case WM_MBUTTONDOWN:
836 case WM_MBUTTONUP:
837 case WM_RBUTTONDBLCLK:
838 case WM_RBUTTONDOWN:
839 case WM_RBUTTONUP:
840 case WM_MOUSEMOVE:
841 parameters = QString::asprintf("x,y(%4d,%4d) Virtual Keys(",
842 GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))
843 + virtualKeys(uint(wParam)) + QLatin1Char(')');
844 break;
845 case WM_MOVE:
846 parameters = QString::asprintf("x,y(%4d,%4d)", LOWORD(lParam), HIWORD(lParam));
847 break;
848 case WM_ERASEBKGND:
849 case WM_PAINT:
850 parameters = QLatin1String("hdc") + wParamS;
851 break;
852 case WM_QUERYNEWPALETTE:
853 break; // lParam & wParam are unused
854 case WM_SETCURSOR:
855 parameters = QString::asprintf("HitTestCode(0x%x) MouseMsg(", LOWORD(lParam));
856 if (const char *mouseMsg = findWMstr(HIWORD(lParam)))
857 parameters += QLatin1String(mouseMsg);
858 parameters += QLatin1Char(')');
859 break;
860 case WM_SETFOCUS:
861 parameters = QLatin1String("Lost Focus ") + wParamS;
862 break;
863 case WM_SETTEXT:
864 parameters = QLatin1String("Set Text (")
865 + QString::fromWCharArray(reinterpret_cast<const wchar_t *>(lParam))
866 + QLatin1Char(')');
867 break;
868 case WM_SIZE:
869 parameters = QString::asprintf("w,h(%4d,%4d) showmode(",
870 LOWORD(lParam), HIWORD(lParam));
871 if (const char *showMode = wmSizeParam(uint(wParam)))
872 parameters += QLatin1String(showMode);
873 parameters += QLatin1Char(')');
874 break;
875 case WM_WINDOWPOSCHANGED:
876 {
877 auto winPos = reinterpret_cast<LPWINDOWPOS>(lParam);
878 if (!winPos)
879 break;
880 const auto insertAfter = quintptr(winPos->hwndInsertAfter);
881 parameters = QString::asprintf("x,y(%4d,%4d) w,h(%4d,%4d) flags(%s) hwndAfter(",
882 winPos->x, winPos->y, winPos->cx, winPos->cy,
883 winPosFlags(winPos->flags).toLatin1().constData());
884 if (const char *h = winPosInsertAfter(insertAfter))
885 parameters += QLatin1String(h);
886 else
887 parameters += QString::number(insertAfter, 16);
888 parameters += QLatin1Char(')');
889 }
890 break;
891 case WM_QUERYENDSESSION:
892 parameters = QLatin1String("End session: ");
893 if (const char *logoffOption = sessionMgrLogOffOption(uint(wParam)))
894 parameters += QLatin1String(logoffOption);
895 break;
896 default:
897 parameters = QLatin1String("wParam") + wParamS + QLatin1String(" lParam") + lParamS;
898 break;
899 }
900
901 return message + QLatin1String("hwnd") + hwndS + QLatin1Char(' ') + parameters;
902 }
903
operator <<(QDebug dbg,const MSG & msg)904 QDebug operator<<(QDebug dbg, const MSG &msg)
905 {
906 QDebugStateSaver saver(dbg);
907 dbg.noquote();
908 dbg.nospace();
909 dbg << decodeMSG(msg);
910 return dbg;
911 }
912 #endif
913
914 #endif // QT_NO_QOBJECT
915
916 #endif // !defined(Q_OS_WINRT)
917
918 #ifndef QT_NO_QOBJECT
removePostedTimerEvent(QObject * object,int timerId)919 void QCoreApplicationPrivate::removePostedTimerEvent(QObject *object, int timerId)
920 {
921 QThreadData *data = object->d_func()->threadData.loadRelaxed();
922
923 const auto locker = qt_scoped_lock(data->postEventList.mutex);
924 if (data->postEventList.size() == 0)
925 return;
926 for (int i = 0; i < data->postEventList.size(); ++i) {
927 const QPostEvent &pe = data->postEventList.at(i);
928 if (pe.receiver == object
929 && pe.event
930 && (pe.event->type() == QEvent::Timer || pe.event->type() == QEvent::ZeroTimerEvent)
931 && static_cast<QTimerEvent *>(pe.event)->timerId() == timerId) {
932 --pe.receiver->d_func()->postedEvents;
933 pe.event->posted = false;
934 delete pe.event;
935 const_cast<QPostEvent &>(pe).event = 0;
936 return;
937 }
938 }
939 }
940 #endif // QT_NO_QOBJECT
941
942 QT_END_NAMESPACE
943