wxTextCtrl для каждого обработчика класса переопределяет обработчик для каждого экземпляра

wxWidgets 3.0.2, MSVC 2013.

Суть этого вопроса: как переопределить обработчик удаления файла по умолчанию на wxTextCtrl ? Есть обработчик по умолчанию, который устанавливает суперкласс, который мне нужно переопределить.

Я пытаюсь сделать текстовую область wxWidgets, которая принимает событие удаления файла. Я не смог найти событие для каждого класса для удаления файлов в документации, поэтому я вернулся к копированию примера кода, который вручную Connect Обработчик в конструкторе. Вот мое определение класса.

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 (родитель для wxTextArea забил мой вклад). В частности, это связано с wxTextCtrl::OnDropFiles (обратите внимание, что различие в регистре "Вкл.

Копаясь в коде обработки событий 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;
    .... 

Как отключить событие для каждого класса? Или, может быть, вместо этого переопределить? В документах нет списка записей в таблице событий для удаления файлов.

ОБНОВЛЕНИЕ: Хорошо, так что есть запись для каждого класса (просто не указано в документации). EVT_MOUSE_EVENTS(BitsTextCtrl::onMouseEvent) может заменить Connect вызовите конструктор, но теперь у меня есть только две копии вызываемого обработчика событий. Та же проблема.

1 ответ

Решение

Решение состояло в том, чтобы избежать вызова wxEvent::Skip в обработчике событий. Я неправильно понял этот метод. Skip() означает "не вызывайте следующий обработчик". Отказ от вызова пропуска говорит wxWindows, что мы закончили с событием.

Другие вопросы по тегам