Page 1 of 1

How to disable accelerator hot keys inside wxTextCtrl ?

Posted: Tue May 06, 2014 10:15 am
by remi
wx3.0.0. wxMSN and wxOSX.

Hi,

I have a classic application frame containing several widgets as children. Also I added accelerators hotkeys using the menubar and menuitems, for the example, the key 'o' open a file. Some of the widgets are wxTextCtrl and I want that the accelerator table be disabled when the focus is on my wxTextCtrl(s). So that, when I type my text, if I press 'o', I want the 'o' character be added in the textctrl and not the accelerator callback be called.

My question is, what is the simplest / elegant method to do this ?

Thank you
Rémi

Re: How to disable accelerator hot keys inside wxTextCtrl ?

Posted: Fri Apr 17, 2015 6:34 pm
by remi
I still need some help for this one. I am exactly in the same case of that thread: viewtopic.php?f=1&t=35427&p=144903&hili ... or#p144893 however I find its solution doesn't fit to all my needs (see point 3 below).

I think the problem is not seen by other wx users because we are, him and I, using simple keys (like 'a') without modifier as wide hot keys (which is common in graphic / CAD applications).

I still didn't find a solution that:
1. handle hot keys when the focus is not on a wxTextCtrl
2. write the pressed character normally in the wxTextCtrl if it has the focus as it wasn't a shortcut.
3. maintain the nice shortcuts display inside the frame's menu bar items.

1 and 2 can be solved overriding wxApp::FilterEvent and handling hot keys manually, it is possible providing some work, like collecting manually the shortcuts list...
However I have a problem with point 3. I would need to keep the display of the hot keys display inside the menu bar items, but adding them obviously create accelerator entries that enter in conflict with the custom hot key handling solution of 1 and 2...

I tried disabling the accelerator table of the main frame after its creation:

Code: Select all

Frame->SetAcceleratorTable(wxNullAcceleratorTable);
however the hot keys are still processed and so the wxTextCtrl are not filled with solution 1+2.

Any idea for either:
A. a simpler solution for 1 + 2 + 3
B. a solution for keeping the display of the shortcuts inside the menubar while removing its effect (hot key handling for letting me do the job).

Many thanks

Re: How to disable accelerator hot keys inside wxTextCtrl ?

Posted: Thu Nov 02, 2017 7:27 pm
by TomasRiker
I know it's a very old thread, but I came across the same problem and think to have found a working solution.

In the wxFrame, handle the wxEVT_CHAR_HOOK event like this:

Code: Select all

// Just to show the declaration of the variables used:
class MyFrame : public wxDocParentFrame
{
private:
	wxMenuBar* p_menuBar;
	wxAcceleratorTable* p_menuBarAcceleratorTable;
};

wxBEGIN_EVENT_TABLE(MyFrame, wxDocParentFrame)
EVT_CHAR_HOOK(MyFrame::handleCharHookEvent)
wxEND_EVENT_TABLE();

void MyFrame::handleCharHookEvent(wxKeyEvent& event)
{
	if (event.GetKeyCode() == -1)
		p_menuBar->SetAcceleratorTable(*p_menuBarAcceleratorTable);
	else
	{
		wxWindow* p_focus = FindFocus();
		if (p_focus && dynamic_cast<wxTextEntry*>(p_focus))
		{
			p_menuBarAcceleratorTable = new wxAcceleratorTable;
			p_menuBarAcceleratorTable->Ref(*p_menuBar->GetAcceleratorTable());
			p_menuBar->SetAcceleratorTable(wxNullAcceleratorTable);
			wxKeyEvent* p_event = new wxKeyEvent(wxEVT_CHAR_HOOK);
			p_event->m_keyCode = -1;
			QueueEvent(p_event);
		}
	}

	event.Skip();
}
The idea: When a key is pressed and a text entry control has the focus, then the frame's menu bar's accelerator might interfere with the text entry control (e. g. Ctrl+Z, Ctrl+A or even regular character input). So we temporarily disable the menu bar's accelerator table and restore it immediately after processing the event. It's important to clone the accelerator table like shown, simply remembering the pointer won't work.

Re: How to disable accelerator hot keys inside wxTextCtrl ?

Posted: Mon Feb 04, 2019 6:35 pm
by alankdkd
TomasRiker: Thanks! This is what I've been looking for! :D

Re: How to disable accelerator hot keys inside wxTextCtrl ?

Posted: Sun Mar 13, 2022 1:40 am
by xamidi
TomasRiker wrote: Thu Nov 02, 2017 7:27 pm It's important to clone the accelerator table like shown, simply remembering the pointer won't work.
Maybe it changed, at least that statement seems false for me. Using wxWidgets-3.1.0, I found no issues with simply using:

Code: Select all

p_menuBarAcceleratorTable = p_menuBar->GetAcceleratorTable();
However, this workaround was very helpful to me, thanks!