From 246117d4440eeea80d965d96c63b7229912c1308 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 22 Sep 2010 13:31:32 +0000 Subject: [PATCH] Fix recently broken generation of wxEVT_CHAR_HOOK events in wxMSW. Changes to VKToWX() semantics broke the logic of the global keyboard hook function in wxMSW which didn't generate wxEVT_CHAR_HOOK events for ASCII special keys such as WXK_ESCAPE any more. Fix this and also generate wxEVT_CHAR_HOOK for all events, not just the non-ASCII keys for consistency with the documentation and wxGTK. Closes #12501. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65589 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/window.cpp | 91 ++++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 32 deletions(-) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index c9015b7469..7c21aaee02 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -5632,28 +5632,65 @@ void wxWindowMSW::GenerateMouseLeave() // keyboard handling // --------------------------------------------------------------------------- +namespace +{ + +// Implementation of InitAnyKeyEvent() which can also be used when there is no +// associated window: this can happen for the wxEVT_CHAR_HOOK events created by +// the global keyboard hook (e.g. the event might have happened in a non-wx +// window). void -wxWindowMSW::InitAnyKeyEvent(wxKeyEvent& event, - WXWPARAM wParam, - WXLPARAM lParam) const +MSWInitAnyKeyEvent(wxKeyEvent& event, + WXWPARAM wParam, + WXLPARAM lParam, + const wxWindow *win /* may be NULL */) { - event.SetId(GetId()); + if ( win ) + { + event.SetId(win->GetId()); + event.SetEventObject(const_cast(win)); + } + else // No associated window. + { + // Use wxID_ANY for compatibility with the old code even if wxID_NONE + // would arguably make more sense. + event.SetId(wxID_ANY); + } + event.m_shiftDown = wxIsShiftDown(); event.m_controlDown = wxIsCtrlDown(); event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN; - event.SetEventObject(const_cast(this)); - event.m_rawCode = (wxUint32) wParam; event.m_rawFlags = (wxUint32) lParam; #ifndef __WXWINCE__ event.SetTimestamp(::GetMessageTime()); #endif - // translate the position to client coordinates - const wxPoint mousePos = ScreenToClient(wxGetMousePosition()); - event.m_x = mousePos.x; - event.m_y = mousePos.y; + // Event coordinates must be in window client coordinates system which + // doesn't make sense if there is no window. + // + // We could use screen coordinates for such events but this would make the + // logic of the event handlers more complicated: you'd need to test for the + // event object and interpret the coordinates differently according to + // whether it's NULL or not so unless somebody really asks for this let's + // just avoid the issue. + if ( win ) + { + const wxPoint mousePos = win->ScreenToClient(wxGetMousePosition()); + event.m_x = mousePos.x; + event.m_y = mousePos.y; + } +} + +} // anonymous namespace + +void +wxWindowMSW::InitAnyKeyEvent(wxKeyEvent& event, + WXWPARAM wParam, + WXLPARAM lParam) const +{ + MSWInitAnyKeyEvent(event, wParam, lParam, this); } wxKeyEvent @@ -6560,32 +6597,22 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) DWORD hiWord = HIWORD(lParam); if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) ) { - int id = wxMSWKeyboard::VKToWX(wParam, lParam); - if ( id >= WXK_START ) + wchar_t uc; + int id = wxMSWKeyboard::VKToWX(wParam, lParam, &uc); + if ( id != WXK_NONE ) { + const wxWindow * const win = wxGetActiveWindow(); + wxKeyEvent event(wxEVT_CHAR_HOOK); - if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - event.m_altDown = true; + MSWInitAnyKeyEvent(event, wParam, lParam, win); - event.SetEventObject(NULL); event.m_keyCode = id; - event.m_shiftDown = wxIsShiftDown(); - event.m_controlDown = wxIsCtrlDown(); -#ifndef __WXWINCE__ - event.SetTimestamp(::GetMessageTime()); -#endif - wxWindow *win = wxGetActiveWindow(); - wxEvtHandler *handler; - if ( win ) - { - handler = win->GetEventHandler(); - event.SetId(win->GetId()); - } - else - { - handler = wxTheApp; - event.SetId(wxID_ANY); - } +#if wxUSE_UNICODE + event.m_uniChar = uc; +#endif // wxUSE_UNICODE + + wxEvtHandler * const handler = win ? win->GetEventHandler() + : wxTheApp; if ( handler && handler->ProcessEvent(event) ) { -- 2.45.2