|
|
  |
Вложенное определение типов |
|
|
|
Mar 18 2006, 19:53
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(zheka @ Mar 18 2006, 21:49)  А вообще все получилось. Уже лазию по менюшке, как в сотовом телефоне. ПРоблема пока только одна - как лезть по дереву обратно, т.е. как определять родителя. Можно конечно решить как и в случае с количеством элементов в массиве - вручную прописывать. Сделать список двухсвязным. Т.е. чтобы submenu хранил также указатель на родиетеля(владельца). struct TMenuItem{ char *title; int type; int count; struct TMenuItem *submenu; struct TMenuItem *parent;} ; Цитата Слышу иронию... Есть более рациональное решение? Когда кажется - креститься надо...
Сообщение отредактировал defunct - Mar 18 2006, 19:55
|
|
|
|
|
Mar 19 2006, 08:50
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Код typedef __flash struct _TMenuItem { char title[16]; int type; __flash struct _TMenuItem *parent; __flash struct _TMenuItem *submenu; } TMenuItem;
TMenuItem __flash Options[2]= { {"Option 1", 1, MainMenu , NULL}, {"Option 2", 1, MainMenu , NULL} }; TMenuItem __flash Channels[2]= { {"Channel 1", 1, MainMenu , NULL}, {"Channel 2", 1, MainMenu , NULL} };
TMenuItem __flash MainMenu[2]= { {"Options", 1, NULL , Options}, {"Channels", 1, NULL ,Channels} }; Бред получается. Как ни располагаю менюшки - всегда будет ошибка undefined symbol. Понятно что при указании идентификатора, он уже должен быть описан ранее. Да и потом - по несколько раз повторять "MainMenu" как указатель на родителя внутри самого родителя - избыточно и нерационально. Но это не в упрек и не в качестве вопроса - я знаю как переделать структуру. ОДнако и в моем решении я также столкнулся с вышеописанной проблемой - undefined symbol. Цитата Когда кажется - креститься надо... Я атеист, мне это не поможет :D
Сообщение отредактировал zheka - Mar 19 2006, 08:54
|
|
|
|
|
Mar 19 2006, 11:25
|

Профессионал
    
Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380

