每个 class 处理程序的 wxTextCtrl 覆盖每个实例的处理程序
wxTextCtrl per class handler overrides per-instance handler
wxWidgets 3.0.2,MSVC 2013。
这个问题的实质是:如何覆盖 wxTextCtrl
上的默认文件放置处理程序? 超级class 有一个默认处理程序] 我需要覆盖的安装。
我正在尝试制作一个接受文件放置事件的 wxWidgets 文本区域。我在文档中找不到文件丢失的每个 class 事件,所以我转而复制示例代码,它在构造函数中手动 Connect
s 一个处理程序。这是我的 class 定义。
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();
};
实现如下所示。
构造函数为此实例设置文件放置处理程序(与示例非常相似)。
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()
我的处理程序被正确调用并且一切正常,但是 wxTextAreaBase
中的默认每个 class 处理程序(wxTextArea
的父级破坏了我的输入)。具体来说,这连接到 wxTextCtrl::OnDropFiles
(注意大小写差异 "On" 与 "on")似乎是一个默认处理程序,它只是假设输入是文本(在我的情况下不是)。
深入研究 wxWidgets 事件处理代码,我发现了以下内容。
// 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;
....
如何禁用每个 class 事件?或者改写它?
docs 不列出文件丢弃的事件 table 条目。
更新:
好的,所以有一个 per class 条目(只是没有在文档中列出)。 EVT_MOUSE_EVENTS(BitsTextCtrl::onMouseEvent)
可以替换构造函数中的 Connect
调用,但现在我只有两个被调用的事件处理程序副本。同样的问题。
解决方案是避免在事件处理程序中调用 wxEvent::Skip
。我误解了这个方法。 Skip()
表示 "don't conusme call the next handler"。不调用 skip 告诉 wxWindows 我们已经完成了事件。
wxWidgets 3.0.2,MSVC 2013。
这个问题的实质是:如何覆盖 wxTextCtrl
上的默认文件放置处理程序? 超级class 有一个默认处理程序] 我需要覆盖的安装。
我正在尝试制作一个接受文件放置事件的 wxWidgets 文本区域。我在文档中找不到文件丢失的每个 class 事件,所以我转而复制示例代码,它在构造函数中手动 Connect
s 一个处理程序。这是我的 class 定义。
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();
};
实现如下所示。 构造函数为此实例设置文件放置处理程序(与示例非常相似)。
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()
我的处理程序被正确调用并且一切正常,但是 wxTextAreaBase
中的默认每个 class 处理程序(wxTextArea
的父级破坏了我的输入)。具体来说,这连接到 wxTextCtrl::OnDropFiles
(注意大小写差异 "On" 与 "on")似乎是一个默认处理程序,它只是假设输入是文本(在我的情况下不是)。
深入研究 wxWidgets 事件处理代码,我发现了以下内容。
// 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;
....
如何禁用每个 class 事件?或者改写它? docs 不列出文件丢弃的事件 table 条目。
更新:
好的,所以有一个 per class 条目(只是没有在文档中列出)。 EVT_MOUSE_EVENTS(BitsTextCtrl::onMouseEvent)
可以替换构造函数中的 Connect
调用,但现在我只有两个被调用的事件处理程序副本。同样的问题。
解决方案是避免在事件处理程序中调用 wxEvent::Skip
。我误解了这个方法。 Skip()
表示 "don't conusme call the next handler"。不调用 skip 告诉 wxWindows 我们已经完成了事件。