History管理 MTK

一、什么是History管理 对于我们上层用户而言,经常接触到的History管理是这样的: void EntryFunc() { U8 *guiBuffer; 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. 组成窗体的控件的属性(如,列表控件当前高亮显示的条目、当前屏的首末条目等)。 举例说明这些数据在实际中是如何被使用的。 假设存在AB两个窗口,A窗口需要保留的数据为data_A。我们先从A窗口进入到B窗口。data_A将在B窗口调用EntryNewScreen()的时候,被压入一个结构类似于栈的数据存储区域;当从B调用GoBackHistory()返回A时,data_A从栈顶被弹出,然后A利用data_A将自身还原到其进入B之前的状态。 这就是History管理的作用。简言之,就是要保持窗口的外观状态。 二、History管理的机制 现在,我们来了解一下前面所说的data_A的数据结构是什么样的。 typedef struct _history { U16 scrnID; //(1)Screen ID (窗口号) FuncPtr entryFuncPtr; //(2)EntryNewScreen时要进入的 Entry_Func U8 inputBuffer[MAX_INPUT_BUFFER]; //(3)没遇到过其使用,都是NULL。 U8 guiBuffer[MAX_GUI_BUFFER]; //(4)窗体中控件的一些需保存的信息的Buffer,通常//在使用时被转化成各控件自定义的结构体如: list_menu_category_history。 } history; 而存放data_A的类似于堆栈的数据区则以全局变量的形式定义在系统中: historyNode historyData[MAX_HISTORY]; (MAX_HISTORY = 50): 设当前窗口A所对应的数据是historyData[ EntryScreenNum – 1 ] ,那么它是何时、是如何被赋值的?又是何时、如何被使用的? 经过跟踪调试,我们已经知道,在由窗口A进入到窗口B(调用EntryNewScreen)的时候,我们将data_A记录到了historyNode 的结构体变量中。但是,在EntryNewScreen的时候传入的,却是data_B,data_A是如何被记录和使用的呢? 我们摘选EntryNewScreen的子函数中所包含的较核心的代码来说明这个问题。这三段代码是按照现在的排放顺序来执行的。 第一段(history h 可理解为data_A): h.scrnID = scrnID; // scrnID = currExitScrnID h.entryFuncPtr = entryFuncPtr; // entryFuncPtr = currEntryFuncPtr pfnUnicodeStrcpy((S8*) h.inputBuffer, (S8*) & nHistory); // nHistory = NULL ; GetCategoryHistory(h.guiBuffer); //GetCategoryHistory是指向获取//guiBuffer的函数的指针 AddHistory(h); //数据入栈 第二段: if(currExitFuncPtr) { //… (*currExitFuncPtr) (); //执行Exit_Func } 第三段(记录Screen_ID,Exit_Func和EntryFunc): currExitScrnID = scrnID; currExitFuncPtr = exitFuncPtr; currEntryFuncPtr = entryFuncPtr; 这样,我们就可以看出,EntryNewScreen函数先将上次执行EntryNewScreen时所记录的currExitScrnID, currEntryFuncPtr以history结构为载体记录入栈;然后执行了记录中的currExitFuncPtr;最后将本窗口的scrnID、exitFuncPtr、entryFuncPtr分别记录入全局变量currExitScrnID、currExitFuncPtr和currEntryFuncPtr,留待下次调用EntryNewScreen时使用。 下面有数据出入栈流程,有兴趣的话可以跟踪一下。以先后顺序代表包含关系,如下: 1.入栈(EntryNewScreen): (1)U8 EntryNewScreen(U16 newscrnID, FuncPtr newExitHandler, FuncPtr newEntryHandler, void *peerBuf) (2)static void ExecuteCurrExitHandler(void); (3)void ExecuteCurrExitHandler_Ext(void); (4)void GenericExitScreen( U16 scrnID , FuncPtr entryFuncPtr ); (5)void AddHistoryReference(history *addHistory); //处理historyData (6)S16 increment(); //更改栈指针 2.出栈(GoBackHistory): (1)void GoBackHistory(void); (2)static void ExecutePopHistory(void); //处理historyData (3)static U8 decrement(void); //更改栈指针 现在我们已经知道了history 的三个结构体 本文来自:我爱研发网(52RD.com) - R&D大本营 详细出处:http://www.52rd.com/Blog/Detail_RD.Blog_wacious_9608.html#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值