|
Делаешь вот так: TMenuItem __flash Channels[2]= { {"Channel 1", 1, NULL, &MainMenu[1] }, {"Channel 2", 1, &MainMenu[0], NULL} }; это позволяет крутиться по итемам одного уровня далее делаешь массив указателей на менюитем, с размером на глубинe вложенности меню. делаешь индекс для этого массива. при активации пункта меню сохраняешь указатель в массиве и сдвигаешь индекс вперед, при возврате сдвигаешь индекс назад или сразу обнуляешь для возврата в главное меню. Для отображения пользуешься ессно указателем лежащим по текущему индексу.
Сообщение отредактировал beer_warrior - Mar 19 2006, 11:27
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Mar 19 2006, 12:03
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Господи, аж неудобно... заставил людей отвелчься от работы и писать программу. Но и я тоже не сидел сложа руки. Пока я буду вникать в ваш код, выложу свой. Мне интересна ваша критика. Код typedef __flash struct _TMenuItem { char title[16]; int type; __flash struct _TMenuItem *parent; __flash struct _TMenuItem *submenu; } TMenuItem;
extern TMenuItem __flash MainMenu[]; extern TMenuItem __flash Search[]; extern TMenuItem __flash Options[]; extern TMenuItem __flash Channels[];
TMenuItem __flash Search[]= { {"Íà÷àòü", 1, MainMenu, NULL}, {"Êîí÷èòü", 1, MainMenu, NULL}, {"Âûéòè", 1, MainMenu, NULL} };
TMenuItem __flash Sub1[]= { {"Sub1 A", 1, Options, NULL}, {"Sub1 B", 1, Options, NULL}, {"Sub1 C", 1, Options, NULL} };
TMenuItem __flash Sub2[]= { {"Sub2 A", 1, Options, NULL}, {"Sub2 B", 1, Options, NULL}, {"Sub2 C", 1, Options, NULL} };
TMenuItem __flash Sub3[]= { {"Sub3 A", 1, Options, NULL}, {"Sub3 B", 1, Options, NULL}, {"Sub3 C", 1, Options, NULL} };
TMenuItem __flash Options[]= { {"Option 1", 1, MainMenu, Sub1}, {"Option 2", 1, MainMenu, Sub2}, {"Option 3", 1, MainMenu, Sub3} };
TMenuItem __flash Channels[]= { {"Channel 1", 1, MainMenu, NULL}, {"Channel 2", 1, MainMenu, NULL}, {"Channel 3", 1, MainMenu, NULL} };
TMenuItem __flash MainMenu[]= { {"Ïîèñê", 1, NULL , Search}, {"Êàíàëû", 1, NULL , Channels}, {"Íàñòðîéêè", 1, NULL , Options} };
////////////////////////////////////////
void EnterMenuItem(TMenuItem __flash *point_to_menu) { int i; char *s=r; LcdClear(); for (i=0;i<3;i++) { LcdGotoXY(2,i+1); sprintf(s,"%p", point_to_menu[i].title); LcdStr(FONT_1X, s, NORMAL); } LcdUpdate(); }
void main () { int i,j, selection_pos, submenu_n; char *s=r; TMenuItem __flash *current_point; DDRD=0x00; PORTD=0xFF; LcdInit(); Delay();
current_point=MainMenu; EnterMenuItem(current_point); selection_pos=0; LcdSelect(selection_pos); LcdUpdate();
for(;;) {
if (!PIND.0) { LcdSelect(selection_pos); selection_pos++; LcdSelect(selection_pos); } if (!PIND.1) { LcdSelect(selection_pos); selection_pos--; LcdSelect(selection_pos); }
if (!PIND.2) { if (current_point[selection_pos].submenu==NULL) continue; current_point=current_point[selection_pos].submenu; EnterMenuItem(current_point); selection_pos=0; LcdSelect(selection_pos);
}
if (!PIND.3) { if (current_point[selection_pos].parent==NULL) continue; current_point=current_point[selection_pos].parent; EnterMenuItem(current_point); selection_pos=0; LcdSelect(selection_pos); }
LcdUpdate();
} Цитата при активации пункта меню сохраняешь указатель в массиве и сдвигаешь индекс вперед, при возврате сдвигаешь индекс назад или сразу обнуляешь для возврата в главное меню. Нравится твоя идея, но! Вспомним windows-проводник. В нем есть две кнопки - "Вверх" и "Назад". Так вот твой вариант это как раз кнопка "Назад". Вариант "Вверх" логичней и в принципе, то что я сделал, работает. Ладно, пойду искать следующие грабли.
|
|
|
|
|
Mar 19 2006, 12:08
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
ЗЫ, я свой выложу чуть позже еще раз после того как проверю полностью. Пока что удалил. Вот обещанный пример (проверенный): Код #define uchar unsigned char #define schar signed char
typedef __flash struct { char title[16]; schar Layer; } TListItem;
TListItem __flash BunchOfStrings[]= { {"Options", 0}, {"Option 1",1}, {"SubOption1 1", 2}, {"Option 2", 1}, {"SubOption2 1", 2}, {"SubOption2 2", 2}, {"SubOption2 3", 2}, {"Channels", 0}, {"Channel 1", 1}, {"Channel 2", 1} // ,{"", -1} // Dummy item для отладки. }; #define MAX_LAYER 3 // Последний уровень субменю
#define mdMoveUp -1 // Движение по меню "вверх" #define mdMoveDown 1 // Движение по меню "вниз" #define mdMoveLeft -2 // Движение по меню в рамках одного слоя влево (пред. пункт) #define mdMoveRight 2 // Движение по меню в рамках одного слоя вправо (следующий пункт) #define ItemCount sizeof(BunchOfStrings)/sizeof(TListItem)
TListItem __flash *GetNextMenuItem(schar MoveDirection) { static uchar CurrentPos = 0; // Текущая позиция в слое schar CurrentLayer; // Текущий слой uchar TempPos;
uchar searchleft(uchar pos, schar layer); uchar searchright(uchar pos, schar layer);
CurrentLayer = BunchOfStrings[CurrentPos].Layer; switch (MoveDirection) { case mdMoveUp: { if ((CurrentLayer > 0)&&(CurrentPos > 0)) { CurrentLayer--; while (!CurrentPos--){ if (BunchOfStrings[CurrentPos].Layer == CurrentLayer) break; } } else{ CurrentPos = 0; } break; }; case mdMoveDown: { if ((CurrentLayer < MAX_LAYER)&&(CurrentPos < ItemCount-1)){ if (BunchOfStrings[CurrentPos +1].Layer > CurrentLayer) { CurrentLayer++; CurrentPos++; } } break; }; case mdMoveLeft: { TempPos = searchright(CurrentPos, CurrentLayer); if (BunchOfStrings[TempPos].Layer != CurrentLayer) TempPos = searchleft(CurrentPos, CurrentLayer); if (BunchOfStrings[TempPos].Layer == CurrentLayer) CurrentPos = TempPos; break; } case mdMoveRight: { TempPos = searchleft(CurrentPos, CurrentLayer); if (BunchOfStrings[TempPos].Layer != CurrentLayer) TempPos = searchright(CurrentPos, CurrentLayer); if (BunchOfStrings[TempPos].Layer == CurrentLayer) CurrentPos = TempPos; break; } default: CurrentPos = 0; } return &BunchOfStrings[CurrentPos];
}
uchar searchleft(uchar pos, schar layer) { uchar i; i = ++pos; while ((i > 0) && (BunchOfStrings[i].Layer > layer)) i++; return i; }
uchar searchright(uchar pos, schar layer) { uchar i; i = --pos; while ((i < ItemCount) && (BunchOfStrings[i].Layer > layer)) i--; return i; } Пример применения: Код int main( void ) { char __flash *c; TListItem __flash *ListItem; // Изначально находимся в меню Options.. ListItem = GetNextMenuItem( mdMoveDown ); // Здесь навелись на Option 1 ListItem = GetNextMenuItem( mdMoveRight ); // Здесь навелись на Option 2 ListItem = GetNextMenuItem( mdMoveDown ); // Здесь навелись на SubOption2_1 ListItem = GetNextMenuItem( mdMoveRight ); // Здесь навелись на SubOption2_2 ListItem = GetNextMenuItem( mdMoveRight ); // Здесь навелись на SubOption2_3 ListItem = GetNextMenuItem( mdMoveRight ); // Здесь навелись на SubOption2_1
ListItem = GetNextMenuItem( mdMoveUp ); ListItem = GetNextMenuItem( mdMoveUp ); ListItem = GetNextMenuItem( mdMoveUp );
ListItem = GetNextMenuItem( mdMoveRight ); ListItem = GetNextMenuItem( mdMoveDown ); ListItem = GetNextMenuItem( mdMoveLeft ); c = ListItem -> title; // Здесь в "c" находится "Channel 2" ....
Сообщение отредактировал defunct - Mar 19 2006, 13:48
|
|
|
|
|
Mar 19 2006, 12:10
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Да, кстати - по поводу предыдущей проблемы - с sizeof - ну задал я размерность массива - и толку :
sprintf(s,"%d", sizeof(MainMenu)); LcdStr(FONT_1X, s, NORMAL);
- показывает большие числа - 22 в частности при размере 3,
sprintf(s,"%d", sizeof(MainMenu[])) - компилятор обзывает инвалидом детства...
Сообщение отредактировал zheka - Mar 19 2006, 12:11
|
|
|
|
|
Mar 19 2006, 13:06
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Господа! Еще вам загадка: Вот из Codevision Example по EEPROM: Код // EEPROM access example
// CodeVisionAVR C Compiler // (C) 2000-2002 HP InfoTech S.R.L. // www.hpinfotech.ro
// Chip: AT90S2313 // Memory Model: TINY // Data Stack Size: 64 bytes
flash char f[]="This is a test"; #pragma warn- eeprom char e[16]; #pragma warn+ char r[16];
void main (void) { char flash *ptr_to_flash; char eeprom *ptr_to_eeprom; char *ptr_to_ram;
// copy the string f from FLASH to // the string e in EEPROM ptr_to_flash=f; ptr_to_eeprom=e; while (*ptr_to_flash) *ptr_to_eeprom++=*ptr_to_flash++;
// copy the string e from EEPROM to // the string r in RAM ptr_to_eeprom=e; ptr_to_ram=r; while (*ptr_to_eeprom) *ptr_to_ram++=*ptr_to_eeprom++;
// stop here while (1); } В общем не выводит ничего... В моей программе часть кода Код while (*ptr_to_flash) *ptr_to_eeprom++=*ptr_to_flash++; была заменена на Код i=0; while (*ptr_to_flash) { *ptr_to_eeprom++=*ptr_to_flash++; LcdLine(0,i*5,80,i*5); i++; } Ну и чтение из EEPROM соответственно модифицировано. Линии там - типа таблицы, оказались очень полезны для отладки. При записи в EEPROM их было столько, сколько символов в записываемой строке. При чтении - рисование таблицы длилось долго-долго, после чего то ли у Меги, то ли у индикатора съезжала крыша... Найдите ошибку... ПОчему ptrt_to_eeprom указывает на что-то очень длинное..
|
|
|
|
|
Mar 19 2006, 14:56
|

Знающий
   
Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768

|
zheka ты продолжаешь хамить,правда уже в косвенной форме. Человек практически написал за тебя код решения вопроса,заданного в посте.С проверкой это не 5 минут времени,а значительно больше  .Ты не словом не поблагодарив,как будто не заметив,ми- ло разворачиваешь обсуждение на 180 градусов и задаеш вопрос совсем из другой оперы Ты черезмерно используешь мягкость людей,здесь собравшихся.Еще раз повторю,в большинстве других форумов ты уже или получил бы бан в лоб,или тема была бы на помойке.Которой здесь,кстати, нет,что говорит о безумной либеральности форума к радости таких как ты. Тут дело уже не в С-учись банальной вежливости и правилам общения интеллигентных людей
--------------------
"Hello, word!" - 17 errors 56 warnings
|
|
|
|
|
Mar 19 2006, 15:16
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Уважаемый WHALE!!! Цитата Человек практически написал за тебя код решения вопроса,заданного в посте Смотрим время редактирования этого поста. То есть время, когда код там появился. Цитата Ты не словом не поблагодарив,как будто не заметив,ми- ло разворачиваешь обсуждение на 180 градусов и задаеш вопрос совсем из другой оперы Смотрим время оставления поста №22, на который вы намекаете. Делаем выводы, об обоснованности данной претензии. Я безумно благодарен этим людям. К сожалению не могу отвечать спасибо на каждый пост, пока задача еще не решена. Цитата Тут дело уже не в С-учись банальной вежливости и правилам общения интеллигентных людей Некоторые из которых пойманы на невнимательности, влекущей за собой необоснованные претензии в мой адрес. Нет, я не отрицаю, что я нетерпелив, иногда лень разобраться прежде чем задавать вопросы другим. Но факты есть факты - искаженное цитирование моих сообщений, последнее ваше обвинение в хамстве. Defunct, Whale все-таки прав, хотя бы один раз я должен Вас поблагодарить за трату Вашего времени на меня. Да и я, кажется уже восхищался этим ранее.
Сообщение отредактировал zheka - Mar 19 2006, 15:18
|
|
|
|
|
Mar 19 2006, 15:38
|

Знающий
   
Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768

|
zheka тьфу,начал писать,получил от тебя РМ.Ладно,я тут вообще не причем, defunct делал за тебя работу в хорошем стиле.Во всяком случае я рад,что ты не безнадежен  Но извини,тебе несколько разных людей делали одинаковые замечания по стиою твоему общения,да и программинга тоже.Ты поблагодарил человека? И так не делается,в одной ветке задавать вопросы,абсолютно не связанные с темой.К тому-же извини, твой последний вопрос уж совсем никакой  В приведенном тобой маленьком кусочке вроде все правильно.И опять те-же вопросы:ты правильно инициировал указатели?И в который раз,насколько я понимаю,свежеоткомпилированный код ты сразу заливаешь в камень и ждешь,сработает ли.Ответь,по- жалуйста,ради бога,ну почему ты не пользуешься отладчиком?!
--------------------
"Hello, word!" - 17 errors 56 warnings
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|