diff --git a/interface/wx/window.h b/interface/wx/window.h index 18f7b7b9af..ee69245147 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -3758,7 +3758,8 @@ public: or wxMOD_WIN specifying the modifier keys that have to be pressed along with the key. @param virtualKeyCode - The virtual key code of the hotkey. + The key code of the hotkey, e.g. an ASCII character such as @c 'K' + or one of elements of wxKeyCode enum. @return @true if the hotkey was registered successfully. @false if some other application already registered a hotkey with this diff --git a/samples/keyboard/keyboard.cpp b/samples/keyboard/keyboard.cpp index 556fa66516..4d17903c2d 100644 --- a/samples/keyboard/keyboard.cpp +++ b/samples/keyboard/keyboard.cpp @@ -34,6 +34,11 @@ enum IDInputEntry, IDInputText, +#if wxUSE_HOTKEY + HotKeyRegister, + HotKeyUnregister, +#endif // wxUSE_HOTKEY + TestAccelA, TestAccelCtrlA, TestAccelEsc @@ -59,6 +64,33 @@ private: void OnTestAccelEsc(wxCommandEvent& WXUNUSED(event)) { m_logText->AppendText("Test accelerator \"Esc\" used.\n"); } +#if wxUSE_HOTKEY + void OnRegisterHotKey(wxCommandEvent& WXUNUSED(event)) + { + if ( RegisterHotKey(0, wxMOD_ALT | wxMOD_SHIFT, WXK_HOME) ) + { + m_logText->AppendText("Try pressing Alt-Shift-Home anywhere now.\n"); + } + else + { + m_logText->AppendText("Failed to register hot key.\n"); + } + } + + void OnUnregisterHotKey(wxCommandEvent& WXUNUSED(event)) + { + if ( !UnregisterHotKey(0) ) + { + m_logText->AppendText("Failed to unregister hot key.\n"); + } + } + + void OnHotkey(wxKeyEvent& event) + { + LogEvent("Hot key", event); + } +#endif // wxUSE_HOTKEY + void OnClear(wxCommandEvent& WXUNUSED(event)) { m_logText->Clear(); } void OnSkipDown(wxCommandEvent& event) { m_skipDown = event.IsChecked(); } void OnSkipHook(wxCommandEvent& event) { m_skipHook = event.IsChecked(); } @@ -186,6 +218,14 @@ MyFrame::MyFrame(const wxString& title) // now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar(); menuBar->Append(menuFile, "&File"); + +#if wxUSE_HOTKEY + wxMenu* menuHotkey = new wxMenu; + menuHotkey->Append(HotKeyRegister, "&Register hot key"); + menuHotkey->Append(HotKeyUnregister, "&Unregister hot key"); + menuBar->Append(menuHotkey, "Hot&key"); +#endif // wxUSE_HOTKEY + menuBar->Append(menuHelp, "&Help"); // ... and attach this menu bar to the frame @@ -232,6 +272,11 @@ MyFrame::MyFrame(const wxString& title) Bind(wxEVT_MENU, &MyFrame::OnTestAccelA, this, TestAccelA); Bind(wxEVT_MENU, &MyFrame::OnTestAccelCtrlA, this, TestAccelCtrlA); Bind(wxEVT_MENU, &MyFrame::OnTestAccelEsc, this, TestAccelEsc); +#if wxUSE_HOTKEY + Bind(wxEVT_MENU, &MyFrame::OnRegisterHotKey, this, HotKeyRegister); + Bind(wxEVT_MENU, &MyFrame::OnUnregisterHotKey, this, HotKeyUnregister); + Bind(wxEVT_HOTKEY, &MyFrame::OnHotkey, this); +#endif // wxUSE_HOTKEY // notice that we don't connect OnCharHook() to the input window, unlike // the usual key events this one is propagated upwards diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 56eef3d15c..0a380c0e8b 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -7510,6 +7510,21 @@ bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode) if ( modifiers & wxMOD_WIN ) win_modifiers |= MOD_WIN; + // Special compatibility hack: the initial version of this function didn't + // use wxMSWKeyboard::WXToVK() at all, which was wrong as the user code is + // expected to use WXK_XXX constants and not VK_XXX ones, but as people had + // no choice but to use the latter with the previous version of wxWidgets, + // now we have to continue accepting VK_XXX here too. So we assume that the + // argument is a VK constant and not a WXK one if it looks like this should + // be the case based on its value. It helps that all of WXK constants + // before WXK_START have the same value as the corresponding VK constants, + // with the only exception of WXK_DELETE which is equal to VK_F16 -- and we + // consider that the latter is unlikely to be used. + if ( keycode >= WXK_START || keycode == WXK_DELETE ) + keycode = wxMSWKeyboard::WXToVK(keycode); + //else: leave it unchanged because it looks like it's a VK constant (which + // includes ASCII digits and upper case letters) + if ( !::RegisterHotKey(GetHwnd(), hotkeyId, win_modifiers, keycode) ) { wxLogLastError(wxT("RegisterHotKey"));