long (classname::* func)(FX::FXObject*,FX::FXSelector,void*); }; static const FX::FXMetaClass metaClass; static FX::FXObject* manufacture(); virtual long handle(FX::FXObject* sender,FX::FXSelector sel,void* ptr); virtual const FX::FXMetaClass* getMetaClass() const { return &metaClass; } friend FX::FXStream& operator <<(FX::FXStream& store,const classname* obj) { return store.saveObject((FX::FXObjectPtr)(obj)); } friend FX::FXStream& operator >>(FX::FXStream& store,classname*& obj) { return store.loadObject((FX::FXObjectPtr&)(obj)); }private:Explicando:Ela cria uma struct interna, chamada FXMapEntry, que armazena as entradas do mapa de mensagens.Declara um objeto estatico do tipo FXMetaClass, que armazena informacoes que descrevem um objeto FOX.manufacture() nada mais e que um metodo fabrica que retorna um novo objeto; por isso o construtor padrao vazio privado e obrigatorio.handle() e o metodo utilizado para executar as acoes propriamente ditas e tambem utilizado para delegar acoes a outros objetos.Os demais sao irrelevantes no momento.Pois bem, a outra macro, FXIMPLEMENT, e o complementar de FXDECLARE. E ela quem vai implementar os metodos declarados por FXDECLARE. Por isso ela e obrigatoria, mesmo na ausencia do mapa de mensagens. Apos expandida, o metodo handle() e implementado da seguinte maneira:long classname::handle(FX::FXObject* sender, FX::FXSelector sel, void* ptr) { const FXMapEntry* me=(const FXMapEntry*)metaClass.search(sel); return me ? (this->* me->func)(sender,sel,ptr) : baseclassname::handle(sender,sel,ptr);}Fucando no codigo-fonte, vi que o metodo search() faz uma busca linear pelo mapa de mensagens, ate encontrar uma entrada contenha o FXSelector sel (passado como parametro de handle()). Vejam:const void* FXMetaClass::search(FXSelector key) const { register const FXObject::FXMapEntry* lst=(const FXObject::FXMapEntry*)assoc; register FXuint n=nassocs; while(n--) { if (lst->keylo <= key && key <= lst->keyhi) return lst; lst = (const FXObject::FXMapEntry*) (((const FXchar*)lst)+assocsz); } return NULL;}Ou seja, se encontrar a entrada, executa a funcao associada; senao, delega para a superclasse. Isto segue o padrao de projeto "Cadeia de Responsabilidade" ("Chain of Responsibility"), em que um objeto vai delegando a acao a seus superiores (digamos assim), ate que alguem o trate. Neste caso, o topo da hierarquia e FXObject, cujo metodo handle() chama onDefault(), que apenas retorna 0.Voltando...Depois de toda essa explicacao, podemos voltar ao nosso assunto principal. Suponhamos que temos uma janela que nao trata nenhum evento. Neste caso, existem duas opcoes: declarar um mapa vazio, ou simplesmente nao declarar mapa nenhum. A primeira opcao ja foi discutida em um dos primeiros tutoriais, mas vou reproduzi-la aqui:FXDEFMAP(FoxTutorialMainWindow) FoxTutorialMainWindowMap[] = {};FXIMPLEMENT(FoxTutorialMainWindow, FXMainWindow, FoxTutorialMainWindowMap, ARRAYNUMBER(FoxTutorialMainWindowMap))Neste caso, a macro ARRAYNUMBER calcula o tamanho do vetor, que e 0 (cuidado: alguns compiladores reclamam). Na hora da busca pela mensagem, o laco while e ignorado e a funcao retorna NULL, disparando o processo ja discutido.A outra maneira e nao declarar mapa nenhum. A chamada a FXIMPLEMENT fica assim:FXIMPLEMENT(FoxTutorialMainWindow, FXMainWindow, NULL, 0)ConclusaoAcho que este topico encerra a discussao sobre o mapa de mensagens. Se eu me lembrar de alguma outra coisa nesse sentido, postarei aqui.Entretanto, ainda ha muito o que falar com relacao ao tratamento de mensagens. Essa serie sera bem longa! Ate a proxima!