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
This commit is contained in:
Vadim Zeitlin
2010-09-22 13:31:32 +00:00
parent a323f63a8d
commit 246117d444

View File

@@ -5632,28 +5632,65 @@ void wxWindowMSW::GenerateMouseLeave()
// keyboard handling // keyboard handling
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
void namespace
wxWindowMSW::InitAnyKeyEvent(wxKeyEvent& event,
WXWPARAM wParam,
WXLPARAM lParam) const
{ {
event.SetId(GetId());
// 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
MSWInitAnyKeyEvent(wxKeyEvent& event,
WXWPARAM wParam,
WXLPARAM lParam,
const wxWindow *win /* may be NULL */)
{
if ( win )
{
event.SetId(win->GetId());
event.SetEventObject(const_cast<wxWindow *>(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_shiftDown = wxIsShiftDown();
event.m_controlDown = wxIsCtrlDown(); event.m_controlDown = wxIsCtrlDown();
event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN; event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN;
event.SetEventObject(const_cast<wxWindow *>(this));
event.m_rawCode = (wxUint32) wParam; event.m_rawCode = (wxUint32) wParam;
event.m_rawFlags = (wxUint32) lParam; event.m_rawFlags = (wxUint32) lParam;
#ifndef __WXWINCE__ #ifndef __WXWINCE__
event.SetTimestamp(::GetMessageTime()); event.SetTimestamp(::GetMessageTime());
#endif #endif
// translate the position to client coordinates // Event coordinates must be in window client coordinates system which
const wxPoint mousePos = ScreenToClient(wxGetMousePosition()); // 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_x = mousePos.x;
event.m_y = mousePos.y; event.m_y = mousePos.y;
}
}
} // anonymous namespace
void
wxWindowMSW::InitAnyKeyEvent(wxKeyEvent& event,
WXWPARAM wParam,
WXLPARAM lParam) const
{
MSWInitAnyKeyEvent(event, wParam, lParam, this);
} }
wxKeyEvent wxKeyEvent
@@ -6560,32 +6597,22 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
DWORD hiWord = HIWORD(lParam); DWORD hiWord = HIWORD(lParam);
if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) ) if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) )
{ {
int id = wxMSWKeyboard::VKToWX(wParam, lParam); wchar_t uc;
if ( id >= WXK_START ) int id = wxMSWKeyboard::VKToWX(wParam, lParam, &uc);
if ( id != WXK_NONE )
{ {
wxKeyEvent event(wxEVT_CHAR_HOOK); const wxWindow * const win = wxGetActiveWindow();
if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
event.m_altDown = true; wxKeyEvent event(wxEVT_CHAR_HOOK);
MSWInitAnyKeyEvent(event, wParam, lParam, win);
event.SetEventObject(NULL);
event.m_keyCode = id; event.m_keyCode = id;
event.m_shiftDown = wxIsShiftDown(); #if wxUSE_UNICODE
event.m_controlDown = wxIsCtrlDown(); event.m_uniChar = uc;
#ifndef __WXWINCE__ #endif // wxUSE_UNICODE
event.SetTimestamp(::GetMessageTime());
#endif wxEvtHandler * const handler = win ? win->GetEventHandler()
wxWindow *win = wxGetActiveWindow(); : wxTheApp;
wxEvtHandler *handler;
if ( win )
{
handler = win->GetEventHandler();
event.SetId(win->GetId());
}
else
{
handler = wxTheApp;
event.SetId(wxID_ANY);
}
if ( handler && handler->ProcessEvent(event) ) if ( handler && handler->ProcessEvent(event) )
{ {