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