wxUint32 m_rawFlags;
private:
+ // Set the event to propagate if necessary, i.e. if it's of wxEVT_CHAR_HOOK
+ // type. This is used by all ctors.
+ void InitPropagation()
+ {
+ if ( m_eventType == wxEVT_CHAR_HOOK )
+ m_propagationLevel = wxEVENT_PROPAGATE_MAX;
+ }
+
// Copy only the event data present in this class, this is used by
// AssignKeyData() and copy ctor.
void DoAssignMembers(const wxKeyEvent& evt)
@event{EVT_CHAR(func)}
Process a @c wxEVT_CHAR event.
@event{EVT_CHAR_HOOK(func)}
- Process a @c wxEVT_CHAR_HOOK event which is sent to the active
- wxTopLevelWindow (i.e. the one containing the currently focused window)
- or wxApp global object if there is no active window before any other
- keyboard events are generated giving the parent window the opportunity
- to intercept all the keyboard entry. If the event is handled, i.e. the
- handler doesn't call wxEvent::Skip(), neither @c wxEVT_KEY_DOWN nor @c
- wxEVT_CHAR events will be generated (although @c wxEVT_KEY_UP still
- will be). Notice that this event is not generated when the mouse is
- captured as it is considered that the window which has the capture
- should receive all the keyboard events too without allowing its parent
- wxTopLevelWindow to interfere with their processing.
+ Process a @c wxEVT_CHAR_HOOK event. Unlike all the other key events,
+ this event is propagated upwards the window hierarchy which allows
+ intercepting it in the parent window of the focused window to which it
+ is sent initially (if there is no focused window, this event is sent to
+ the wxApp global object). It is also generated before any other key
+ events and so gives the parent window an opportunity to modify the
+ keyboard handling of its children, e.g. it is used internally by
+ wxWidgets in some ports to intercept pressing Esc key in any child of a
+ dialog to close the dialog itself when it's pressed. If the event is
+ handled, i.e. the handler doesn't call wxEvent::Skip(), neither @c
+ wxEVT_KEY_DOWN nor @c wxEVT_CHAR events will be generated (although @c
+ wxEVT_KEY_UP still will be). Notice that this event is not generated
+ when the mouse is captured as it is considered that the window which
+ has the capture should receive all the keyboard events too without
+ allowing its parent wxTopLevelWindow to interfere with their processing.
@endEventTable
@see wxKeyboardState
#if wxUSE_UNICODE
m_uniChar = WXK_NONE;
#endif
+
+ InitPropagation();
}
wxKeyEvent::wxKeyEvent(const wxKeyEvent& evt)
wxKeyboardState(evt)
{
DoAssignMembers(evt);
+
+ InitPropagation();
}
wxKeyEvent::wxKeyEvent(wxEventType eventType, const wxKeyEvent& evt)
DoAssignMembers(evt);
m_eventType = eventType;
+
+ InitPropagation();
}
bool wxKeyEvent::IsKeyInCategory(int category) const
// if it was processed (and not skipped).
bool SendCharHookEvent(const wxKeyEvent& event, wxWindow *win)
{
- // wxEVT_CHAR_HOOK must be sent to the top level parent window to allow it
+ // wxEVT_CHAR_HOOK must be sent to allow the parent windows (e.g. a dialog
+ // which typically closes when Esc key is pressed in any of its controls)
// to handle key events in all of its children unless the mouse is captured
// in which case we consider that the keyboard should be "captured" too.
if ( !g_captureWindow )
{
- wxWindow * const parent = wxGetTopLevelParent(win);
- if ( parent )
- {
- // We need to make a copy of the event object because it is
- // modified while it's handled, notably its WasProcessed() flag
- // is set after it had been processed once.
- wxKeyEvent eventCharHook(event);
- eventCharHook.SetEventType(wxEVT_CHAR_HOOK);
- if ( parent->HandleWindowEvent(eventCharHook) )
- return true;
- }
+ wxKeyEvent eventCharHook(wxEVT_CHAR_HOOK, event);
+ if ( win->HandleWindowEvent(eventCharHook) )
+ return true;
}
return false;
#endif // wxUSE_UNICODE
)
{
- const wxWindow * const win = wxGetActiveWindow();
+ wxWindow const* win = wxWindow::DoFindFocus();
+ if ( !win )
+ {
+ // Even if the focus got lost somehow, still send the event
+ // to the top level parent to allow a wxDialog to always
+ // close on Escape.
+ win = wxGetActiveWindow();
+ }
wxKeyEvent event(wxEVT_CHAR_HOOK);
MSWInitAnyKeyEvent(event, wParam, lParam, win);
#if wxOSX_USE_CARBON
long keyval = event.m_keyCode ;
- wxNonOwnedWindow *tlw = focus->MacGetTopLevelWindow() ;
- if (tlw)
{
- event.SetEventType( wxEVT_CHAR_HOOK );
- handled = tlw->HandleWindowEvent( event );
- if ( handled && event.GetSkipped() )
+ wxKeyEvent eventCharHook(wxEVT_CHAR_HOOK, event);
+ handled = focus->HandleWindowEvent( eventCharHook );
+ if ( handled && eventCharHook.GetSkipped() )
handled = false ;
}
if ( !handled )
{
- event.SetEventType( wxEVT_CHAR );
- event.Skip( false ) ;
handled = focus->HandleWindowEvent( event ) ;
}
// changed by SetupKeyEvent() so it can be wxEVT_KEY_UP too by now).
if ( wxevent.GetEventType() == wxEVT_KEY_DOWN )
{
- wxKeyEvent eventHook(wxevent);
- eventHook.SetEventType(wxEVT_CHAR_HOOK);
- if ( wxGetTopLevelParent(GetWXPeer())->OSXHandleKeyEvent(eventHook) )
+ wxKeyEvent eventHook(wxEVT_CHAR_HOOK, wxevent);
+ if ( GetWXPeer()->OSXHandleKeyEvent(eventHook) )
return true;
}