Передача событий в wxView
Передача событий в wxView
Привет. Проблема в следующем. Есть приложение на базе архитектуры документ-вид. видов у документа два. Так вот событие от кнопки, скажем, последовательно проходит через класс документа, через класс вида (первого) и так далеее. А во второй вид это событие не приходит, как сделать, чтоб событие можно было отловить и во втором виде?
Re: Передача событий в wxView
Я тут вроде нашел ответ. Вот код. Посмотрите правильно я сделал?
Code: Select all
#include <wx/wx.h>
#include <wx/docview.h>
#include <wx/progdlg.h>
// ----------------------------------------------------------------------------
// CDocument
// ----------------------------------------------------------------------------
// Это класс документа. Тут храняться данные, и методы обработки тоже тут находяться
// Здесь происходит загрузка и сохранение и/в файл, изменение данных и так далее
// Для примера возьмем текстовую строку - m_Text - это будут наши данные.
class CDocument : public wxDocument
{
CDocument();
virtual bool OnCreate(const wxString& path, long flags);
bool AddNewView( wxClassInfo* pClassInfo, long flags );
// это здесь и далее нужно для RTTI,
// так как создание объектов делается через RTTI
DECLARE_DYNAMIC_CLASS(CDocument)
public:
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// CTextViewCtrl
// ----------------------------------------------------------------------------
// Это клас редактора. Команды меню направляются в активный вид View, так как у
// нас их два, то нужно отслеживать фокус редактора и устанавливать активным
// соответсвующимй вид.
class CTextViewCtrl : public wxTextCtrl
{
public:
CTextViewCtrl(wxWindow *parent, wxWindowID id = wxID_ANY);
void SetView(wxView *v)
{
m_view = v;
}
private:
wxView *m_view;
void OnSetFocus(wxFocusEvent& event);
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// CFrame
// ----------------------------------------------------------------------------
// Класс фрейма - тоже должно быть знакомо
// собственно самое главное окошко )
// в качестве родителя используется специальный класс wxDocParentFrame
// в нем реализован некоторый функционал по обработке предопределеннных меню
// (wxID_NEW, wxID_OPEN и т.д.)
class CFrame : public wxDocParentFrame
{
public:
CFrame(wxDocManager *manager, wxFrame *parent);
CTextViewCtrl *m_leftText;
CTextViewCtrl *m_rightText;
void OnProgressDialog(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event) { wxMessageBox("Sample for 2 View"); }
void OnUpdateFileDisable(wxUpdateUIEvent& event) { event.Enable(false); }
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// CApp
// ----------------------------------------------------------------------------
// Класс приложения, должен быть знаком )
class CApp : public wxApp
{
// менеджер документов
// он хранит список созданных документов (в случае MDI приложения) или один
// документ в случае SDI
wxDocManager *m_docManager;
public:
virtual bool OnInit();
CFrame *GetMainFrame();
};
// Объявляет глобальный объект CApp,
// теперь к классу приложения можно обращаться
// с помощью глобальной функции wxGetApp().метод_класса_CApp
DECLARE_APP(CApp)
// ----------------------------------------------------------------------------
// CViewTextLeft
// ----------------------------------------------------------------------------
// Собственно вид, создается документом
// и отображает данные из документа,
// чтоб получить доступ к документу используется метод wxDocument *GetDocument();
// его нужно приводить к нашему типу документа, обычно пишут так
// CDocument *pDoc = wxDynamicCast(GetDocument(), CDocument);
// или по старому
// CDocument *pDoc = (CDocument *)GetDocument();
class CViewTextLeft : public wxView
{
CViewTextLeft();
virtual bool OnCreate(wxDocument *WXUNUSED(doc), long WXUNUSED(flags));
bool OnClose(bool bDelWindow);
void OnUpdate(wxView* sender, wxObject* hint);
virtual void OnDraw(wxDC *dc);
CTextViewCtrl *m_leftText;
void OnFile(wxCommandEvent& event);
void OnUpdateFile(wxUpdateUIEvent& event);
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(CViewTextLeft)
};
// ----------------------------------------------------------------------------
// CViewTextRight
// ----------------------------------------------------------------------------
// Собственно вид, создается документом
// и отображает данные из документа,
// чтоб получить доступ к документу используется метод wxDocument *GetDocument();
// его нужно приводить к нашему типу документа, обычно пишут так
// CDocument *pDoc = wxDynamicCast(GetDocument(), CDocument);
// или по старому
// CDocument *pDoc = (CDocument *)GetDocument();
class CViewTextRight : public wxView
{
CViewTextRight();
virtual bool OnCreate(wxDocument *WXUNUSED(doc), long WXUNUSED(flags));
bool OnClose(bool bDelWindow);
void OnUpdate(wxView* sender, wxObject* hint);
virtual void OnDraw(wxDC *dc);
CTextViewCtrl *m_rightText;
void OnFile(wxCommandEvent& event);
void OnUpdateFile(wxUpdateUIEvent& event);
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(CViewTextRight)
};
// ----------------------------------------------------------------------------
// I M P L E M E N T A T I O N
// ----------------------------------------------------------------------------
IMPLEMENT_APP(CApp)
IMPLEMENT_DYNAMIC_CLASS(CDocument, wxDocument)
IMPLEMENT_DYNAMIC_CLASS(CViewTextLeft, wxView)
IMPLEMENT_DYNAMIC_CLASS(CViewTextRight, wxView)
BEGIN_EVENT_TABLE(CDocument, wxDocument)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(CTextViewCtrl, wxTextCtrl)
EVT_SET_FOCUS(CTextViewCtrl::OnSetFocus)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(CViewTextLeft, wxView)
EVT_MENU(wxID_FILE1, CViewTextLeft::OnFile)
EVT_UPDATE_UI(wxID_FILE1, CViewTextLeft::OnUpdateFile)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(CViewTextRight, wxView)
EVT_MENU(wxID_FILE2, CViewTextRight::OnFile)
EVT_UPDATE_UI(wxID_FILE2, CViewTextRight::OnUpdateFile)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(CFrame, wxDocParentFrame)
EVT_MENU(wxID_ABOUT, CFrame::OnAbout)
EVT_MENU(wxID_ADD, CFrame::OnProgressDialog)
EVT_UPDATE_UI(wxID_FILE2, CFrame::OnUpdateFileDisable)
EVT_UPDATE_UI(wxID_FILE2, CFrame::OnUpdateFileDisable)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// CTextViewCtrl
// ----------------------------------------------------------------------------
CTextViewCtrl::CTextViewCtrl(wxWindow *parent, wxWindowID id)
: wxTextCtrl(parent, id, "", wxDefaultPosition, wxSize(200, 200), wxTE_MULTILINE)
, m_view(NULL)
{
}
void CTextViewCtrl::OnSetFocus(wxFocusEvent& event)
{
if (m_view)
{
// при получении фокуса элементом управления
// делаем соответсвующий (содержащий данный элемент управления)
// вид активным
m_view->Activate(true);
}
event.Skip(); // что бы курсор отображался
}
// ----------------------------------------------------------------------------
// CDocument
// ----------------------------------------------------------------------------
CDocument::CDocument()
{
}
// Добавление видов
bool CDocument::OnCreate(const wxString& path, long flags)
{
wxLogDebug("CDocument::OnCreate");
if ( !AddNewView( CLASSINFO( CViewTextLeft ), flags ) )
{
return false;
}
if ( !AddNewView( CLASSINFO( CViewTextRight ), flags ) )
{
return false;
}
return true;
}
// вспомогательная функция создания видов через RTTI
// код подсмотрен в исходниках wxWidgets
bool CDocument::AddNewView( wxClassInfo* pClassInfo, long flags )
{
if( !pClassInfo )
{
return false;
}
wxView* pView = (wxView *)pClassInfo->CreateObject();
if( pView )
{
pView->SetDocument( this );
if ( !pView->OnCreate( this, flags ) )
{
delete pView;
}
else
{
AddView( pView );
return true;
}
}
return false;
}
// ----------------------------------------------------------------------------
// CApp
// ----------------------------------------------------------------------------
bool CApp::OnInit()
{
// для SDI - 1 документ
// для MDI - без ограничений
// устанавливает число одновременно открытых документов
m_docManager = new wxDocManager;
m_docManager->SetMaxDocsOpen(1);
new wxDocTemplate( m_docManager,
_T(""), // тут парамтеры всякие, можно помотреть в документации
_T(""),
_T(""),
_T(""),
_T(""),
_T(""),
CLASSINFO(CDocument),// Это документ
NULL // А здесь обычно вид, если один
// а если несколько как у нас, то создаем вручную
// CDocument::OnCreate() (смотри выше)
);
CFrame *frame = new CFrame(m_docManager, NULL);
SetTopWindow(frame);
frame->Center();
frame->Show();
return true;
}
CFrame *CApp::GetMainFrame()
{
return (CFrame *)GetTopWindow();
}
// ----------------------------------------------------------------------------
// CFrame
// ----------------------------------------------------------------------------
CFrame::CFrame(wxDocManager *manager, wxFrame *parent)
: wxDocParentFrame( manager, parent, wxID_ANY, _("Document View 2 SDI"))
{
wxMenu *menuFile = new wxMenu();
menuFile->Append(wxID_NEW, _("&New\tCtrl+N"));
menuFile->Append(wxID_CLOSE, _("&Close"));
menuFile->AppendSeparator();
menuFile->Append(wxID_EXIT, _("E&xit"));
wxMenu *menuEdit = new wxMenu();
menuEdit->Append(wxID_FILE1, _("&Menu of Left Text Ctrl"));
menuEdit->Append(wxID_FILE2, _("&Menu of Right Text Ctrl"));
menuEdit->Append(wxID_ADD, _("&Show Progress Dialog"));
wxMenu *menuHelp = new wxMenu();
menuHelp->Append(wxID_ABOUT, _("&About\tCtrl+A"));
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append(menuFile, _("&File"));
menuBar->Append(menuEdit, _("&Edit"));
menuBar->Append(menuHelp, _("&Help"));
SetMenuBar(menuBar);
SetMinSize(GetSize());
wxPanel *panel = new wxPanel(this);
m_leftText = new CTextViewCtrl(panel);
m_rightText = new CTextViewCtrl(panel);
wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_leftText, 1, wxEXPAND|wxRIGHT, 2);
sizer->Add(m_rightText, 1, wxEXPAND|wxRIGHT, 2);
panel->SetSizer(sizer);
sizer->SetSizeHints(this);
CreateStatusBar(2);
}
void CFrame::OnProgressDialog(wxCommandEvent& event)
{
wxProgressDialog dlg("Progress", "Wait while working...", 100, this, wxPD_AUTO_HIDE);
for (int i = 0; i <= 100; i++)
{
dlg.Update(i);
wxMilliSleep(100);
}
}
// ----------------------------------------------------------------------------
// CViewTextLeft
// ----------------------------------------------------------------------------
CViewTextLeft::CViewTextLeft()
{
}
bool CViewTextLeft::OnCreate(wxDocument *WXUNUSED(doc), long WXUNUSED(flags))
{
m_leftText = wxGetApp().GetMainFrame()->m_leftText;
m_leftText->SetFocus();
m_leftText->SetView(this);
Activate(true);
return true;
}
bool CViewTextLeft::OnClose(bool bDelWindow)
{
m_leftText->Clear();
m_leftText->SetView(NULL);
m_leftText = NULL;
Activate(false);
if ( bDelWindow )
{
}
return true;
}
// вызывается когда документ обновляет виды с помощью UpdateAllViews()
void CViewTextLeft::OnUpdate(wxView* sender, wxObject* hint)
{
}
// вызывается CCanvas для рисования
void CViewTextLeft::OnDraw(wxDC *dc)
{
}
void CViewTextLeft::OnFile(wxCommandEvent& event)
{
m_leftText->AppendText("Select menu to left View\n");
}
void CViewTextLeft::OnUpdateFile(wxUpdateUIEvent& event)
{
event.Enable(true);
}
// ----------------------------------------------------------------------------
// CViewTextRight
// ----------------------------------------------------------------------------
CViewTextRight::CViewTextRight()
{
}
bool CViewTextRight::OnCreate(wxDocument *WXUNUSED(doc), long WXUNUSED(flags))
{
m_rightText = wxGetApp().GetMainFrame()->m_rightText;
m_rightText->SetView(this);
return true;
}
bool CViewTextRight::OnClose(bool bDelWindow)
{
m_rightText->Clear();
m_rightText->SetView(NULL);
m_rightText = NULL;
Activate(false);
if ( bDelWindow )
{
}
return true;
}
// вызывается когда документ обновляет виды с помощью UpdateAllViews()
void CViewTextRight::OnUpdate(wxView* sender, wxObject* hint)
{
}
// вызывается CCanvas для рисования
void CViewTextRight::OnDraw(wxDC *dc)
{
}
void CViewTextRight::OnFile(wxCommandEvent& event)
{
m_rightText->AppendText("Select menu to right View\n");
}
void CViewTextRight::OnUpdateFile(wxUpdateUIEvent& event)
{
event.Enable(true);
}