Я в своё время написал кодгенератор. Стркуктура меню описана в текстовом файле вида:
CMenuItem menuChnl1("Канал 1") { CMenuTuner menuTun1(&tun1) { CMenuTunerFreq menuFrq1(&(tun1.Params()->nFreq)); CMenuTunerSr menuSr1 (&(tun1.Params()->nSr)); CMenuTunerMode menuS21 (&(tun1.Params()->nMode)); CMenuTunerPol menuPol1(&(tun1.Params()->nPol)); CMenuLnb menuLNB1() { CMenuLnbType menuLnbt1(); CMenuLnbLHet menuLHet1(&(tun1.Params()->nLnbLHet)); CMenuLnbHHet menuHHet1(&(tun1.Params()->nLnbHHet)); CMenuLnbSf menuSf1 (&(tun1.Params()->nLnbSf)); CMenuLnb22KHz menu22k1 (&(tun1.Params()->nLnbNo22KHz)); } } CMenuItem menuCam1("КАМ") { CMenuCam menuCamSt1(&cam1); } } CMenuItem menuChnl2("Канал 2") { CMenuTuner menuTun2(&tun2) { CMenuTunerFreq menuFrq2(&(tun2.Params()->nFreq)); CMenuTunerSr menuSr2 (&(tun2.Params()->nSr)); CMenuTunerMode menuS22 (&(tun2.Params()->nMode)); CMenuTunerPol menuPol2(&(tun2.Params()->nPol)); CMenuLnb menuLNB2() { CMenuLnbType menuLnbt2(); CMenuLnbLHet menuLHet2(&(tun2.Params()->nLnbLHet)); CMenuLnbHHet menuHHet2(&(tun2.Params()->nLnbHHet)); CMenuLnbSf menuSf2 (&(tun2.Params()->nLnbSf)); CMenuLnb22KHz menu22k2 (&(tun2.Params()->nLnbNo22KHz)); } } CMenuItem menuCam2("КАМ") { CMenuCam menuCamSt2(&cam2); } } CMenuItem menuIp("Настройки IP"){ CMenuItem menuIpAddr("Адрес") { CMenuIpEdit menuIpAddrE(pVarBoardInfo->ipaddr); } CMenuItem menuIpMask("Маска подсети") { CMenuIpEdit menuIpMaskE(pVarBoardInfo->ipmask); } CMenuItem menuIpGtw("Шлюз") { CMenuIpEdit menuIpGtwE(pVarBoardInfo->ipgate); } } CMenuItem menuService("Сервис") { CMenuInfo menuInfo(); CMenuContrast menuContrast(); CMenuItem menuResetEntry("Сброс к заводским") { CMenuReset menuReset(); } }В процессе трансляции проекта кодгенератор генерит из него .cpp и .h с прототипами структур, ссылающимися друг на друга структурами и конструкторами классов.
.... extern MENUCONST MENUNAVSTRUCT mns_menuIpGtwE; extern MENUCONST MENUNAVSTRUCT mns_menuService; extern MENUCONST MENUNAVSTRUCT mns_menuInfo; extern MENUCONST MENUNAVSTRUCT mns_menuContrast; extern MENUCONST MENUNAVSTRUCT mns_menuResetEntry; extern MENUCONST MENUNAVSTRUCT mns_menuReset; .... MENUCONST MENUNAVSTRUCT mns_menuTop = {NULL, &mns_menuTop, &mns_menuTop, &mns_menuChnl1, &menuTop}; MENUCONST MENUNAVSTRUCT mns_menuChnl1 = {&mns_menuTop, &mns_menuService, &mns_menuChnl2, &mns_menuTun1, &menuChnl1}; MENUCONST MENUNAVSTRUCT mns_menuTun1 = {&mns_menuChnl1, &mns_menuCam1, &mns_menuCam1, &mns_menuFrq1, &menuTun1}; MENUCONST MENUNAVSTRUCT mns_menuFrq1 = {&mns_menuTun1, &mns_menuLNB1, &mns_menuSr1, NULL, &menuFrq1}; MENUCONST MENUNAVSTRUCT mns_menuSr1 = {&mns_menuTun1, &mns_menuFrq1, &mns_menuS21, NULL, &menuSr1}; MENUCONST MENUNAVSTRUCT mns_menuS21 = {&mns_menuTun1, &mns_menuSr1, &mns_menuPol1, NULL, &menuS21}; .... CMenuItem menuChnl1(&mns_menuChnl1,"Канал 1"); CMenuTuner menuTun1(&mns_menuTun1,&tun1); CMenuTunerFreq menuFrq1(&mns_menuFrq1,&(tun1.Params()->nFreq)); CMenuTunerSr menuSr1(&mns_menuSr1,&(tun1.Params()->nSr)); CMenuTunerMode menuS21(&mns_menuS21,&(tun1.Params()->nMode)); CMenuTunerPol menuPol1(&mns_menuPol1,&(tun1.Params()->nPol)); ....