Quando falei sobre o mapa de mensagens (aqui), eu adicionei quatro mapeamentos. Entretanto, todos eles eram do mesmo tipo e chamavam a mesma acao; vejam:FXMAPFUNC(SEL_COMMAND, FoxTutorialMainWindow::ID_INFORMATION, FoxTutorialMainWindow::onCmdMessage),FXMAPFUNC(SEL_COMMAND, FoxTutorialMainWindow::ID_QUESTION, FoxTutorialMainWindow::onCmdMessage),FXMAPFUNC(SEL_COMMAND, FoxTutorialMainWindow::ID_WARNING, FoxTutorialMainWindow::onCmdMessage),FXMAPFUNC(SEL_COMMAND, FoxTutorialMainWindow::ID_ERROR, FoxTutorialMainWindow::onCmdMessage),Uma situacao dessas ocorre quando eu tenho varias acoes muito semelhantes: em vez de definir um callback para cada acao, eu defino apenas um; a diferenca entre eles e feita dentro do corpo da funcao.O FOX Toolkit fornece uma macro auxiliar para facilitar essa tarefa: FXMAPFUNCS. Neste topico, explicarei como usa-la.Definindo uma acao para varios IDsDiante de uma situacao dessas, seria bem mais facil se eu pudesse diminuir o numero de linhas a serem escritas. A proposito, o FOX Toolkit tem um slogan que diz: "Cada linha de codigo nao escrita e uma linha correta". Pense no caso de uma calculadora: cada botao executa uma acao bem semelhante um ao outro: adicionar o seu valor a expressao e atualizar a caixa de texto que a exibe.Imagina se eu tivesse que escrever uma funcao para cada botao? Seriam 10 botoes de digitos + 5 operacoes (contanto com a igualdade), isso apenas para uma calculadora basica. 15 funcoes, 15 entradas no mapa.Para facilitar, pode-se definir apenas uma funcao e liga-las todas aos botoes da calculadora. E para evitar as quinze entradas no mapa, utiliza-se a macro FXMAPFUNCS. Para nao ficar macante, e reaproveitar os codigos ja escritos, vou voltar ao exemplo do tutorial sobre as mensagens exibidas ao usuario.Declarando as mensagensPara poder utilizar a macro FXMAPFUNCS, e necessario que os IDs das mensagens sejam declarados sequencialmente. Isso porque a macro pega um intervalo de IDs. No nosso exemplo:enum { ID_INFORMATION = FXMainWindow::ID_LAST, ID_QUESTION, ID_WARNING, ID_ERROR, ID_LAST,};Com isso, basta usar a macro magica. A sintaxe dela e:FXMAPFUNCS(tipo, ID_min, ID_max, callback)No nosso exemplo, o mapa de mensagens fica assim:FXDEFMAP(FoxTutorialMainWindow) FoxTutorialMainWindowMap[] = { FXMAPFUNCS(SEL_COMMAND, FoxTutorialMainWindow::ID_INFORMATION, FoxTutorialMainWindow::ID_ERROR, FoxTutorialMainWindow::onCmdMessage),};Ou seja, com apenas uma chamada, eu defini a mesma acao para quatro mensagens diferentes.Diferenciando as mensagensJa que cada evento vai disparar a mesma acao, e preciso diferenciar os diferentes eventos. Todo callback no FOX Toolkit tem o mesmo formato (com os nomes tipicos dos parametros):long onAction(FXObject *sender, FXSelector sel, void *ptr);Neste caso, o que mais importa e o segundo parametro (sempre que um parametro nao for utilizado, pode permanecer anonimo). Um FXSelector nada mais e que uma mistura entre o tipo de mensagem e o ID da mensagem. Essa mistura e feita automaticamente pela macro FXSEL ao se acrescentar uma entrada no mapa. Apenas adiantando uma informacao, essa macro tambem e utilizada ao se delegar acoes; falarei sobre isso no futuro.Ja que o FOX junta essas duas informacoes, ele pode separa-las: FXSELID recupera o ID da mensagem, e FXSELTYPE recupera o tipo da mensagem. Sendo assim, fica facil saber quem enviou a mensagem, sem precisar recorrer a ponteiros (como normalmente acontece com uma certa linguagem que dizem nao ter ponteiros). Um teste switch resolve o caso:long FoxTutorialMainWindow::onCmdMessage( FXObject*, FXSelector sel, void*) { switch (FXSELID(sel)) { case ID_INFORMATION: FXMessageBox::information(this, MBOX_OK, "Informacao", "Operacao finalizada"); break; case ID_QUESTION: FXMessageBox::question(this, MBOX_YES_NO, "Sair", "Deseja realmente sair do programa?"); break; case ID_WARNING: FXMessageBox::warning(this, MBOX_OK,