History管理

来源:互联网 发布:sqlserver restoring 编辑:程序博客网 时间:2024/05/06 05:33

对于我们上层用户而言,经常接触到的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)文字输入界面用来保存已输入的文字。
     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时使用。 

原创粉丝点击