Added #include in helpbase.cpp
[wxWidgets.git] / src / common / helpbase.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: helpbase.cpp
3 // Purpose: Help system base classes
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "helpbase.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/defs.h"
25 #endif
26
27 #include "wx/helpbase.h"
28 #include "wx/app.h"
29
30 #ifdef __WXMSW__
31 #include "wx/msw/private.h"
32 #endif
33
34 #if wxUSE_HELP
35
36 IMPLEMENT_CLASS(wxHelpControllerBase, wxObject)
37
38 /*
39 * Invokes context-sensitive help
40 */
41
42 IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
43
44 wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
45 {
46 m_inHelp = FALSE;
47
48 if (beginHelp)
49 BeginContextHelp(win);
50 }
51
52 wxContextHelp::~wxContextHelp()
53 {
54 if (m_inHelp)
55 EndContextHelp();
56 }
57
58 bool wxContextHelp::BeginContextHelp(wxWindow* win)
59 {
60 if (!win)
61 win = wxTheApp->GetTopWindow();
62 if (!win)
63 return FALSE;
64
65 wxCursor cursor(wxCURSOR_QUESTION_ARROW);
66 wxSetCursor(cursor);
67
68 win->CaptureMouse();
69
70 EventLoop(cursor, win);
71
72 win->ReleaseMouse();
73
74 return TRUE;
75 }
76
77 bool wxContextHelp::EndContextHelp()
78 {
79 m_inHelp = FALSE;
80
81 return TRUE;
82 }
83
84 bool wxContextHelp::EventLoop(const wxCursor& cursor, wxWindow* win)
85 {
86 #ifdef __WXMSW__
87 m_inHelp = TRUE;
88 while ( m_inHelp )
89 {
90 MSG msg;
91 if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
92 {
93 if (!ProcessHelpMessage((WXMSG*) & msg, cursor, win))
94 {
95 m_inHelp = FALSE;
96 }
97 }
98 else
99 {
100 wxTheApp->ProcessIdle();
101 }
102 }
103 return TRUE;
104 #else
105 return FALSE;
106 #endif
107 }
108
109 #ifdef __WXMSW__
110 bool wxContextHelp::ProcessHelpMessage(WXMSG* wxmsg, const wxCursor& cursor, wxWindow* winInQuestion)
111 {
112 MSG& msg = * (MSG*) wxmsg;
113
114 if (msg.message == WM_KEYDOWN || msg.wParam == VK_ESCAPE)
115 {
116 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
117 return FALSE;
118 }
119
120 if (msg.message == WM_CAPTURECHANGED)
121 {
122 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
123 return FALSE;
124 }
125
126 if (msg.message == WM_ACTIVATE)
127 {
128 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
129 return FALSE;
130 }
131
132 if ((msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST))
133 // || (msg.message >= WM_NCMOUSEFIRST && msg.message <= WM_NCMOUSELAST))
134 {
135 wxSetCursor(cursor);
136
137 HWND hWndHit = ::WindowFromPoint(msg.pt);
138
139 wxWindow* win = wxFindWinFromHandle((WXHWND) hWndHit) ;
140 HWND hWnd = hWndHit;
141
142 // Try to find a window with a wxWindow associated with it
143 while (!win && (hWnd != 0))
144 {
145 hWnd = ::GetParent(hWnd);
146 win = wxFindWinFromHandle((WXHWND) hWnd) ;
147 }
148
149 if (win)
150 {
151 // It's a wxWindows window
152 if (msg.message != WM_LBUTTONDOWN)
153 {
154 // Hit one of our owned windows -- eat the message.
155 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
156 return TRUE;
157 }
158 int iHit = (int)::SendMessage(hWndHit, WM_NCHITTEST, 0,
159 MAKELONG(msg.pt.x, msg.pt.y));
160 if (iHit == HTMENU || iHit == HTSYSMENU)
161 {
162 // Eat this message, send the event and return
163 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
164 DispatchEvent(win, wxPoint(msg.pt.x, msg.pt.y));
165 return FALSE;
166 }
167 else if (iHit == HTCLIENT)
168 {
169 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
170 DispatchEvent(win, wxPoint(msg.pt.x, msg.pt.y));
171 return FALSE;
172 }
173 else
174 {
175 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
176 return FALSE;
177 }
178 }
179 else
180 {
181 // Someone else's message
182 if (PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE))
183 {
184 ::TranslateMessage(&msg);
185 ::DispatchMessage(&msg);
186 }
187 return TRUE;
188 }
189 }
190 else
191 {
192 // allow all other messages to go through (capture still set)
193 if (PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE))
194 DispatchMessage(&msg);
195 return TRUE;
196
197 }
198 return TRUE;
199 }
200 #endif
201
202 // Dispatch the help event to the relevant window
203 bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
204 {
205 wxWindow* subjectOfHelp = win;
206 bool eventProcessed = FALSE;
207 while (subjectOfHelp && !eventProcessed)
208 {
209 wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
210 helpEvent.SetEventObject(this);
211 eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
212
213 // Go up the window hierarchy until the event is handled (or not).
214 // I.e. keep submitting ancestor windows until one is recognised
215 // by the app code that processes the ids and displays help.
216 subjectOfHelp = subjectOfHelp->GetParent();
217 }
218 return eventProcessed;
219 }
220
221
222 #endif // wxUSE_HELP