Урок: создаём GUI, часть 1 : Эльфостроение : Форум |
arban: |
22.02.09, 22:00 |
Урок: создаём графический интерфейс (GUI). Надеюсь, вы уже скачали и установили svn-клиент TortoiseSVN, компилятор Embedded Workbench 4.0 Evaluation (IAR) и слили в папку свн по адресу svn://svn.boba.su/SE. Если это еще не сделали то вперёд Наша задача - создать меню со списком элементов, притом задать им имя и действие. Начнем... 1. Заходим в папку со слитым репозиторием (далее буду называть это слитой свн), копируем и переименовываем папку HelloWorld в любую другую, например GUI_Example. В папке видим файлы: HelloWorld.eww, main.c, main.ewp и скрытую папку .svn (её можно удалить, но не обязательно, конечно если вы не имеете собственного свн). 2. Открываем файл HelloWorld.eww. Слева ищем слово Debug, жмем на стрелку правее и выбираем Release. Убираем всё лишнее и получаем такой код: Код: #include "..\\\\include\\Lib_Clara.h" #include "..\\\\include\\Dir.h" BOOK * HWBook; int TerminateElf(void * ,BOOK* book) { FreeBook(book); return(1); } typedef struct { BOOK * book; }MSG; int ShowAuthorInfo(void *mess ,BOOK* book) { MSG * msg = (MSG*)mess; MessageBox(0x6fFFFFFF,STR("Hello Wordl!\\n\\nExample elf.."),0, 1 ,5000,msg->book); return(1); } const PAGE_MSG HW_PageEvents[]@ "DYN_PAGE" ={ ELF_TERMINATE_EVENT , TerminateElf, ELF_SHOW_INFO_EVENT , ShowAuthorInfo, 0,0 }; PAGE_DESC base_page ={"HW_BasePage",0,HW_PageEvents}; void elf_exit(void) { kill_data(&ELF_BEGIN, (void(*)(void*))mfree_adr()); } void onCloseHWBook(BOOK * book) { if (book) { SUBPROC(elf_exit); } } BOOK * CreateHWBook() { HWBook= new BOOK; CreateBook(HWBook,onCloseHWBook,&base_page,"Example",-1,0); return(HWBook); } int main (void) { CreateHWBook(); return(0); } Этот код также можно сохранить как основу для других эльфов. Данный код запускает эльф и создаёт для него книгу (далее бук, BOOK). Теперь нам надо создать заголовочный файл (далее модуль), который и будет отвечать за GUI (далее гуи). 3. В папке с нашим проектом создаём файлы gui.c и gui.h. В IAR'е (далее йаре, йар) слева, на панельке щелкаем правой кнопкой мыши и выбираем Add->Add Files..., выбираем файл gui.c. Затем выбираем его (в панельке слева). Видим пустое окно. Вписываем в него следующий код: Код: #include "..\\\\include\\Lib_Clara.h" #include "..\\\\include\\Dir.h" #include "gui.h" #define GUI_NAME L"Example" void GuiBack(BOOK *bk, void *lt) { FreeBook((BOOK*)myBook); } void GuiOnEnterPressed(BOOK *bk, void *lt) { int item=ListMenu_GetSelectedItem(myBook->gui); if(item==0) { MessageBox(0x6fFFFFFF,STR("Элемент 1"),0, 1 ,5000,0); } if(item==1) { MessageBox(0x6fFFFFFF,STR("Элемент 2"),0, 1 ,5000,0); } } int GuiOnLBMessage(GUI_MESSAGE * msg) { int item; switch(msg->msg) { case 1: item=GUIonMessage_GetCreatedItemIndex(msg); if(item==0) SetMenuItemText0(msg,Str2ID(L"Элемент 1",0,SID_ANY_LEN)); if(item==1) SetMenuItemText0(msg,Str2ID(L"Элемент 2",0,SID_ANY_LEN)); } return(1); }; void GuiCreateGuiList(void * r0, BOOK * bk) { myBook->gui=CreateListObject(bk,0); GuiObject_SetTitleText(myBook->gui,Str2ID(GUI_NAME,0,SID_ANY_LEN)); SetNumOfMenuItem(myBook->gui,2); OneOfMany_SetonMessage((GUI_ONEOFMANY*)myBook->gui,GuiOnLBMessage); SetCursorToItem(myBook->gui,0); SetMenuItemStyle(myBook->gui,0); GUIObject_Softkey_SetAction(myBook->gui,ACTION_BACK, GuiBack); GUIObject_Softkey_SetAction(myBook->gui,ACTION_LONG_BACK, GuiBack); GUIObject_Softkey_SetAction(myBook->gui,ACTION_SELECT1,GuiOnEnterPressed); ShowWindow(myBook->gui); }; А теперь опишу код: Функция void GuiCreateGuiList(void * r0, BOOK * bk) отвечает за само создание меню. Сначала присвоем структуре myBook->gui (о ней мы поговорим позже) указатель на меню-список. Затем функцией GuiObject_SetTitleText(myBook->gui,Str2ID(GUI_NAME,0,SID_ANY_LEN)) установим заголовок меню, его мы задали в константе GUI_NAME. Потом устанавливаем кол-во пунктов(SetNumOfMenuItem(myBook->gui,2);), названия пунктов (OneOfMany_SetonMessage((GUI_ONEOFMANY*)myBook->gui,GuiOnLBMessage);), установим курсор на первый пункт(SetCursorToItem(myBook->gui,0);), установим стиль меню (SetMenuItemStyle(myBook->gui,0);), посмотреть какие стили существуют можно по сслылке http://supertrubka.org/wiki/doku.php?id=elflib:functions:setmenuitemstyle. А теперь зададим действия для софт-клавиш: Код: //описание функций GuiBack и GuiOnEnterPressed мы рассмотрим чуть позже //при коротком и длинном нажатии на клавишу Назад GUIObject_Softkey_SetAction(myBook->gui,ACTION_BACK, GuiBack); GUIObject_Softkey_SetAction(myBook->gui,ACTION_LONG_BACK, GuiBack); //при выборе GUIObject_Softkey_SetAction(myBook->gui,ACTION_SELECT1,GuiOnEnterPressed); И, наконец, покажем наше меню (ShowWindow(myBook->gui);). Функция: Код: void GuiBack(BOOK *bk, void *lt) { FreeBook((BOOK*)myBook); } отвечает за выход из нашей меню, в ней мы освобождаем созданный нами бук (FreeBook((BOOK*)myBook);). Вместе с буком у нас удалиться и наш гуи. Функция: Код: void GuiOnEnterPressed(BOOK *bk, void *lt) { int item=ListMenu_GetSelectedItem(myBook->gui); if(item==0) { MessageBox(0x6fFFFFFF,STR("Элемент 1"),0, 1 ,5000,0); } if(item==1) { MessageBox(0x6fFFFFFF,STR("Элемент 2"),0, 1 ,5000,0); } } отвечает за действие при выборе пункта. Сначала мы функцией ListMenu_GetSelectedItem(myBook->gui) присваиваем переменной item значение текущего выбранного пункта, потом проверяем какой пункт у нас выбран и совершаем действие, в нашем случае выводим сообщение. Функция: Код: int GuiOnLBMessage(GUI_MESSAGE * msg) { int item; switch(msg->msg) { case 1: item=GUIonMessage_GetCreatedItemIndex(msg); if(item==0) SetMenuItemText0(msg,Str2ID(L"Элемент 1",0,SID_ANY_LEN)); if(item==1) SetMenuItemText0(msg,Str2ID(L"Элемент 2",0,SID_ANY_LEN)); } return(1); }; задаёт пунктам имена, работает почти также как и GuiOnEnterPressed, так что подробно расписывать здесь, думаю не надо. 4. Теперь нам надо запустить это дело. Выбираем в панеле файл main.c и создаём структуру: Код: typedef struct { BOOK book; GUI_LIST*gui; }MyBOOK; MyBOOK*myBook; заместо BOOK * HWBook, где book содержит нашу книгу, а gui указатель на гуи. Его то мы и использовали в нашей менюшке. Теперь необходимо исправить функцию: Код: BOOK * CreateHWBook() { HWBook= new BOOK; CreateBook(HWBook,onCloseHWBook,&base_page,"Example",-1,0); return(HWBook); } меняем на: Код: MyBOOK * CreateHWBook() { myBook= new MyBOOK; CreateBook(myBook,onCloseHWBook,&base_page,"Example",-1,0); return(myBook); } Почти готово. Далее открываем файл gui.h и вписываем в него: Код: typedef struct { BOOK book; GUI_LIST*gui; }MyBOOK; extern MyBOOK*myBook; extern void GuiCreateGuiList(void * r0, BOOK * bk); Сохраняем, закрываем. Заходим опять в IAR. Теперь структуру MyBOOK нужно стереть из main.c, так как мы её добавили в gui.h для того чтобы она могла быть использована в других модулях. В функции main перед return(0); пишем GuiCreateGuiList(0, (BOOK*)myBook);. 5. Всё готово! В файле main.c у вас должно быть: Код: #include "..\\\\include\\Lib_Clara.h" #include "..\\\\include\\Dir.h" #include "gui.h" MyBOOK * myBook; int TerminateElf(void * ,BOOK* book) { FreeBook(book); return(1); } typedef struct { BOOK * book; }MSG; int ShowAuthorInfo(void *mess ,BOOK* book) { MSG * msg = (MSG*)mess; MessageBox(0x6fFFFFFF,STR("Hello Wordl!\\n\\nExample elf.."),0, 1 ,5000,msg->book); return(1); } const PAGE_MSG HW_PageEvents[]@ "DYN_PAGE" ={ ELF_TERMINATE_EVENT , TerminateElf, ELF_SHOW_INFO_EVENT , ShowAuthorInfo, 0,0 }; PAGE_DESC base_page ={"HW_BasePage",0,HW_PageEvents}; void elf_exit(void) { kill_data(&ELF_BEGIN, (void(*)(void*))mfree_adr()); } void onCloseHWBook(BOOK * book) { if (book) { SUBPROC(elf_exit); } } MyBOOK * CreateHWBook() { myBook= new MyBOOK; CreateBook(myBook,onCloseHWBook,&base_page,"Example",-1,0); return(myBook); } int main (void) { CreateHWBook(); GuiCreateGuiList(0, (BOOK *)myBook); return(0); } В gui.c: Код: #include "..\\\\include\\Lib_Clara.h" #include "..\\\\include\\Dir.h" #include "gui.h" #define GUI_NAME L"Example" void GuiBack(BOOK *bk, void *lt) { FreeBook((BOOK*)myBook); } void GuiOnEnterPressed(BOOK *bk, void *lt) { int item=ListMenu_GetSelectedItem(myBook->gui); if(item==0) { MessageBox(0x6fFFFFFF,STR("Элемент 1"),0, 1 ,5000,0); } if(item==1) { MessageBox(0x6fFFFFFF,STR("Элемент 2"),0, 1 ,5000,0); } } int GuiOnLBMessage(GUI_MESSAGE * msg) { int item; switch(msg->msg) { case 1: item=GUIonMessage_GetCreatedItemIndex(msg); if(item==0) SetMenuItemText0(msg,Str2ID(L"Элемент 1",0,SID_ANY_LEN)); if(item==1) SetMenuItemText0(msg,Str2ID(L"Элемент 2",0,SID_ANY_LEN)); } return(1); }; void GuiCreateGuiList(void * r0, BOOK * bk) { myBook->gui=CreateListObject(bk,0); GuiObject_SetTitleText(myBook->gui,Str2ID(GUI_NAME,0,SID_ANY_LEN)); SetNumOfMenuItem(myBook->gui,2); OneOfMany_SetonMessage((GUI_ONEOFMANY*)myBook->gui,GuiOnLBMessage); SetCursorToItem(myBook->gui,0); SetMenuItemStyle(myBook->gui,0); GUIObject_Softkey_SetAction(myBook->gui,ACTION_BACK, GuiBack); GUIObject_Softkey_SetAction(myBook->gui,ACTION_LONG_BACK, GuiBack); GUIObject_Softkey_SetAction(myBook->gui,ACTION_SELECT1,GuiOnEnterPressed); ShowWindow(myBook->gui); }; В gui.h: Код: typedef struct { BOOK book; GUI_LIST*gui; }MyBOOK; extern MyBOOK * myBook; extern void GuiCreateGuiList(void * r0, BOOK * bk); Всё, теперь можно скомпилировать наш эльф. Просто жмём F7, если всё сделали правильно, то внизу должен появиться лог: Код: Building configuration: main - Release Updating build tree... gui.c main.c Linking Идём в папку Release/Exe/ и забираем наш эльф main.elf. Вот и всё! Мы научились создавать простейшую меню со списком пунктов. (c)arban |
MODDER-GT: |
24.04.10, 13:16 |
..Убираем всё лишнее и получаем такой код... где именно убираем? |
arban: |
24.04.10, 14:28 |
MODDER-GT, в файле main.c Да и вообще, урок устарел и ошибки, возможно, есть |
cachok9999: |
25.04.10, 18:18 |
Defined, can you make a GUI to put an Image background? Regards |
arban: |
19.07.10, 11:29 |
Жестокий код. А инициализацию myBook кто делать будет? Посмотри исходники на свн, как сказал JokerXT, как там всё устроено и т.д. |
Pavlus: |
19.07.10, 12:10 |
Вот, кажется так правильно: Код: #include "..\\include\Lib_Clara.h" #include "..\\include\Dir.h" #include "gui.h" MyBOOK * myBook; u16 timer; char *BookName="MyBook"; void elf_exit(void) { kill_data(&ELF_BEGIN, (void(*)(void*))mfree_adr()); } int TerminateElf(void * ,BOOK* book) { FreeBook(book); return(1); } typedef struct { BOOK * book; }MSG; int ShowAuthorInfo(void *mess ,BOOK* book) { MSG * msg = (MSG*)mess; MessageBox(EMPTY_SID,STR("Hello Wordl!\n\nExample elf.."), NOIMAGE, 1, 5000,msg->book); return(1); } const PAGE_MSG MY_PageEvents[]@ "DYN_PAGE" ={ ELF_TERMINATE_EVENT , TerminateElf, ELF_SHOW_INFO_EVENT , ShowAuthorInfo, 0,0 }; PAGE_DESC base_page ={"MY_BasePage",0,MY_PageEvents}; void onCloseMYBook(BOOK * book) { if (book) { SUBPROC(elf_exit); } } //------------------------------------------------------------------------------ int isMyElfBook(BOOK * book){ //return 0==strcmp(book->xbook->name,BookName); if(!strcmp(book->xbook->name,BookName)) return(1); return(0); } int checkMyBookExist(void){ if(FindBook(isMyElfBook)){ return(1); } return(0); } MyBOOK * CreateMYBook() { myBook= new MyBOOK; CreateBook(&(myBook->book),onCloseMYBook,&base_page,BookName,-1,0); return(myBook); } //------------------------------------------------------------------------------ void reportElfIsStarted(BOOK * book){ const int bufsize=strlen(BookName)+strlen(" is running"); char * strMsg=new char[bufsize+1]; strcpy(strMsg,BookName); strcat(strMsg," is running"); MessageBox(0x6FFFFFFF,Str2ID(strMsg,6,SID_ANY_LEN),NOIMAGE,1,5000,0); if(strMsg)delete(strMsg); } int main (void) { if(FindBook(isMyElfBook)){ reportElfIsStarted; TerminateElf; } else{ CreateMYBook(); GuiCreateGuiList(0, &(myBook->book)); } return(0); } |
lexa4311: |
01.08.10, 22:32 |
mugen, прихлопнули тебя, да, месть арбана жестока, согласен конечно p.s. у меня тоже w810 |
URL этой темы: https://mobilefree.justdanpo.ru/newbb_plus/viewtopic.php?topic_id=3730 © 2005-2018 supertrubka.org |