2014-01-22 34 views
0

我試圖實現我自己的自定義事件。它可以工作,如果我從我連接它的類(一個wxFrame)發佈它,但是如果它從一個子wxFrame發佈它不會被捕獲。wxwidgets自定義事件不會傳播到父窗口

自定義事件:

**cFrameFocus.h** 
#pragma once 
#include <wx\event.h> 
class cFrameFocusEvent; 
const wxEventTypeTag<cFrameFocusEvent> evtFRAME_FOCUS(wxNewEventType()); 
//eventhandler macro 
#if _MSC_VER <= 1600 
typedef void (wxEvtHandler::*MyFrameFocusEventFunction)(cFrameFocusEvent&); 
#define FrameFocusEventHandler(func) wxEVENT_HANDLER_CAST(MyFrameFocusEventFunction,func) 
#else 
#define FrameFocusEventHandler(func) (&func) 
#endif 
class cFrameFocusEvent : 
    public wxEvent 
{ 
    wxWindow* m_frame; 
public: 
    cFrameFocusEvent(wxEventType pEventType,int pWinId = wxID_ANY,const wxWindow* pWin = 0); 
    ~cFrameFocusEvent(void); 
    //impement base class pure virtual 
    virtual wxEvent* Clone(void)const; 
    //accessor 
    wxWindow* GetWindow(void)const; 
}; 

**cFrameFocus.cpp** 
#include "cFrameFocus.h" 
cFrameFocusEvent::cFrameFocusEvent(wxEventType pEventType,int pWinId,const wxWindow* pWin): 
wxEvent(pWinId,pEventType) 
{ 
    m_frame = const_cast<wxWindow*>(pWin); 
} 
cFrameFocusEvent::~cFrameFocusEvent(void) 
{ 
} 
wxEvent* cFrameFocusEvent::Clone(void)const{ 
    return new cFrameFocusEvent(*this); 
} 
wxWindow* cFrameFocusEvent::GetWindow(void)const{ 
    return m_frame; 
} 

子框架試圖甚至派:

cFrameFocusEvent* pevent = new cFrameFocusEvent(evtFRAME_FOCUS,GetId(),this); 
wxQueueEvent(GetParent(),pevent); 

注:我已經偶然發現了這個問題wxWidgets 2.9 custom events,但它並沒有幫助我。

+1

我想你需要從'wxCommandEvent'派生出來。 – Simple

回答

3

您需要閱讀event propagation overview以瞭解wxWidgets中的事件是如何工作的。特別是,它會告訴你,只有從wxCommandEvent派生的事件默認向上傳播,對於其他的你需要調用ResumePropagation(N)來使它們傳播N級別(當然也可以是INT_MAX,使它們無限制地傳播)。

+0

感謝您的快速響應。我現在通過從wxCommandEvent派生它來嘗試它(因爲它在默認情況下向上傳播)。可悲的是它仍然不起作用 –

+0

你沒有顯示處理事件的代碼,所以我的猜測是問題出在那裏。我建議你看一下包含在wxWidgets發行版中的事件示例,它展示瞭如何定義和發送並捕獲簡單的自定義命令事件,上面的代碼對我來說看起來很奇怪。 –

+0

其實錯誤在於我提供的代碼。我將在下面發佈你的答案 –

1

在對wxWidgets代碼進行了一些深入的調試和研究之後,我發現了它。 問題在於,對於每個包含文件「cFrameFocus.h」的wxEventTypeTag都會改變(它的id),這意味着當它包含在文件中以連接到此事件類型ID時,ID爲「x」並且在發佈此事件的其他文件中,事件類型的ID爲「y」。 對此的解決方案不是傳播的問題(因爲它無論如何發送到0級,它應該被處理),而不是一個「編程錯誤」。

**cFrameFocus.h** 
extern const wxEventTypeTag<cFrameFocusEvent> evtFRAME_FOCUS; 

**cFrameFocus.cpp** 
const wxEventTypeTag<cFrameFocusEvent> evtFRAME_FOCUS(wxNewEventType()); 

此代碼改變固定在錯誤

EDIT

如VZ評價所提到的,它更適合於使用宏,而不是直接訪問功能。

適當溶液:

***cFrameFocus.h*** 

wxDECLARE_EVENT(evtFRAME_FOCUS,cFrameFocusEvent);

***cFrameFocus.cpp*** 
wxDEFINE_EVENT(evtFRAME_FOCUS,cFrameFocusEvent); 
+1

這就是爲什麼你應該使用'wxDECLARE_EVENT(evtFRAME_FOCUS,cFrameFocusEvent)'和'wxDEFINE_EVENT(evtFRAME_FOCUS,cFrameFocusEvent)'宏而不是手動執行它。它們不僅將你與事件類型內部未來可能發生的任何變化隔離開來,而且還清楚地表明只能在頭文件(它是聲明)和源文件中使用另一個(它是一個定義)。 –

+0

我也嘗試過使用宏,但它並沒有改變這種情況。就像在文件中所述。直到現在唯一的區別是示例實現在一個文件中(所有這些,從wxApp到其他所有文件),而我的不是。它似乎沒有「extern」聲明,它將無法工作,如果文件不止一次被包含在內 –

+1

但是'extern' **在宏內部是**,這就是整個點。 –