wxWidgets 3.0.2, MSVC 2013.
The essence of this question is: how does one override the default file drop handler on a wxTextCtrl
? There's a default handler that the superclass installs that I need to override.
I am trying to make a wxWidgets text area that accepts a file drop event. I couldn't find a per class event for file drops in the documentation so I fell back to copying the sample code, which manually Connect
s a handler in the constructor. Here's my class definition.
struct BitsTextCtrl : public wxTextCtrl {
AsmFrame *m_frame;
BitsTextCtrl(AsmFrame *frame, wxPanel *parent);
void onMouseEvent(wxMouseEvent& evt) { evt.Skip(); /* for now */ }
void onDropFiles(wxDropFilesEvent &evt); // my target to setup in the constructor
wxDECLARE_EVENT_TABLE();
};
The implementation looks like the following. The constructor sets up the file drop handler for this instance (much like the samples).
BitsTextCtrl::BitsTextCtrl(AsmFrame *frame, wxPanel *parent)
: wxTextCtrl(parent,
wxID_ANY, wxT(""),
wxDefaultPosition, wxSize(DFT_W/2,3*DFT_H/4),
wxTE_RICH2 | wxTE_MULTILINE | wxTE_DONTWRAP | wxTE_PROCESS_TAB | wxHSCROLL)
{
SetFont(wxFont(12, wxTELETYPE, wxNORMAL, wxNORMAL));
SetBackgroundColour(wxColor(0xffeeeeeeUL));
DragAcceptFiles(true);
Connect(
wxEVT_DROP_FILES,
wxDropFilesEventHandler(BitsTextCtrl::onDropFiles),
NULL, this);
}
void BitsTextCtrl::onDropFiles(wxDropFilesEvent &evt) {
if (evt.GetNumberOfFiles() == 1) {
wxString* dropped = evt.GetFiles();
SetValue(FormatBits(ReadBinary(dropped->c_str())));
}
evt.Skip();
}
wxBEGIN_EVENT_TABLE(BitsTextCtrl, wxTextCtrl)
EVT_MOUSE_EVENTS(BitsTextCtrl::onMouseEvent)
// NOTE: no entry for EVT_DROP_FILES
wxEND_EVENT_TABLE()
My handler gets called correctly and all is well, but then the default per-class handler in wxTextAreaBase
(parent to wxTextArea
clobbers my input). Specifically, this is wired up to wxTextCtrl::OnDropFiles
(note casing difference "On" vs "on") appears to be a default handler that just assumes input is text (which it's not in my case).
Digging through the wxWidgets event handling code I found the following.
// from wxWidgets/...event.cpp (with my annotations in [..])
bool wxEvtHandler::TryHereOnly(wxEvent& event)
{
// If the event handler is disabled it doesn't process any events
if ( !GetEvtHandlerEnabled() )
return false;
// Handle per-instance dynamic event tables first
[This is the path the calls my handler: does the right thing]
if ( m_dynamicEvents && SearchDynamicEventTable(event) )
return true;
// Then static per-class event tables
[This is the default per-class handler than clobbers my hard work]
if ( GetEventHashTable().HandleEvent(event, this) )
return true;
....
How do I disable the per-class event? Or perhaps override it instead? The docs don't list an event table entry for file drops.
UPDATE:
Okay so there is an per class entry (just not listed in the documentation). EVT_MOUSE_EVENTS(BitsTextCtrl::onMouseEvent)
can replace the Connect
call in the constructor, but now I just have two copies of the event handler being called. Same problem.