一、entryfunction
在文档里面我们看到下面的条款:
以下引自:write applications using pixtel MMI platform.pdf
Before display the new screen over previous screen the following must be executed:
1. save the contents of previous screen.
保存前面那个窗体的内容;
2. get the buffer to store the contents of screen to displayed.
获得足够的缓存空间来保存当前要显示的窗体的内容。
3. get display attribute for the following screen, i.e. item to display as lists, circular menu etc.
获得下一个要显示的窗体的属性;
4. retrieve number of submenu items to be displayed.
获取要显示的子菜单条目的个数;
5. set the parent of new screen to be displayed.
设置要被显示的新窗体的父窗体;
6. set the submenu item to be displayed highlighted, on next screen.
设置下一级子菜单要被高亮显示的条目;
7. set the function to be executed on pressing right or left soft key.
设置按下左右软件的执行函数;
8. set the function to be called on exiting the next screen.
设置退出下个窗体的的调用函数;
这些工作一般都在窗体的入口函数里面实现的内容,因此我们有必要先从窗体的入口函数开始。以一段代码来说明(这里省略了很多的东西):
void EntryScrIncomingOptions(void)
{
1、退出上一窗口,进入新的窗口
EntryNewScreen(ITEM_SCR_INCOMING_OPTIONS,NULL, EntryScrIncomingOptions, NULL);
2、获取当前窗口的GUI buffer
guiBuffer = GetCurrGuiBuffer(ITEM_SCR_INCOMING_OPTIONS);
3、获取列表窗口的子菜单数目;
number_of_items = GetNumOfChild_Ext(MITEM_OPT_PSEUDO);
4、获取要显示的字符串序列;
GetSequenceStringIds_Ext(MITEM_OPT_PSEUDO, list_of_items);
5、设置当前窗口的父窗口的ID;
SetParentHandler(MITEM_OPT_PSEUDO);
6、注册highlight 函数
RegisterHighlightHandler(ExecuteCurrHiliteHandler);
7、在已经获取了以上信息后,绘制当前的窗口;
ShowCategory1Screen(
STR_SCR1002_CAPTION,
0,
STR_GLOBAL_OK,
IMG_GLOBAL_OK,
STR_GLOBAL_BACK,
IMG_GLOBAL_BACK,
number_of_items,
list_of_items,
0,
guiBuffer);
8、后面是注册按键函数;
SetRightSoftkeyFunction(GoBackHistory, KEY_EVENT_UP);
SetKeyHandler(KbCBackCallIncomingRejected, KEY_END, KEY_EVENT_DOWN);
SetKeyHandler(KbCBackCallIncomingAccepted, KEY_SEND, KEY_EVENT_DOWN);
SetSideVolumeKeysForCM();
SetKeyHandler(GoBackHistory, KEY_LEFT_ARROW, KEY_EVENT_DOWN);
}
这是一个典型的窗口入口函数,窗口的进入都是通过类似的这种 entry××function() 来实现。这时引来另外一个问题,就是关于窗口切换是通过什么来实现的,怎么才能保证这些窗口在切换的过程中保持当时的状态。这就涉及到history 管理。
History 的管理是通过栈来实现的。在文档中,我们读到这样的内容:
History concept is implemented as a stack. Whenever a new history node is added to the list, it is added at the beginning and whenever a node is deleted it is deleted form the beginning.
历史这个概念是用栈来实现的。当一个新的历史节点加入到这个列表时,它就被加到栈顶,但这个节点被删除时,它就被从栈顶删除。
一般来说历史的应用步骤是这样的:
1. saving screen contents to history.
保存窗体的数据到历史中去。这个数据的内容将在下面提到。
2. going back N levers in history and redrawing screen at that depth.
返回到N 级历史,并重画当时的窗体。
3. deleting N nodes from top of stack from history.
从历史的栈顶删除N个节点。
还是这样一个函数:
void EntryFunc()
{
EntryNewScreen( Screen_ID , Exit_Func , Entry_Func , NULL );
guiBuffer = GetCurrGuiBuffer( SCR_ID_WORDMAIN_LIST );
ShowCategroyXXScreen( Title_ID , … , guiBuffer);
}
这里无论是EntryNewScreen的调用,还是guiBuffer的传入,我们都很少考虑过对这些指针和函数在GUI的管理起到了什么样的作用。下面我们就要了解,以上的代码与History管理之间存在的关系。
在MTK环境中,每当我们进入一个窗口,系统将先提取前一个窗口需保留的数据。这些数据包括:
1. 窗口ID ;
2. 进入窗口时调用的函数和退出调用的函数 -- Exit_Func 和 Entry_Func ;
3. 组成窗体的控件的属性(如,列表控件当前高亮显示的条目、当前屏的首末条目等)。
通过跟踪调试程序可以看到 这些动作是在每次调用 EntryNewScreen函数的时候实现的。具体的实现过程就是 :EntryNewScreen函数先将上次执行EntryNewScreen时所记录的currExitScrnID, currEntryFuncPtr以history结构为载体记录入栈;然后执行了记录中的currExitFuncPtr;最后将本窗口的scrnID、exitFuncPtr、entryFuncPtr分别记录入全局变量currExitScrnID、currExitFuncPtr和currEntryFuncPtr,留待下次调用EntryNewScreen时使用。在退出本窗口的时候通过GoBackHistory 出栈,返回到本窗口的父窗口。
举例说明这些数据在实际中是如何被使用的。
假设存在AB两个窗口,A窗口需要保留的数据为data_A。我们先从A窗口进入到B窗口。data_A将在B窗口调用EntryNewScreen()的时候,被压入一个结构类似于栈的数据存储区域;当从B调用GoBackHistory()返回A时,data_A从栈顶被弹出,然后A利用data_A将自身还原到其进入B之前的状态。
这就是History管理的作用。简言之,就是要保持窗口的外观状态。到这里,我们就回答了前面所提出的问题。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xzl04/archive/2009/04/11/4063062.aspx