MTK按键处理流程和⾼亮处理机制声明:以上资料来⾃⽹上
1.按键处理流程
主要简单分析⼀下左右软件的事件,以左软键事件为例
牵涉到的常⽤函数:
void SetKeyHandler( FuncPtr funcPtr, U16 keyCode, U16 keyType );
void SetLeftSoftkeyFunction( void (*f)(void), MMI_key_event_type k );
void ChangeLeftSoftkey( U16 s, U16 i );
1. SetKeyHandler与SetLeftSoftkeyFunction
(1). SetKeyHandler
主要作⽤就是将需要起作⽤的函数的指针(funcPtr)
-->全局矩阵数组currKeyFuncPtrs[keyCode][keyType]的指定位置 ;
(2). SetLeftSoftkeyFunction
该函数内部主要流程:
Step1. call register_left_softkey_handler( )
这个函数call SetKeyHandler: 存储需要起作⽤的函数(left_softkey_down/left_softkey_up)
以left_softkey为例, 该函数⾸先⾸先刷新按键区域图像(redraw_softkey),
然后执⾏关联函数(softkey_functions[key][k]).
Step2. 在上⼀步⾥我们会发现,softkey_functions[key][k]⾥的函数指针没有初始化
通过 call t_left_softkey_function(f, k);
--->softkey_functions[key][k] = f;
这样,就成功的把按键按下/放开的作⽤函数与具体的动作关联起来了。
Step3. 最后call SetInputboxLSKFunction(f)
-
-->将上述函数与特定的输⼊(如触摸笔)关联起来。
(3). 以上两个函数的主要区别:
SetLeftSoftkeyFunction可以识别长按状态并且可以关联触摸笔操作等。
2. ChangeLeftSoftkey
主要执⾏流程:
Step1. call change_left_softkey: 设置左软键图表,⽂字
Step2. redraw_softkey: 刷新左软键显⽰区域
重工业2.⾼亮处理机制
1 相关函数和变量列表:
voidRegisterHighlightHandler(void(*f)(S32item_index))
注册窗⼝的通⽤⾼亮处理函数。
9929
astronauticsMMI_list_highlight_handler
通⽤⾼亮处理函数的全局变量指针。
voidExecuteCurrHiliteHandler(S32hiliteid)
当前⾼亮菜单项的通⽤处理函数,它会找到菜单项对应的处理函数。⼀般在窗⼝创建过程中被创
建RegisterHighlightHandler(ExecuteCurrHiliteHandler)。
FuncPtrmmi_frm_get_hilite_hdlr(U16menu_id)
获取menu_id对应的菜单⾼亮函数,从两个函数指针数组⾥获取。先查找动态菜单的⾼亮函数指针数组,这个是在程序中动态添加的数组;如果找不到,再到静态数组⾥查找,这个数组是在编译过程中⽣成的,通常我们在res_mainmenu.c等函数⾥增加的菜单会被资源⽣成⼯具编译成⼀个静态数组。
mmi_frm_int_hilite_hdlr_table[]动态数组。
mmi_frm_const_hilite_hdlr_table[]静态数组。
currParentID
当前⽗窗⼝全局变量
会计人员职业道德voidSetHiliteHandler(U16itemid,FuncPtrhiliteFuncPtr)with
设置动态⾼亮数组的MENUID及它相对应的处理函数,⼀般⽤在⾃定义的菜单项。⽐如在图⽚浏览、JAVA应⽤、WAP记录等不可预期菜单项数⽬的环境,我们不可能做静态的MENUID和处理函数,就需要⽤到动态的实现⽅式。
hintData[][]
[待确认]:这是⼀个动态菜单的数据缓冲,和MENUID⼀⼀对应。通俗⼀点说,就是菜单的显⽰字符串。⽹上有⽂章对此以
及ConstructHintsList()理解应该有误,主要是因为代码⾥该函数注释说是处理静态的,应该是注释错了。引⽤⼀段描述:
2、ConstructHintsList()
ConstructsHintListforastaticmenuscreen
vipabc青少年英语voidConstructHintsList(U16parentID,U8**hintArray)
{。。。。。。
(*maxHiliteInfo[hiliteItemID[i]].hintFuncPtr)(idx);//SetHintHandler注册的函数的函数在此被执⾏
hintArray[idx]=hintData[idx];//该语句是该函数的核⼼,就是将全局变量hintData[idx]数组地址
//赋给⽤户传过来的指针数组;⾄于hintData[idx]中是否有数据不
//管;hintData[idx]的数据会在调⽤SetHintHandler注册的函数时对其
//进⾏初始化;要记住SetHintHandler注册的函数在SetHiliteHandler注册的
//函数之前执⾏。
我认为ConstructHintsList()是创建动态菜单的,时间关系,待分析。
3⾼亮机制说明:
3.1使⽤流程
每个窗⼝进⼊后基本都有类似下⾯的⼀段程序:
。
。。。。。
EntryNewScreen(EM_DEBUG_INFO_SCR,NULL,EntryEMDebugInfo,NULL);
guiBuffer=GetCurrGuiBuffer(EM_DEBUG_INFO_SCR);
nItems=GetNumOfChild(EM_DEBUG_INFO_MENUID);
GetSequenceStringIds(EM_DEBUG_INFO_MENUID,ItemList);
SetParentHandler(EM_DEBUG_INFO_MENUID);
RegisterHighlightHandler(ExecuteCurrHiliteHandler);
ShowCategory52Screen(。。。)
SetRightSoftkeyFunction(GoBackHistory,KEY_EVENT_UP);
。。。。。。
3.2分析
这是窗⼝建⽴过程的⼀个通⽤处理结构,这⾥简单说明⼀下,每个函数的具体实现和功能请阅读代码。
EntryNewScreen初始化建⽴⼀个窗⼝需要的变量和过程,并退出上⼀个窗⼝,清除按键处理函数等;
留学翻译
SetParentHandler很重要,设置当前⽗窗⼝全局变量的MENUID,⽤来定位到当前是在哪⼀个窗⼝,后⾯依据他来在菜单树中查找到⾼亮的菜单项的MENUID,找到菜单项的MENUID后,通过mmi_frm_get_hilite_hdlr(U16menu_id)可以找到菜单项对应的⾼亮函
数;RegisterHighlightHandler把ExecuteCurrHiliteHandler注册成⼀个通⽤的⾼亮处理函数,我们只要告
诉ExecuteCurrHiliteHandler当前⾼亮的菜单项的MENUID,它就能找到执⾏函数并开始执⾏了。到这⾥就应该已经基本明⽩了⾼亮机制了,弄明⽩了其实也很简单的^_^;
ShowCategory52Screen()只是⼀个窗⼝界⾯绘制函数,和事件处理逻辑没有关系。
SetRightSoftkeyFunction(GoBackHistory,KEY_EVENT_UP)等函数设置这个窗⼝要响应哪些按键事件,并设置好相应的处理函数。
3.3⾼亮函数触发过程
RegisterHighlightHandler把ExecuteCurrHiliteHandler注册成⼀个通⽤的⾼亮处理函数,实际上是给MMI_list_highlight_handler函数指针赋值。触发则需要调⽤MMI_list_highlight_handler。
由于MTK平台⽀持各种菜单形式,⽐如纯⽂本的菜单、带CHECKBOX的、带RADIO的、带⼀个图⽚的、带两个图⽚的、两⾏的。我们现在只对⼀种标准菜单进⾏分析,其他形式的分析⽅法相同。
standard_list_highlight_handler(S32item_index)⾥会执⾏注册的⾼亮处理函数MMI_list_highlight_handler,
⽽standard_list_highlight_handler本⾝⼜是⼀个注册函数,在wgui_fixed_list_create_text_menu()⾥会被注册
到MMI_fixed_list_menu.item_highlighted,MMI_fixed_list_menu是菜单组件的数据结构,包含有菜单组件从显⽰到功能处理函数的所有数据,具体每个组件怎么被显⽰,怎么响应功能按键就不在这⾥讨论了,后续我可能会写出⽂档,有兴趣的同学⾃⼰看代码,效果会更好。
这⾥简单说⼀下,MMI_fixed_list_menu.item_highlighted在这个组件⾥,会被gui_fixed_list_menu_switch_highlighted_item()函数来执⾏,⽽gui_fixed_list_menu_switch_highlighted_item()则在上下按键执⾏的时候被执⾏,⽐响应上按键的函数
是voidfixed_list_goto_previous_item(void),它调⽤voidgui_fixed_list_menu_goto_previous_item(fixed_list_menu*m),
⽽voidgui_fixed_list_menu_goto_previous_item(fixed_list_menu*m)则调⽤gui_fixed_list_menu_switch_highlighted_item(),整个触发过程就完成了。
关于上下按键的注册,则在wgui_fixed_list_create_text_menu()⾥有:
if(flag&WGUI_LIST_MENU_DISABLE_VOL_KEY)
register_fixed_list_keys_ex();
el
register_fixed_list_keys();
来注册按键事件处理函数,其实现过程很简单:
voidregister_fixed_list_keys(void)
{
/*----------------------------------------------------------------*/
/*LocalVariables*/
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/*CodeBody*/
医学视频/*----------------------------------------------------------------*/
SetKeyHandler(fixed_list_goto_previous_item,KEY_UP_ARROW,KEY_EVENT_DOWN);
SetKeyHandler(fixed_list_goto_next_item,KEY_DOWN_ARROW,KEY_EVENT_DOWN);
SetKeyHandler(fixed_list_goto_previous_item,KEY_VOL_UP,KEY_EVENT_DOWN);
SetKeyHandler(fixed_list_goto_next_item,KEY_VOL_DOWN,KEY_EVENT_DOWN);
}
confident用法
关于如何实现按键事件的响应、按键的处理逻辑,⼜是⼀个专题了。⼤致包括键盘中断、去抖、键盘映射、检测、进程通信、应⽤部分按键处理机制等,有机会再写出⽂档。
4相关知识点说明:
4.1初始化相关
⾼亮的⼀些全局变量会在InitEvents()⾥进⾏初始化,在event.c⽂件⾥。这个函数在开机过程中的⼀个调⽤栈关系如下:
InitEvents();
InitEventHandlersBeforePowerOn();
voidMMI_task(oslEntryType*entry_param)
InitEvents();还会在InitFramework()中被调⽤,⽽InitFramework()会由于开机的状态不同,如USB开机、闹钟开机等,调⽤流程也不尽相同。具体的可参见我的另⼀篇应⽤开机流程的⽂档。
4.2菜单结构及查找
4.2.1菜单数数组⽰意
constCUSTOM_MENUmtk_nCustMenus[]={
{1,0,18,0,16,2,10933,11062,(U16*)nOrderMenuItem_0},
{2,0,3,1,0,1,26218,26085,(U16*)nOrderMenuItem_1},
{3,2,0,1,0,1,555,0,(U16*)0},
{4,2,0,1,0,1,552,0,(U16*)0},
{5,2,0,1,0,1,26173,0,(U16*)0},
{0,0,0,0,0,0,0,0,(U16*)0},
{0,0,0,0,0,0,0,0,(U16*)0},
{0,0,0,0,0,0,0,0,(U16*)0},
{0,0,0,0,0,0,0,0,(U16*)0},
{0,0,0,0,0,0,0,0,(U16*)0},
{0,0,0,0,0,0,0,0,(U16*)0},
。。。。。。。。
}
CUSTOM_MENUnCustMenus[MAX_MENU_ITEMS];
inform
4.2.2通过⽗窗⼝MENUID及⾼亮INDEX找到⾼亮窗⼝MENUID
U16GetSeqItemId_Ext(U16parent_item_id,U16index)
{
/*----------------------------------------------------------------*/
/*LocalVariables*/
/*----------------------------------------------------------------*/
U8i=0,idx=0;