1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qcoreapplication.h"
43 #include "qcoreapplication_p.h"
44 #include "qstringlist.h"
45 #include "qt_windows.h"
46 #include "qvector.h"
47 #include "qmutex.h"
48 #include "qfileinfo.h"
49 #include "qcorecmdlineargs_p.h"
50 #include <private/qthread_p.h>
51 #include <ctype.h>
52
53 QT_BEGIN_NAMESPACE
54
55 bool usingWinMain = false; // whether the qWinMain() is used or not
56 int appCmdShow = 0;
57
qWinAppInst()58 Q_CORE_EXPORT HINSTANCE qWinAppInst() // get Windows app handle
59 {
60 return GetModuleHandle(0);
61 }
62
qWinAppPrevInst()63 Q_CORE_EXPORT HINSTANCE qWinAppPrevInst() // get Windows prev app handle
64 {
65 return 0;
66 }
67
qWinAppCmdShow()68 Q_CORE_EXPORT int qWinAppCmdShow() // get main window show command
69 {
70 #if defined(Q_OS_WINCE)
71 return appCmdShow;
72 #else
73 STARTUPINFO startupInfo;
74 GetStartupInfo(&startupInfo);
75
76 return (startupInfo.dwFlags & STARTF_USESHOWWINDOW)
77 ? startupInfo.wShowWindow
78 : SW_SHOWDEFAULT;
79 #endif
80 }
81
qAppFileName()82 Q_CORE_EXPORT QString qAppFileName() // get application file name
83 {
84 // We do MAX_PATH + 2 here, and request with MAX_PATH + 1, so we can handle all paths
85 // up to, and including MAX_PATH size perfectly fine with string termination, as well
86 // as easily detect if the file path is indeed larger than MAX_PATH, in which case we
87 // need to use the heap instead. This is a work-around, since contrary to what the
88 // MSDN documentation states, GetModuleFileName sometimes doesn't set the
89 // ERROR_INSUFFICIENT_BUFFER error number, and we thus cannot rely on this value if
90 // GetModuleFileName(0, buffer, MAX_PATH) == MAX_PATH.
91 // GetModuleFileName(0, buffer, MAX_PATH + 1) == MAX_PATH just means we hit the normal
92 // file path limit, and we handle it normally, if the result is MAX_PATH + 1, we use
93 // heap (even if the result _might_ be exactly MAX_PATH + 1, but that's ok).
94 wchar_t buffer[MAX_PATH + 2];
95 DWORD v = GetModuleFileName(0, buffer, MAX_PATH + 1);
96 buffer[MAX_PATH + 1] = 0;
97
98 if (v == 0)
99 return QString();
100 else if (v <= MAX_PATH)
101 return QString::fromWCharArray(buffer);
102
103 // MAX_PATH sized buffer wasn't large enough to contain the full path, use heap
104 wchar_t *b = 0;
105 int i = 1;
106 size_t size;
107 do {
108 ++i;
109 size = MAX_PATH * i;
110 b = reinterpret_cast<wchar_t *>(realloc(b, (size + 1) * sizeof(wchar_t)));
111 if (b)
112 v = GetModuleFileName(NULL, b, size);
113 } while (b && v == size);
114
115 if (b)
116 *(b + size) = 0;
117 QString res = QString::fromWCharArray(b);
118 free(b);
119
120 return res;
121 }
122
appName() const123 QString QCoreApplicationPrivate::appName() const
124 {
125 return QFileInfo(qAppFileName()).baseName();
126 }
127
128 class QWinMsgHandlerCriticalSection
129 {
130 CRITICAL_SECTION cs;
131 public:
QWinMsgHandlerCriticalSection()132 QWinMsgHandlerCriticalSection()
133 { InitializeCriticalSection(&cs); }
~QWinMsgHandlerCriticalSection()134 ~QWinMsgHandlerCriticalSection()
135 { DeleteCriticalSection(&cs); }
136
lock()137 void lock()
138 { EnterCriticalSection(&cs); }
unlock()139 void unlock()
140 { LeaveCriticalSection(&cs); }
141 };
142
qWinMsgHandler(QtMsgType t,const char * str)143 Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str)
144 {
145 Q_UNUSED(t);
146 // OutputDebugString is not threadsafe.
147
148 // cannot use QMutex here, because qWarning()s in the QMutex
149 // implementation may cause this function to recurse
150 static QWinMsgHandlerCriticalSection staticCriticalSection;
151
152 if (!str)
153 str = "(null)";
154
155 staticCriticalSection.lock();
156
157 QString s(QString::fromLocal8Bit(str));
158 s += QLatin1Char('\n');
159 OutputDebugString((wchar_t*)s.utf16());
160
161 staticCriticalSection.unlock();
162 }
163
164
165 /*****************************************************************************
166 qWinMain() - Initializes Windows. Called from WinMain() in qtmain_win.cpp
167 *****************************************************************************/
168
169 #if defined(Q_OS_WINCE)
qWinMain(HINSTANCE instance,HINSTANCE prevInstance,LPSTR cmdParam,int cmdShow,int & argc,QVector<char * > & argv)170 Q_CORE_EXPORT void __cdecl qWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam,
171 int cmdShow, int &argc, QVector<char *> &argv)
172 #else
173 Q_CORE_EXPORT
174 void qWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam,
175 int cmdShow, int &argc, QVector<char *> &argv)
176 #endif
177 {
178 static bool already_called = false;
179
180 if (already_called) {
181 qWarning("Qt: Internal error: qWinMain should be called only once");
182 return;
183 }
184 already_called = true;
185 usingWinMain = true;
186
187 // Install default debug handler
188 qInstallMsgHandler(qWinMsgHandler);
189
190 // Create command line
191 argv = qWinCmdLine<char>(cmdParam, int(strlen(cmdParam)), argc);
192
193 appCmdShow = cmdShow;
194
195 // Ignore Windows parameters
196 Q_UNUSED(instance);
197 Q_UNUSED(prevInstance);
198 }
199
200 /*!
201 The message procedure calls this function for every message
202 received. Reimplement this function if you want to process window
203 messages \a msg that are not processed by Qt. If you don't want
204 the event to be processed by Qt, then return true and set \a result
205 to the value that the window procedure should return. Otherwise
206 return false.
207
208 It is only directly addressed messages that are filtered. To
209 handle system wide messages, such as messages from a registered
210 hot key, you need to install an event filter on the event
211 dispatcher, which is returned from
212 QAbstractEventDispatcher::instance().
213 */
winEventFilter(MSG * msg,long * result)214 bool QCoreApplication::winEventFilter(MSG *msg, long *result) // Windows event filter
215 {
216 Q_UNUSED(msg);
217 Q_UNUSED(result);
218 return false;
219 }
220
removePostedTimerEvent(QObject * object,int timerId)221 void QCoreApplicationPrivate::removePostedTimerEvent(QObject *object, int timerId)
222 {
223 QThreadData *data = object->d_func()->threadData;
224
225 QMutexLocker locker(&data->postEventList.mutex);
226 if (data->postEventList.size() == 0)
227 return;
228 for (int i = 0; i < data->postEventList.size(); ++i) {
229 const QPostEvent & pe = data->postEventList.at(i);
230 if (pe.receiver == object
231 && pe.event
232 && (pe.event->type() == QEvent::Timer || pe.event->type() == QEvent::ZeroTimerEvent)
233 && static_cast<QTimerEvent *>(pe.event)->timerId() == timerId) {
234 --pe.receiver->d_func()->postedEvents;
235 pe.event->posted = false;
236 delete pe.event;
237 const_cast<QPostEvent &>(pe).event = 0;
238 return;
239 }
240 }
241 }
242
243 #if defined(Q_WS_WIN) && !defined(QT_NO_DEBUG_STREAM)
244 /*****************************************************************************
245 Convenience functions for convert WM_* messages into human readable strings,
246 including a nifty QDebug operator<< for simpel QDebug() << msg output.
247 *****************************************************************************/
248 QT_BEGIN_INCLUDE_NAMESPACE
249 #include <windowsx.h>
250 #include "qdebug.h"
251 QT_END_INCLUDE_NAMESPACE
252
253 #if !defined(GET_X_LPARAM)
254 # define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
255 # define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
256 #endif
257 #ifdef _WIN32_WCE
258 # ifndef WM_NCACTIVATE
259 # define WM_NCACTIVATE 0x86
260 # endif
261 #endif
262
263 // The values below should never change. Note that none of the usual
264 // WM_...FIRST & WM_...LAST values are in the list, as they normally have other
265 // WM_... representations
266 struct KnownWM {
267 uint WM;
268 const char* str;
269 } knownWM[] =
270 {{ 0x0000, "WM_NULL" },
271 { 0x0001, "WM_CREATE" },
272 { 0x0002, "WM_DESTROY" },
273 { 0x0003, "WM_MOVE" },
274 { 0x0005, "WM_SIZE" },
275 { 0x0006, "WM_ACTIVATE" },
276 { 0x0007, "WM_SETFOCUS" },
277 { 0x0008, "WM_KILLFOCUS" },
278 { 0x000A, "WM_ENABLE" },
279 { 0x000B, "WM_SETREDRAW" },
280 { 0x000C, "WM_SETTEXT" },
281 { 0x000D, "WM_GETTEXT" },
282 { 0x000E, "WM_GETTEXTLENGTH" },
283 { 0x000F, "WM_PAINT" },
284 { 0x0010, "WM_CLOSE" },
285 { 0x0011, "WM_QUERYENDSESSION" },
286 { 0x0013, "WM_QUERYOPEN" },
287 { 0x0016, "WM_ENDSESSION" },
288 { 0x0012, "WM_QUIT" },
289 { 0x0014, "WM_ERASEBKGND" },
290 { 0x0015, "WM_SYSCOLORCHANGE" },
291 { 0x0018, "WM_SHOWWINDOW" },
292 { 0x001A, "WM_WININICHANGE" },
293 { 0x001B, "WM_DEVMODECHANGE" },
294 { 0x001C, "WM_ACTIVATEAPP" },
295 { 0x001D, "WM_FONTCHANGE" },
296 { 0x001E, "WM_TIMECHANGE" },
297 { 0x001F, "WM_CANCELMODE" },
298 { 0x0020, "WM_SETCURSOR" },
299 { 0x0021, "WM_MOUSEACTIVATE" },
300 { 0x0022, "WM_CHILDACTIVATE" },
301 { 0x0023, "WM_QUEUESYNC" },
302 { 0x0024, "WM_GETMINMAXINFO" },
303 { 0x0026, "WM_PAINTICON" },
304 { 0x0027, "WM_ICONERASEBKGND" },
305 { 0x0028, "WM_NEXTDLGCTL" },
306 { 0x002A, "WM_SPOOLERSTATUS" },
307 { 0x002B, "WM_DRAWITEM" },
308 { 0x002C, "WM_MEASUREITEM" },
309 { 0x002D, "WM_DELETEITEM" },
310 { 0x002E, "WM_VKEYTOITEM" },
311 { 0x002F, "WM_CHARTOITEM" },
312 { 0x0030, "WM_SETFONT" },
313 { 0x0031, "WM_GETFONT" },
314 { 0x0032, "WM_SETHOTKEY" },
315 { 0x0033, "WM_GETHOTKEY" },
316 { 0x0037, "WM_QUERYDRAGICON" },
317 { 0x0039, "WM_COMPAREITEM" },
318 { 0x003D, "WM_GETOBJECT" },
319 { 0x0041, "WM_COMPACTING" },
320 { 0x0044, "WM_COMMNOTIFY" },
321 { 0x0046, "WM_WINDOWPOSCHANGING" },
322 { 0x0047, "WM_WINDOWPOSCHANGED" },
323 { 0x0048, "WM_POWER" },
324 { 0x004A, "WM_COPYDATA" },
325 { 0x004B, "WM_CANCELJOURNAL" },
326 { 0x004E, "WM_NOTIFY" },
327 { 0x0050, "WM_INPUTLANGCHANGEREQUEST" },
328 { 0x0051, "WM_INPUTLANGCHANGE" },
329 { 0x0052, "WM_TCARD" },
330 { 0x0053, "WM_HELP" },
331 { 0x0054, "WM_USERCHANGED" },
332 { 0x0055, "WM_NOTIFYFORMAT" },
333 { 0x007B, "WM_CONTEXTMENU" },
334 { 0x007C, "WM_STYLECHANGING" },
335 { 0x007D, "WM_STYLECHANGED" },
336 { 0x007E, "WM_DISPLAYCHANGE" },
337 { 0x007F, "WM_GETICON" },
338 { 0x0080, "WM_SETICON" },
339 { 0x0081, "WM_NCCREATE" },
340 { 0x0082, "WM_NCDESTROY" },
341 { 0x0083, "WM_NCCALCSIZE" },
342 { 0x0084, "WM_NCHITTEST" },
343 { 0x0085, "WM_NCPAINT" },
344 { 0x0086, "WM_NCACTIVATE" },
345 { 0x0087, "WM_GETDLGCODE" },
346 { 0x0088, "WM_SYNCPAINT" },
347 { 0x00A0, "WM_NCMOUSEMOVE" },
348 { 0x00A1, "WM_NCLBUTTONDOWN" },
349 { 0x00A2, "WM_NCLBUTTONUP" },
350 { 0x00A3, "WM_NCLBUTTONDBLCLK" },
351 { 0x00A4, "WM_NCRBUTTONDOWN" },
352 { 0x00A5, "WM_NCRBUTTONUP" },
353 { 0x00A6, "WM_NCRBUTTONDBLCLK" },
354 { 0x00A7, "WM_NCMBUTTONDOWN" },
355 { 0x00A8, "WM_NCMBUTTONUP" },
356 { 0x00A9, "WM_NCMBUTTONDBLCLK" },
357 { 0x00AB, "WM_NCXBUTTONDOWN" },
358 { 0x00AC, "WM_NCXBUTTONUP" },
359 { 0x00AD, "WM_NCXBUTTONDBLCLK" },
360 { 0x00FF, "WM_INPUT" },
361 { 0x0100, "WM_KEYDOWN" },
362 { 0x0101, "WM_KEYUP" },
363 { 0x0102, "WM_CHAR" },
364 { 0x0103, "WM_DEADCHAR" },
365 { 0x0104, "WM_SYSKEYDOWN" },
366 { 0x0105, "WM_SYSKEYUP" },
367 { 0x0106, "WM_SYSCHAR" },
368 { 0x0107, "WM_SYSDEADCHAR" },
369 { 0x0109, "WM_UNICHAR" },
370 { 0x010D, "WM_IME_STARTCOMPOSITION" },
371 { 0x010E, "WM_IME_ENDCOMPOSITION" },
372 { 0x010F, "WM_IME_COMPOSITION" },
373 { 0x0110, "WM_INITDIALOG" },
374 { 0x0111, "WM_COMMAND" },
375 { 0x0112, "WM_SYSCOMMAND" },
376 { 0x0113, "WM_TIMER" },
377 { 0x0114, "WM_HSCROLL" },
378 { 0x0115, "WM_VSCROLL" },
379 { 0x0116, "WM_INITMENU" },
380 { 0x0117, "WM_INITMENUPOPUP" },
381 { 0x011F, "WM_MENUSELECT" },
382 { 0x0120, "WM_MENUCHAR" },
383 { 0x0121, "WM_ENTERIDLE" },
384 { 0x0122, "WM_MENURBUTTONUP" },
385 { 0x0123, "WM_MENUDRAG" },
386 { 0x0124, "WM_MENUGETOBJECT" },
387 { 0x0125, "WM_UNINITMENUPOPUP" },
388 { 0x0126, "WM_MENUCOMMAND" },
389 { 0x0127, "WM_CHANGEUISTATE" },
390 { 0x0128, "WM_UPDATEUISTATE" },
391 { 0x0129, "WM_QUERYUISTATE" },
392 { 0x0132, "WM_CTLCOLORMSGBOX" },
393 { 0x0133, "WM_CTLCOLOREDIT" },
394 { 0x0134, "WM_CTLCOLORLISTBOX" },
395 { 0x0135, "WM_CTLCOLORBTN" },
396 { 0x0136, "WM_CTLCOLORDLG" },
397 { 0x0137, "WM_CTLCOLORSCROLLBAR" },
398 { 0x0138, "WM_CTLCOLORSTATIC" },
399 { 0x0200, "WM_MOUSEMOVE" },
400 { 0x0201, "WM_LBUTTONDOWN" },
401 { 0x0202, "WM_LBUTTONUP" },
402 { 0x0203, "WM_LBUTTONDBLCLK" },
403 { 0x0204, "WM_RBUTTONDOWN" },
404 { 0x0205, "WM_RBUTTONUP" },
405 { 0x0206, "WM_RBUTTONDBLCLK" },
406 { 0x0207, "WM_MBUTTONDOWN" },
407 { 0x0208, "WM_MBUTTONUP" },
408 { 0x0209, "WM_MBUTTONDBLCLK" },
409 { 0x020A, "WM_MOUSEWHEEL" },
410 { 0x020B, "WM_XBUTTONDOWN" },
411 { 0x020C, "WM_XBUTTONUP" },
412 { 0x020D, "WM_XBUTTONDBLCLK" },
413 { 0x020E, "WM_MOUSEHWHEEL" },
414 { 0x0210, "WM_PARENTNOTIFY" },
415 { 0x0211, "WM_ENTERMENULOOP" },
416 { 0x0212, "WM_EXITMENULOOP" },
417 { 0x0213, "WM_NEXTMENU" },
418 { 0x0214, "WM_SIZING" },
419 { 0x0215, "WM_CAPTURECHANGED" },
420 { 0x0216, "WM_MOVING" },
421 { 0x0218, "WM_POWERBROADCAST" },
422 { 0x0219, "WM_DEVICECHANGE" },
423 { 0x0220, "WM_MDICREATE" },
424 { 0x0221, "WM_MDIDESTROY" },
425 { 0x0222, "WM_MDIACTIVATE" },
426 { 0x0223, "WM_MDIRESTORE" },
427 { 0x0224, "WM_MDINEXT" },
428 { 0x0225, "WM_MDIMAXIMIZE" },
429 { 0x0226, "WM_MDITILE" },
430 { 0x0227, "WM_MDICASCADE" },
431 { 0x0228, "WM_MDIICONARRANGE" },
432 { 0x0229, "WM_MDIGETACTIVE" },
433 { 0x0230, "WM_MDISETMENU" },
434 { 0x0231, "WM_ENTERSIZEMOVE" },
435 { 0x0232, "WM_EXITSIZEMOVE" },
436 { 0x0233, "WM_DROPFILES" },
437 { 0x0234, "WM_MDIREFRESHMENU" },
438 { 0x0281, "WM_IME_SETCONTEXT" },
439 { 0x0282, "WM_IME_NOTIFY" },
440 { 0x0283, "WM_IME_CONTROL" },
441 { 0x0284, "WM_IME_COMPOSITIONFULL" },
442 { 0x0285, "WM_IME_SELECT" },
443 { 0x0286, "WM_IME_CHAR" },
444 { 0x0288, "WM_IME_REQUEST" },
445 { 0x0290, "WM_IME_KEYDOWN" },
446 { 0x0291, "WM_IME_KEYUP" },
447 { 0x02A0, "WM_NCMOUSEHOVER" },
448 { 0x02A1, "WM_MOUSEHOVER" },
449 { 0x02A2, "WM_NCMOUSELEAVE" },
450 { 0x02A3, "WM_MOUSELEAVE" },
451 { 0x02B1, "WM_WTSSESSION_CHANGE" },
452 { 0x02C0, "WM_TABLET_FIRST" },
453 { 0x02C1, "WM_TABLET_FIRST + 1" },
454 { 0x02C2, "WM_TABLET_FIRST + 2" },
455 { 0x02C3, "WM_TABLET_FIRST + 3" },
456 { 0x02C4, "WM_TABLET_FIRST + 4" },
457 { 0x02C5, "WM_TABLET_FIRST + 5" },
458 { 0x02C6, "WM_TABLET_FIRST + 6" },
459 { 0x02C7, "WM_TABLET_FIRST + 7" },
460 { 0x02C8, "WM_TABLET_FIRST + 8" },
461 { 0x02C9, "WM_TABLET_FIRST + 9" },
462 { 0x02CA, "WM_TABLET_FIRST + 10" },
463 { 0x02CB, "WM_TABLET_FIRST + 11" },
464 { 0x02CC, "WM_TABLET_FIRST + 12" },
465 { 0x02CD, "WM_TABLET_FIRST + 13" },
466 { 0x02CE, "WM_TABLET_FIRST + 14" },
467 { 0x02CF, "WM_TABLET_FIRST + 15" },
468 { 0x02D0, "WM_TABLET_FIRST + 16" },
469 { 0x02D1, "WM_TABLET_FIRST + 17" },
470 { 0x02D2, "WM_TABLET_FIRST + 18" },
471 { 0x02D3, "WM_TABLET_FIRST + 19" },
472 { 0x02D4, "WM_TABLET_FIRST + 20" },
473 { 0x02D5, "WM_TABLET_FIRST + 21" },
474 { 0x02D6, "WM_TABLET_FIRST + 22" },
475 { 0x02D7, "WM_TABLET_FIRST + 23" },
476 { 0x02D8, "WM_TABLET_FIRST + 24" },
477 { 0x02D9, "WM_TABLET_FIRST + 25" },
478 { 0x02DA, "WM_TABLET_FIRST + 26" },
479 { 0x02DB, "WM_TABLET_FIRST + 27" },
480 { 0x02DC, "WM_TABLET_FIRST + 28" },
481 { 0x02DD, "WM_TABLET_FIRST + 29" },
482 { 0x02DE, "WM_TABLET_FIRST + 30" },
483 { 0x02DF, "WM_TABLET_LAST" },
484 { 0x0300, "WM_CUT" },
485 { 0x0301, "WM_COPY" },
486 { 0x0302, "WM_PASTE" },
487 { 0x0303, "WM_CLEAR" },
488 { 0x0304, "WM_UNDO" },
489 { 0x0305, "WM_RENDERFORMAT" },
490 { 0x0306, "WM_RENDERALLFORMATS" },
491 { 0x0307, "WM_DESTROYCLIPBOARD" },
492 { 0x0308, "WM_DRAWCLIPBOARD" },
493 { 0x0309, "WM_PAINTCLIPBOARD" },
494 { 0x030A, "WM_VSCROLLCLIPBOARD" },
495 { 0x030B, "WM_SIZECLIPBOARD" },
496 { 0x030C, "WM_ASKCBFORMATNAME" },
497 { 0x030D, "WM_CHANGECBCHAIN" },
498 { 0x030E, "WM_HSCROLLCLIPBOARD" },
499 { 0x030F, "WM_QUERYNEWPALETTE" },
500 { 0x0310, "WM_PALETTEISCHANGING" },
501 { 0x0311, "WM_PALETTECHANGED" },
502 { 0x0312, "WM_HOTKEY" },
503 { 0x0317, "WM_PRINT" },
504 { 0x0318, "WM_PRINTCLIENT" },
505 { 0x0319, "WM_APPCOMMAND" },
506 { 0x031A, "WM_THEMECHANGED" },
507 { 0x0358, "WM_HANDHELDFIRST" },
508 { 0x0359, "WM_HANDHELDFIRST + 1" },
509 { 0x035A, "WM_HANDHELDFIRST + 2" },
510 { 0x035B, "WM_HANDHELDFIRST + 3" },
511 { 0x035C, "WM_HANDHELDFIRST + 4" },
512 { 0x035D, "WM_HANDHELDFIRST + 5" },
513 { 0x035E, "WM_HANDHELDFIRST + 6" },
514 { 0x035F, "WM_HANDHELDLAST" },
515 { 0x0360, "WM_AFXFIRST" },
516 { 0x0361, "WM_AFXFIRST + 1" },
517 { 0x0362, "WM_AFXFIRST + 2" },
518 { 0x0363, "WM_AFXFIRST + 3" },
519 { 0x0364, "WM_AFXFIRST + 4" },
520 { 0x0365, "WM_AFXFIRST + 5" },
521 { 0x0366, "WM_AFXFIRST + 6" },
522 { 0x0367, "WM_AFXFIRST + 7" },
523 { 0x0368, "WM_AFXFIRST + 8" },
524 { 0x0369, "WM_AFXFIRST + 9" },
525 { 0x036A, "WM_AFXFIRST + 10" },
526 { 0x036B, "WM_AFXFIRST + 11" },
527 { 0x036C, "WM_AFXFIRST + 12" },
528 { 0x036D, "WM_AFXFIRST + 13" },
529 { 0x036E, "WM_AFXFIRST + 14" },
530 { 0x036F, "WM_AFXFIRST + 15" },
531 { 0x0370, "WM_AFXFIRST + 16" },
532 { 0x0371, "WM_AFXFIRST + 17" },
533 { 0x0372, "WM_AFXFIRST + 18" },
534 { 0x0373, "WM_AFXFIRST + 19" },
535 { 0x0374, "WM_AFXFIRST + 20" },
536 { 0x0375, "WM_AFXFIRST + 21" },
537 { 0x0376, "WM_AFXFIRST + 22" },
538 { 0x0377, "WM_AFXFIRST + 23" },
539 { 0x0378, "WM_AFXFIRST + 24" },
540 { 0x0379, "WM_AFXFIRST + 25" },
541 { 0x037A, "WM_AFXFIRST + 26" },
542 { 0x037B, "WM_AFXFIRST + 27" },
543 { 0x037C, "WM_AFXFIRST + 28" },
544 { 0x037D, "WM_AFXFIRST + 29" },
545 { 0x037E, "WM_AFXFIRST + 30" },
546 { 0x037F, "WM_AFXLAST" },
547 { 0x0380, "WM_PENWINFIRST" },
548 { 0x0381, "WM_PENWINFIRST + 1" },
549 { 0x0382, "WM_PENWINFIRST + 2" },
550 { 0x0383, "WM_PENWINFIRST + 3" },
551 { 0x0384, "WM_PENWINFIRST + 4" },
552 { 0x0385, "WM_PENWINFIRST + 5" },
553 { 0x0386, "WM_PENWINFIRST + 6" },
554 { 0x0387, "WM_PENWINFIRST + 7" },
555 { 0x0388, "WM_PENWINFIRST + 8" },
556 { 0x0389, "WM_PENWINFIRST + 9" },
557 { 0x038A, "WM_PENWINFIRST + 10" },
558 { 0x038B, "WM_PENWINFIRST + 11" },
559 { 0x038C, "WM_PENWINFIRST + 12" },
560 { 0x038D, "WM_PENWINFIRST + 13" },
561 { 0x038E, "WM_PENWINFIRST + 14" },
562 { 0x038F, "WM_PENWINLAST" },
563 { 0x0400, "WM_USER" },
564 { 0x8000, "WM_APP" },
565 { 0,0 }}; // End of known messages
566
567 // Looks up the WM_ message in the table above
findWMstr(uint msg)568 static const char* findWMstr(uint msg)
569 {
570 uint i = 0;
571 const char* result = 0;
572 // Known WM_'s
573 while (knownWM[i].str && (knownWM[i].WM != msg))
574 ++i;
575 result = knownWM[i].str;
576 return result;
577 };
578
579 // Convenience function for converting flags and values into readable strings
580 struct FLAG_STRING_STRUCT
581 {
582 uint value;
583 const char* str;
584 };
585
FLAG_STRING(uint value=0,const char * c=0)586 FLAG_STRING_STRUCT FLAG_STRING(uint value = 0, const char *c = 0)
587 {
588 FLAG_STRING_STRUCT s = {value, c};
589 return s;
590 }
591
592 #define FLGSTR(x) FLAG_STRING(x, #x)
593
594 // Returns an ORed (" | ") together string for the flags active in the actual
595 // value. (...) must consist of FLAG_STRING, with a FLAG_STRING() as the last
596 // value in the list passed to the function
flagCheck(uint actual,...)597 QString flagCheck(uint actual, ...)
598 {
599 va_list ap;
600 va_start(ap, actual);
601
602 QString result;
603 int count = 0;
604 FLAG_STRING_STRUCT v;
605 while((v=va_arg(ap,FLAG_STRING_STRUCT)).str) {
606 if ((actual & v.value) == v.value) {
607 if (count++)
608 result += QLatin1String(" | ");
609 result += QString::fromLatin1(v.str);
610 }
611 }
612 va_end(ap);
613 return result;
614 };
615
616 // Returns the string representation of the value in 'actual'. (...) must
617 // consist of FLAG_STRING, with a FLAG_STRING() as the last value in the list
618 // passed to the function
valueCheck(uint actual,...)619 QString valueCheck(uint actual, ...)
620 {
621 va_list ap;
622 va_start(ap, actual);
623
624 QString result;
625 FLAG_STRING_STRUCT v;
626 while((v=va_arg(ap,FLAG_STRING_STRUCT)).str && (actual != v.value))
627 ;
628 result = QString::fromLatin1(v.str);
629
630 va_end(ap);
631 return result;
632 };
633
634 #ifdef Q_CC_BOR
635
decodeMSG(const MSG & msg)636 QString decodeMSG(const MSG& msg)
637 {
638 return QString::fromLatin1("THis is not supported on Borland");
639 }
640
641 #else
642
643 // Returns a "human readable" string representation of the MSG and the
644 // information it points to
decodeMSG(const MSG & msg)645 QString decodeMSG(const MSG& msg)
646 {
647 const WPARAM wParam = msg.wParam;
648 const LPARAM lParam = msg.lParam;
649 QString wmmsg = QString::fromLatin1(findWMstr(msg.message));
650 // Unknown WM_, so use number
651 if (wmmsg.isEmpty())
652 wmmsg = QString::fromLatin1("WM_(%1)").arg(msg.message);
653
654 QString rawParameters;
655 rawParameters.sprintf("hwnd(0x%p) ", (void *)msg.hwnd);
656
657 // Custom WM_'s
658 if (msg.message > WM_APP)
659 wmmsg = QString::fromLatin1("WM_APP + %1").arg(msg.message - WM_APP);
660 else if (msg.message > WM_USER)
661 wmmsg = QString::fromLatin1("WM_USER + %1").arg(msg.message - WM_USER);
662
663 QString parameters;
664 switch (msg.message) {
665 #ifdef WM_ACTIVATE
666 case WM_ACTIVATE:
667 {
668 QString activation = valueCheck(wParam,
669 FLAG_STRING(WA_ACTIVE, "Activate"),
670 FLAG_STRING(WA_INACTIVE, "Deactivate"),
671 FLAG_STRING(WA_CLICKACTIVE, "Activate by mouseclick"),
672 FLAG_STRING());
673 parameters.sprintf("%s Hwnd (0x%p)", activation.toLatin1().data(), (void *)msg.hwnd);
674 }
675 break;
676 #endif
677 #ifdef WM_CAPTURECHANGED
678 case WM_CAPTURECHANGED:
679 parameters.sprintf("Hwnd gaining capture (0x%p)", (void *)lParam);
680 break;
681 #endif
682 #ifdef WM_CREATE
683 case WM_CREATE:
684 {
685 LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
686 QString styles = flagCheck(lpcs->style,
687 FLGSTR(WS_BORDER),
688 FLGSTR(WS_CAPTION),
689 FLGSTR(WS_CHILD),
690 FLGSTR(WS_CLIPCHILDREN),
691 FLGSTR(WS_CLIPSIBLINGS),
692 FLGSTR(WS_DISABLED),
693 FLGSTR(WS_DLGFRAME),
694 FLGSTR(WS_GROUP),
695 FLGSTR(WS_HSCROLL),
696 FLGSTR(WS_OVERLAPPED),
697 #if defined(WS_OVERLAPPEDWINDOW) && (WS_OVERLAPPEDWINDOW != 0)
698 FLGSTR(WS_OVERLAPPEDWINDOW),
699 #endif
700 #ifdef WS_ICONIC
701 FLGSTR(WS_ICONIC),
702 #endif
703 FLGSTR(WS_MAXIMIZE),
704 FLGSTR(WS_MAXIMIZEBOX),
705 FLGSTR(WS_MINIMIZE),
706 FLGSTR(WS_MINIMIZEBOX),
707 FLGSTR(WS_OVERLAPPEDWINDOW),
708 FLGSTR(WS_POPUP),
709 #ifdef WS_POPUPWINDOW
710 FLGSTR(WS_POPUPWINDOW),
711 #endif
712 FLGSTR(WS_SIZEBOX),
713 FLGSTR(WS_SYSMENU),
714 FLGSTR(WS_TABSTOP),
715 FLGSTR(WS_THICKFRAME),
716 #ifdef WS_TILED
717 FLGSTR(WS_TILED),
718 #endif
719 #ifdef WS_TILEDWINDOW
720 FLGSTR(WS_TILEDWINDOW),
721 #endif
722 FLGSTR(WS_VISIBLE),
723 FLGSTR(WS_VSCROLL),
724 FLAG_STRING());
725
726 QString exStyles = flagCheck(lpcs->dwExStyle,
727 #ifdef WS_EX_ACCEPTFILES
728 FLGSTR(WS_EX_ACCEPTFILES),
729 #endif
730 #ifdef WS_EX_APPWINDOW
731 FLGSTR(WS_EX_APPWINDOW),
732 #endif
733 FLGSTR(WS_EX_CLIENTEDGE),
734 FLGSTR(WS_EX_DLGMODALFRAME),
735 #ifdef WS_EX_LEFT
736 FLGSTR(WS_EX_LEFT),
737 #endif
738 FLGSTR(WS_EX_LEFTSCROLLBAR),
739 #ifdef WS_EX_LTRREADING
740 FLGSTR(WS_EX_LTRREADING),
741 #endif
742 #ifdef WS_EX_MDICHILD
743 FLGSTR(WS_EX_MDICHILD),
744 #endif
745 #ifdef WS_EX_NOACTIVATE
746 FLGSTR(WS_EX_NOACTIVATE),
747 #endif
748 #ifdef WS_EX_NOANIMATION
749 FLGSTR(WS_EX_NOANIMATION),
750 #endif
751 FLGSTR(WS_EX_NOPARENTNOTIFY),
752 FLGSTR(WS_EX_OVERLAPPEDWINDOW),
753 #ifdef WS_EX_PALETTEWINDOW
754 FLGSTR(WS_EX_PALETTEWINDOW),
755 #endif
756 #ifdef WS_EX_RIGHT
757 FLGSTR(WS_EX_RIGHT),
758 #endif
759 #ifdef WS_EX_RIGHTSCROLLBAR
760 FLGSTR(WS_EX_RIGHTSCROLLBAR),
761 #endif
762 #ifdef WS_EX_RTLREADING
763 FLGSTR(WS_EX_RTLREADING),
764 #endif
765 FLGSTR(WS_EX_STATICEDGE),
766 FLGSTR(WS_EX_TOOLWINDOW),
767 FLGSTR(WS_EX_TOPMOST),
768 #ifdef WS_EX_TRANSPARENT
769 FLGSTR(WS_EX_TRANSPARENT),
770 #endif
771 FLGSTR(WS_EX_WINDOWEDGE),
772 #ifdef WS_EX_CAPTIONOKBTN
773 FLGSTR(WS_EX_CAPTIONOKBTN),
774 #endif
775 FLAG_STRING());
776
777 QString className;
778 if (lpcs->lpszClass != 0) {
779 if (HIWORD(lpcs->lpszClass) == 0) // Atom
780 className = QString::number(LOWORD(lpcs->lpszClass), 16);
781 else // String
782 className = QString((QChar*)lpcs->lpszClass,
783 (int)wcslen(reinterpret_cast<const wchar_t *>(lpcs->lpszClass)));
784 }
785
786 QString windowName;
787 if (lpcs->lpszName != 0)
788 windowName = QString((QChar*)lpcs->lpszName,
789 (int)wcslen(reinterpret_cast<const wchar_t *>(lpcs->lpszName)));
790
791 parameters.sprintf("x,y(%4d,%4d) w,h(%4d,%4d) className(%s) windowName(%s) parent(0x%p) style(%s) exStyle(%s)",
792 lpcs->x, lpcs->y, lpcs->cx, lpcs->cy, className.toLatin1().data(),
793 windowName.toLatin1().data(), (void *)lpcs->hwndParent,
794 styles.toLatin1().data(), exStyles.toLatin1().data());
795 }
796 break;
797 #endif
798 #ifdef WM_DESTROY
799 case WM_DESTROY:
800 parameters.sprintf("Destroy hwnd (0x%p)", (void *)msg.hwnd);
801 break;
802 #endif
803 #ifdef WM_IME_NOTIFY
804 case WM_IME_NOTIFY:
805 {
806 QString imnCommand = valueCheck(wParam,
807 FLGSTR(IMN_CHANGECANDIDATE),
808 FLGSTR(IMN_CLOSECANDIDATE),
809 FLGSTR(IMN_CLOSESTATUSWINDOW),
810 FLGSTR(IMN_GUIDELINE),
811 FLGSTR(IMN_OPENCANDIDATE),
812 FLGSTR(IMN_OPENSTATUSWINDOW),
813 FLGSTR(IMN_SETCANDIDATEPOS),
814 FLGSTR(IMN_SETCOMPOSITIONFONT),
815 FLGSTR(IMN_SETCOMPOSITIONWINDOW),
816 FLGSTR(IMN_SETCONVERSIONMODE),
817 FLGSTR(IMN_SETOPENSTATUS),
818 FLGSTR(IMN_SETSENTENCEMODE),
819 FLGSTR(IMN_SETSTATUSWINDOWPOS),
820 FLAG_STRING());
821 parameters.sprintf("Command(%s : 0x%p)", imnCommand.toLatin1().data(), (void *)lParam);
822 }
823 break;
824 #endif
825 #ifdef WM_IME_SETCONTEXT
826 case WM_IME_SETCONTEXT:
827 {
828 bool fSet = (BOOL)wParam;
829 DWORD fShow = (DWORD)lParam;
830 QString showFlgs = flagCheck(fShow,
831 #ifdef ISC_SHOWUICOMPOSITIONWINDOW
832 FLGSTR(ISC_SHOWUICOMPOSITIONWINDOW),
833 #endif
834 #ifdef ISC_SHOWUIGUIDWINDOW
835 FLGSTR(ISC_SHOWUIGUIDWINDOW),
836 #endif
837 #ifdef ISC_SHOWUISOFTKBD
838 FLGSTR(ISC_SHOWUISOFTKBD),
839 #endif
840 FLGSTR(ISC_SHOWUICANDIDATEWINDOW),
841 FLGSTR(ISC_SHOWUICANDIDATEWINDOW << 1),
842 FLGSTR(ISC_SHOWUICANDIDATEWINDOW << 2),
843 FLGSTR(ISC_SHOWUICANDIDATEWINDOW << 3),
844 FLAG_STRING());
845 parameters.sprintf("Input context(%s) Show flags(%s)", (fSet? "Active" : "Inactive"), showFlgs.toLatin1().data());
846 }
847 break;
848 #endif
849 #ifdef WM_KILLFOCUS
850 case WM_KILLFOCUS:
851 parameters.sprintf("Hwnd gaining keyboard focus (0x%p)", (void *)wParam);
852 break;
853 #endif
854 #ifdef WM_CHAR
855 case WM_CHAR:
856 #endif
857 #ifdef WM_IME_CHAR
858 case WM_IME_CHAR:
859 #endif
860 #ifdef WM_KEYDOWN
861 case WM_KEYDOWN:
862 #endif
863 #ifdef WM_KEYUP
864 case WM_KEYUP:
865 {
866 int nVirtKey = (int)wParam;
867 long lKeyData = (long)lParam;
868 int repCount = (lKeyData & 0xffff); // Bit 0-15
869 int scanCode = (lKeyData & 0xf0000) >> 16; // Bit 16-23
870 bool contextCode = (lKeyData && 0x20000000); // Bit 29
871 bool prevState = (lKeyData && 0x40000000); // Bit 30
872 bool transState = (lKeyData && 0x80000000); // Bit 31
873 parameters.sprintf("Virual-key(0x%x) Scancode(%d) Rep(%d) Contextcode(%d), Prev state(%d), Trans state(%d)",
874 nVirtKey, scanCode, repCount, contextCode, prevState, transState);
875 }
876 break;
877 #endif
878 #ifdef WM_INPUTLANGCHANGE
879 case WM_INPUTLANGCHANGE:
880 parameters = QLatin1String("Keyboard layout changed");
881 break;
882 #endif // WM_INPUTLANGCHANGE
883 #ifdef WM_NCACTIVATE
884 case WM_NCACTIVATE:
885 {
886 parameters = (msg.wParam? QLatin1String("Active Titlebar") : QLatin1String("Inactive Titlebar"));
887 }
888 break;
889 #endif
890 #ifdef WM_MOUSEACTIVATE
891 case WM_MOUSEACTIVATE:
892 {
893 QString mouseMsg = QString::fromLatin1(findWMstr(HIWORD(lParam)));
894 parameters.sprintf("TLW(0x%p) HittestCode(0x%x) MouseMsg(%s)", (void *)wParam, LOWORD(lParam), mouseMsg.toLatin1().data());
895 }
896 break;
897 #endif
898 #ifdef WM_MOUSELEAVE
899 case WM_MOUSELEAVE:
900 break; // wParam & lParam not used
901 #endif
902 #ifdef WM_MOUSEHOVER
903 case WM_MOUSEHOVER:
904 #endif
905 #ifdef WM_MOUSEWHEEL
906 case WM_MOUSEWHEEL:
907 #endif
908 #ifdef WM_MOUSEHWHEEL
909 case WM_MOUSEHWHEEL:
910 #endif
911 #ifdef WM_LBUTTONDBLCLK
912 case WM_LBUTTONDBLCLK:
913 #endif
914 #ifdef WM_LBUTTONDOWN
915 case WM_LBUTTONDOWN:
916 #endif
917 #ifdef WM_LBUTTONUP
918 case WM_LBUTTONUP:
919 #endif
920 #ifdef WM_MBUTTONDBLCLK
921 case WM_MBUTTONDBLCLK:
922 #endif
923 #ifdef WM_MBUTTONDOWN
924 case WM_MBUTTONDOWN:
925 #endif
926 #ifdef WM_MBUTTONUP
927 case WM_MBUTTONUP:
928 #endif
929 #ifdef WM_RBUTTONDBLCLK
930 case WM_RBUTTONDBLCLK:
931 #endif
932 #ifdef WM_RBUTTONDOWN
933 case WM_RBUTTONDOWN:
934 #endif
935 #ifdef WM_RBUTTONUP
936 case WM_RBUTTONUP:
937 #endif
938 #ifdef WM_MOUSEMOVE
939 case WM_MOUSEMOVE:
940 {
941 QString vrtKeys = flagCheck(wParam,
942 FLGSTR(MK_CONTROL),
943 FLGSTR(MK_LBUTTON),
944 FLGSTR(MK_MBUTTON),
945 FLGSTR(MK_RBUTTON),
946 FLGSTR(MK_SHIFT),
947 #ifdef MK_XBUTTON1
948 FLGSTR(MK_XBUTTON1),
949 #endif
950 #ifdef MK_XBUTTON2
951 FLGSTR(MK_XBUTTON2),
952 #endif
953 FLAG_STRING());
954 parameters.sprintf("x,y(%4d,%4d) Virtual Keys(%s)", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), vrtKeys.toLatin1().data());
955 }
956 break;
957 #endif
958 #ifdef WM_MOVE
959 case WM_MOVE:
960 parameters.sprintf("x,y(%4d,%4d)", LOWORD(lParam), HIWORD(lParam));
961 break;
962 #endif
963 #if defined(WM_PAINT) && defined(WM_ERASEBKGND)
964 case WM_ERASEBKGND:
965 case WM_PAINT:
966 parameters.sprintf("hdc(0x%p)", (void *)wParam);
967 break;
968 #endif
969 #ifdef WM_QUERYNEWPALETTE
970 case WM_QUERYNEWPALETTE:
971 break; // lParam & wParam are unused
972 #endif
973 #ifdef WM_SETCURSOR
974 case WM_SETCURSOR:
975 {
976 QString mouseMsg = QString::fromLatin1(findWMstr(HIWORD(lParam)));
977 parameters.sprintf("HitTestCode(0x%x) MouseMsg(%s)", LOWORD(lParam), mouseMsg.toLatin1().data());
978 }
979 break;
980 #endif
981 #ifdef WM_SETFOCUS
982 case WM_SETFOCUS:
983 parameters.sprintf("Lost Focus (0x%p)", (void *)wParam);
984 break;
985 #endif
986 #ifdef WM_SETTEXT
987 case WM_SETTEXT:
988 parameters.sprintf("Set Text (%s)", QString((QChar*)lParam, (int)wcslen(reinterpret_cast<const wchar_t *>(lParam))).toLatin1().data()); //Unicode string
989 break;
990 #endif
991 #ifdef WM_SIZE
992 case WM_SIZE:
993 {
994 QString showMode = valueCheck(wParam,
995 FLGSTR(SIZE_MAXHIDE),
996 FLGSTR(SIZE_MAXIMIZED),
997 FLGSTR(SIZE_MAXSHOW),
998 FLGSTR(SIZE_MINIMIZED),
999 FLGSTR(SIZE_RESTORED),
1000 FLAG_STRING());
1001
1002 parameters.sprintf("w,h(%4d,%4d) showmode(%s)", LOWORD(lParam), HIWORD(lParam), showMode.toLatin1().data());
1003 }
1004 break;
1005 #endif
1006 #ifdef WM_WINDOWPOSCHANGED
1007 case WM_WINDOWPOSCHANGED:
1008 {
1009 LPWINDOWPOS winPos = (LPWINDOWPOS)lParam;
1010 if (!winPos)
1011 break;
1012 QString hwndAfter = valueCheck(quint64(winPos->hwndInsertAfter),
1013 FLAG_STRING((qptrdiff)HWND_BOTTOM, "HWND_BOTTOM"),
1014 FLAG_STRING((qptrdiff)HWND_NOTOPMOST, "HWND_NOTOPMOST"),
1015 FLAG_STRING((qptrdiff)HWND_TOP, "HWND_TOP"),
1016 FLAG_STRING((qptrdiff)HWND_TOPMOST, "HWND_TOPMOST"),
1017 FLAG_STRING());
1018 if (hwndAfter.isEmpty())
1019 hwndAfter = QString::number((quintptr)winPos->hwndInsertAfter, 16);
1020 QString flags = flagCheck(winPos->flags,
1021 FLGSTR(SWP_DRAWFRAME),
1022 FLGSTR(SWP_FRAMECHANGED),
1023 FLGSTR(SWP_HIDEWINDOW),
1024 FLGSTR(SWP_NOACTIVATE),
1025 #ifdef SWP_NOCOPYBITS
1026 FLGSTR(SWP_NOCOPYBITS),
1027 #endif
1028 FLGSTR(SWP_NOMOVE),
1029 FLGSTR(SWP_NOOWNERZORDER),
1030 FLGSTR(SWP_NOREDRAW),
1031 FLGSTR(SWP_NOREPOSITION),
1032 #ifdef SWP_NOSENDCHANGING
1033 FLGSTR(SWP_NOSENDCHANGING),
1034 #endif
1035 FLGSTR(SWP_NOSIZE),
1036 FLGSTR(SWP_NOZORDER),
1037 FLGSTR(SWP_SHOWWINDOW),
1038 FLAG_STRING());
1039 parameters.sprintf("x,y(%4d,%4d) w,h(%4d,%4d) flags(%s) hwndAfter(%s)", winPos->x, winPos->y, winPos->cx, winPos->cy, flags.toLatin1().data(), hwndAfter.toLatin1().data());
1040 }
1041 break;
1042 #endif
1043 default:
1044 parameters.sprintf("wParam(0x%p) lParam(0x%p)", (void *)wParam, (void *)lParam);
1045 break;
1046 }
1047 // Yes, we want to give the WM_ names 20 chars of space before showing the
1048 // decoded message, since some of the common messages are quite long, and
1049 // we don't want the decoded information to vary in output position
1050 QString message = QString::fromLatin1("%1: ").arg(wmmsg, 20);
1051 message += rawParameters;
1052 message += parameters;
1053 return message;
1054 }
1055
1056 #endif
1057
operator <<(QDebug dbg,const MSG & msg)1058 QDebug operator<<(QDebug dbg, const MSG &msg)
1059 {
1060 dbg << decodeMSG(msg);
1061 return dbg.nospace();
1062 }
1063 #endif
1064
1065 QT_END_NAMESPACE
1066