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