Catching key events globally
From WxWiki
Keyboard events go to the component that currently has focus and do not propagate to the parent; if you are trying to catch key events globally it can thus be a little tricky. Here are a few ways to solve this problem - keep in mind there are probably more than presented here.
Contents |
[edit] Filter events
Source: http://wxforum.shadonet.com/viewtopic.php?p=66017#66017
Override wxApp::FilterEvent. This function is called early in event-processing, so you can do things like this (for F1):
int MyApp::FilterEvent(wxEvent& event) { if ( event.GetEventType()==wxEVT_KEY_DOWN && ((wxKeyEvent&)event).GetKeyCode()==WXK_F1) { frame->OnHelpF1( (wxKeyEvent&)event ); return true; } return -1; }
This will work most of the time. It will fail if
- Your application is not in the foreground. If you wish to catch keys even when your app is in the background, you will need to use platform-specific code
- Your window-manager grabs the key for itself, in which case your app won't see it.
- (Using wxGtk---I don't know about other platforms) the key is pressed while a modal wxDialog is showing, and the dialog doesn't have keyboard focus. The solution is to call SetFocus() on one of the dialog's children before calling ShowModal().
[edit] Recursive connect
You can recursively ->Connect() all components in a frame, therefore you will catch events no matter where the focus is.
void MyDialog::createChilds(void) { // create the childs: panels, textctrls, buttons, ... // ... ///////////////////////////////////// // after creation: this->connectKeyDownEvent(this); } void MyDialog::connectKeyDownEvent(wxWindow* pclComponent) { if(pclComponent) { pclComponent->Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(MyDialog::onKeyDown), (wxObject*) NULL, this); wxWindowListNode* pclNode = pclComponent->GetChildren().GetFirst(); while(pclNode) { wxWindow* pclChild = pclNode->GetData(); this->connectKeyDownEvent(pclChild); pclNode = pclNode->GetNext(); } } } void MyDialog::onKeyDown(wxKeyEvent& event) { // do your event-processing here }
Code author : clyde729 (Source : http://wxforum.shadonet.com/viewtopic.php?t=9361)
[edit] Register Hot Key
bool wxWindow::RegisterHotKey(int hotkeyId, int modifiers, int virtualKeyCode)
You can also make a hot key part of a menu item
editMenu->Append(MENU_EDIT_COPY, _("Copy\tCtrl-C"));
[edit] Accelerator table
MyFrame::MyFrame(...) : wxFrame { wxAcceleratorEntry entries[14]; entries[0].Set(wxACCEL_CTRL, (int) 'O', MENU_LOAD_FILE); ... entries[12].Set(wxACCEL_NORMAL, WXK_SPACE, KEY_SPACE); entries[13].Set(wxACCEL_NORMAL, WXK_ESCAPE, KEY_ESC); wxAcceleratorTable accel(14, entries); SetAcceleratorTable(accel); } ... EVT_MENU(KEY_ESC,MyFrame::CheckAbort) EVT_MENU(KEY_SPACE,MyFrame::CheckAbort)
Source : http://wxforum.shadonet.com/viewtopic.php?t=18140 Author : celstark
