Remove all lines containing cvs/svn "$Id$" keyword.
[wxWidgets.git] / src / msw / evtloopconsole.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/evtloopconsole.cpp
3 // Purpose: wxConsoleEventLoop class for Windows
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 01.06.01
7 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #include "wx/log.h"
28 #include "wx/msw/wrapwin.h"
29 #endif //WX_PRECOMP
30
31 #include "wx/evtloop.h"
32
33 // ============================================================================
34 // wxMSWEventLoopBase implementation
35 // ============================================================================
36
37 // ----------------------------------------------------------------------------
38 // ctor/dtor
39 // ----------------------------------------------------------------------------
40
41 wxMSWEventLoopBase::wxMSWEventLoopBase()
42 {
43 m_shouldExit = false;
44 m_exitcode = 0;
45 }
46
47 // ----------------------------------------------------------------------------
48 // wxEventLoop message processing dispatching
49 // ----------------------------------------------------------------------------
50
51 bool wxMSWEventLoopBase::Pending() const
52 {
53 MSG msg;
54 return ::PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE) != 0;
55 }
56
57 bool wxMSWEventLoopBase::GetNextMessage(WXMSG* msg)
58 {
59 const BOOL rc = ::GetMessage(msg, NULL, 0, 0);
60
61 if ( rc == 0 )
62 {
63 // got WM_QUIT
64 return false;
65 }
66
67 if ( rc == -1 )
68 {
69 // should never happen, but let's test for it nevertheless
70 wxLogLastError(wxT("GetMessage"));
71
72 // still break from the loop
73 return false;
74 }
75
76 return true;
77 }
78
79 int wxMSWEventLoopBase::GetNextMessageTimeout(WXMSG *msg, unsigned long timeout)
80 {
81 // MsgWaitForMultipleObjects() won't notice any input which was already
82 // examined (e.g. using PeekMessage()) but not yet removed from the queue
83 // so we need to remove any immediately messages manually
84 //
85 // NB: using MsgWaitForMultipleObjectsEx() could simplify the code here but
86 // it is not available in very old Windows versions
87 if ( !::PeekMessage(msg, 0, 0, 0, PM_REMOVE) )
88 {
89 // we use this function just in order to not block longer than the
90 // given timeout, so we don't pass any handles to it at all
91 DWORD rc = ::MsgWaitForMultipleObjects
92 (
93 0, NULL,
94 FALSE,
95 timeout,
96 QS_ALLINPUT
97 );
98
99 switch ( rc )
100 {
101 default:
102 wxLogDebug("unexpected MsgWaitForMultipleObjects() return "
103 "value %lu", rc);
104 // fall through
105
106 case WAIT_TIMEOUT:
107 return -1;
108
109 case WAIT_OBJECT_0:
110 if ( !::PeekMessage(msg, 0, 0, 0, PM_REMOVE) )
111 {
112 // somehow it may happen that MsgWaitForMultipleObjects()
113 // returns true but there are no messages -- just treat it
114 // the same as timeout then
115 return -1;
116 }
117 break;
118 }
119 }
120
121 return msg->message != WM_QUIT;
122 }
123
124 // ============================================================================
125 // wxConsoleEventLoop implementation
126 // ============================================================================
127
128 #if wxUSE_CONSOLE_EVENTLOOP
129
130 void wxConsoleEventLoop::WakeUp()
131 {
132 #if wxUSE_THREADS
133 wxWakeUpMainThread();
134 #endif
135 }
136
137 void wxConsoleEventLoop::ProcessMessage(WXMSG *msg)
138 {
139 ::DispatchMessage(msg);
140 }
141
142 bool wxConsoleEventLoop::Dispatch()
143 {
144 MSG msg;
145 if ( !GetNextMessage(&msg) )
146 return false;
147
148 ProcessMessage(&msg);
149
150 return !m_shouldExit;
151 }
152
153 int wxConsoleEventLoop::DispatchTimeout(unsigned long timeout)
154 {
155 MSG msg;
156 int rc = GetNextMessageTimeout(&msg, timeout);
157 if ( rc != 1 )
158 return rc;
159
160 ProcessMessage(&msg);
161
162 return !m_shouldExit;
163 }
164
165 #endif // wxUSE_CONSOLE_EVENTLOOP