天天看点

MFC与wxWidgets比较(2)

今天我们来比较 MFC 和 wxWidgets 的最核心的代码,也就是MFC的消息映射和wxWidgets的事件表。

1.MFC 中的消息映射宏

    DECLARE_MESSAGE_MAP()

    BEGIN_MESSAGE_MAP(theClass, baseClass)

    END_MESSAGE_MAP()

展开后代码如下:

#ifdef _AFXDLL

#define DECLARE_MESSAGE_MAP() /

private: /

    static const AFX_MSGMAP_ENTRY _messageEntries[]; /

protected: /

    static AFX_DATA const AFX_MSGMAP messageMap; /

    static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); /

    virtual const AFX_MSGMAP* GetMessageMap() const; /

#else

#define DECLARE_MESSAGE_MAP() /

private: /

    static const AFX_MSGMAP_ENTRY _messageEntries[]; /

protected: /

    static AFX_DATA const AFX_MSGMAP messageMap; /

    virtual const AFX_MSGMAP* GetMessageMap() const; /

#endif

#ifdef _AFXDLL

# define BEGIN_MESSAGE_MAP(theClass, baseClass) /

    const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() /

        { return &baseClass::messageMap; } /

    const AFX_MSGMAP* theClass::GetMessageMap() const /

        { return &theClass::messageMap; } /

    AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = /

    { &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; /

    AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = /

    { /

#else

# define BEGIN_MESSAGE_MAP(theClass, baseClass) /

    const AFX_MSGMAP* theClass::GetMessageMap() const /

        { return &theClass::messageMap; } /

    AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = /

    { &baseClass::messageMap, &theClass::_messageEntries[0] }; /

    AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = /

    { /

#endif

# define END_MESSAGE_MAP() /

        {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } /

    }; /

其中 AFX_MSGMAP 和 AFX_MSGMAP_ENTRY 的声明如下:

struct AFX_MSGMAP

{

#ifdef _AFXDLL // use shared dll

    const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();

#else

    const AFX_MSGMAP* pBaseMap;

#endif

    const AFX_MSGMAP_ENTRY* lpEntries;

};

struct AFX_MSGMAP_ENTRY

{

    UINT nMessage;   // windows message

    UINT nCode;      // control code or WM_NOTIFY code

    UINT nID;        // control ID (or 0 for windows messages)

    UINT nLastID;    // used for entries specifying a range of control id's

    UINT nSig;       // signature type (action) or pointer to message #

    AFX_PMSG pfn;    // routine to call (or special value)

};

2.wxWidgets 中的事件表宏

   DECLARE_EVENT_TABLE()

   BEGIN_EVENT_TABLE(theClass, baseClass)

   END_EVENT_TABLE()

展开后代码如下:

#define DECLARE_EVENT_TABLE() /

    private: /

        static const wxEventTableEntry sm_eventTableEntries[]; /

    protected: /

        static const wxEventTable        sm_eventTable; /

        virtual const wxEventTable*      GetEventTable() const; /

        static wxEventHashTable          sm_eventHashTable; /

        virtual wxEventHashTable&        GetEventHashTable() const;

#define BEGIN_EVENT_TABLE(theClass, baseClass) /

    const wxEventTable theClass::sm_eventTable = /

        { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; /

    const wxEventTable *theClass::GetEventTable() const /

        { return &theClass::sm_eventTable; } /

    wxEventHashTable theClass::sm_eventHashTable(theClass::sm_eventTable); /

    wxEventHashTable &theClass::GetEventHashTable() const /

        { return theClass::sm_eventHashTable; } /

    const wxEventTableEntry theClass::sm_eventTableEntries[] = { /

#define END_EVENT_TABLE() DECLARE_EVENT_TABLE_ENTRY( wxEVT_NULL, 0, 0, 0, 0 ) };

struct WXDLLIMPEXP_BASE wxEventTable

{

    const wxEventTable *baseTable;    // base event table (next in chain)

    const wxEventTableEntry *entries; // bottom of entry array

};

class WXDLLIMPEXP_BASE wxEventHashTable

{

private:

    // Internal data structs

    struct EventTypeTable

    {

        wxEventType                   eventType;

        wxEventTableEntryPointerArray eventEntryTable;

    };

    typedef EventTypeTable* EventTypeTablePointer;

public:

    // Constructor, needs the event table it needs to hash later on.

    // Note: hashing of the event table is not done in the constructor as it

    //       can be that the event table is not yet full initialize, the hash

    //       will gets initialized when handling the first event look-up request.

    wxEventHashTable(const wxEventTable &table);

    // Destructor.

    ~wxEventHashTable();

    // Handle the given event, in other words search the event table hash

    // and call self->ProcessEvent() if a match was found.

    bool HandleEvent(wxEvent &event, wxEvtHandler *self);

    // Clear table

    void Clear();

    // Clear all tables

    static void ClearAll();

    // Rebuild all tables

    static void ReconstructAll();

protected:

    // Init the hash table with the entries of the static event table.

    void InitHashTable();

    // Helper funtion of InitHashTable() to insert 1 entry into the hash table.

    void AddEntry(const wxEventTableEntry &entry);

    // Allocate and init with null pointers the base hash table.

    void AllocEventTypeTable(size_t size);

    // Grow the hash table in size and transfer all items currently

    // in the table to the correct location in the new table.

    void GrowEventTypeTable();

protected:

    const wxEventTable    &m_table;

    bool                   m_rebuildHash;

    size_t                 m_size;

    EventTypeTablePointer *m_eventTypeTable;

    static wxEventHashTable* sm_first;

    wxEventHashTable* m_previous;

    wxEventHashTable* m_next;

    DECLARE_NO_COPY_CLASS(wxEventHashTable)

};

继续阅读