最近测试组对手机里IP通话这方面很是重视,不仅要求IP设置里面的内容可设置也可取消设置,而且要求通过通话记录等所有相关方式实现IP拨号。在做这块内容时自己频繁的用到mmi_frm_hide_menu_item和mmi_frm_unhide_menu_item函数,以前只知道用,没怎么去看过他的实现,今天禁不住好奇就偷偷钻进去瞄了一眼,不看还不想看,一看就觉得惊奇,这两个函数功能虽简单,却使用另一种自己没想到的手法去实现。让我再次感叹mtk代码的规范优美。
首先介绍在这之中一个很重要的变量:static U8 MenuItemMask[(MAX_MENU_ITEMS_VALUE / 8) + 1];
mtk使用8位数的数组来存储所有菜单的显示属性,每个数的每个位代表一个菜单是否显示,0表示显示,1表示隐藏。
用位来表示菜单的显示属性,这种做法让我惊叹,不仅数据量得到减小,而且逻辑紧密,接口清晰。
但有一点不足,就是这两个函数操作的menuid必须定义在GlobalMenuItems.h中操作才能有效。
下面贴出这两个函数实现的代码:
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 1
/*****************************************************************************
* FUNCTION
* mmi_frm_hide_menu_item
* DESCRIPTION
* Set the bit represented the menuitem on to hide it
* PARAMETERS
* menu_item_id [IN] Id of the menuitem
* RETURNS
* void
*****************************************************************************/
void mmi_frm_hide_menu_item(U16 menu_item_id)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U16 idx = 0, reminding = 0;
U16 item_id = menu_item_id - 1;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (menu_item_id < MAX_MENU_ITEMS_VALUE)
{
idx = item_id / 8;
reminding = item_id - (idx * 8);
MenuItemMask[idx] |= (1 << (7 - reminding));
}
}
/*****************************************************************************
* FUNCTION
* mmi_frm_unhide_menu_item
* DESCRIPTION
* Reset the bit represented the menuitem on to unhide it
* PARAMETERS
* menu_item_id [IN] Id of the menuitem
* RETURNS
* void
*****************************************************************************/
void mmi_frm_unhide_menu_item(U16 menu_item_id)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U16 idx = 0, reminding = 0;
U16 item_id = menu_item_id - 1;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (menu_item_id < MAX_MENU_ITEMS_VALUE)
{
idx = item_id / 8;
reminding = item_id - (idx * 8);
MenuItemMask[idx] &= ~(1 << (7 - reminding));
}
}
一般在调用完这两个函数后还会执行如下的动作,以便为shouCategory做准备:
U16 nNumofItem;
U16 nStrItemList[6];
nNumofItem = GetNumOfChild_Ext(MENU_ID_PHB_EXTRA_NUMBER);
GetSequenceStringIds_Ext(MENU_ID_PHB_EXTRA_NUMBER, nStrItemList);
执行的这两个函数实现如下:
代码
其中核心的实现函数为:MMI_BOOL mmi_frm_test_menu_item_hide(U16 menu_item_id);
该函数的实现为:
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> 1
/*****************************************************************************
* FUNCTION
* mmi_frm_test_menu_item_hide
* DESCRIPTION
* test if the menuitem is hidden or not
* PARAMETERS
* menu_item_id [IN] Id of the menuitem
* RETURNS
* MMI_BOOL MMI_TRUE if the menuitem is hidden
*****************************************************************************/
MMI_BOOL mmi_frm_test_menu_item_hide(U16 menu_item_id)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U16 idx = 0, reminding = 0;
U16 item_id = menu_item_id - 1;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (menu_item_id < MAX_MENU_ITEMS_VALUE)
{
idx = item_id / 8;
reminding = item_id - (idx * 8);
if ((MenuItemMask[idx] >> (7 - reminding)) & 1)
{
return MMI_TRUE;
}
}
return MMI_FALSE;
}
void mmi_frm_hide_menu_item(U16 menu_item_id);将要隐藏的菜单ID对应MenuItemMask数组中的位 置1
而MMI_BOOL mmi_frm_test_menu_item_hide(U16 menu_item_id);通过判断MenuItemMask中对应的位是否是1来判断这个位所对应的菜单是否被隐藏,他所使用到的
CUSTOM_MENU nCustMenus[MAX_MENU_ITEMS];
定义在StandaloneRes.c中InitializeResourceVariables函数里面
nCustMenus = (CUSTOM_MENU *)(langpack2ndJumpTbl[9]);//071706 menu resource
其中
void* langpack2ndJumpTbl[] = {
(void*) mtk_gLanguageArray,
void* langpack2ndJumpTbl[] = {
(void*) mtk_gLanguageArray,
(void*) &mtk_gMaxDeployedLangs,
(void*) mtk_gStringList,
(void*) mtk_gIMEModeArray,
(void*) &mtk_gMaxDeployedLangs,
(void*) mtk_gStringList,
(void*) mtk_gIMEModeArray,
(void*) mtk_gIMEQSearchModeArray,
(void*) mtk_gIMEQSearchModeArray,
(void*) mtk_gIMELDBArray,
(void*) mtk_gIMELDBArray,
(void*) &mtk_gIMEModule
#if defined(__MMI_T9_TR_CHINESE__)
,(void*) &l0104
#else
,0
#endif
#if defined(__MMI_T9_SM_CHINESE__)
, (void*) &l0204
#else
,0
#endif
,(void*) mtk_nCustMenus//071706 menu resource
};
}
则nCustMenus[] 为CUSTOM_MENU mtk_nCustMenus[]
上述数组是在Mtk_resgenerator.cpp 中生成的,进入MTK编译系统,这里就不阐述了。
上述的工作方式希望对自己以后得代码有参考价值。向mtk优秀的代码不断学习。