关于在已有的一个OSD Win上增加了一个Page: (以在Mainmenu里增加一个test page为例)
1、 MApp_Main.c里有个while(1)循环;
2、 通过 while(1)循环MApp_MultiTasks 里面的 MApp_ProcessUserInput 可以 得到 当前的 u8KeyCode
3、 while(1)循环 里面的MApp_TopStateMachine的作用:
3.1、在刚开机时,首先 enTopState = STATE_TOP_DIGITALINPUTS 等待用户输入;
3.2、再次调用:MApp_TopStateMachine时,switch ( enTopState ) 之后调用 switch (MApp_TV) ;
3.3、当用户在IR中输入Menu按键;
3.4、通过MApp_TV调用MApp_TV_ProcessUserInput 之后
switch ( u8KeyCode )
case KEY_MENU:
enTVState = STATE_TV_INIT;
enTVRetVal = EXIT_GOTO_MENU;
u8KeyCode = KEY_NULL;
break;
switch(MApp_TV())
case EXIT_GOTO_MENU:
enTopState = STATE_TOP_MENU;
break;
3.5、再次调用:MApp_TopStateMachine时,witch ( enTopState ) 之后调用 switch(MApp_Menu_Main()) ;
3.6、通过MApp_Menu_Main调用MApp_ZUI_ACT_StartupOSD(E_OSD_MAIN_MENU);再调用MApp_ZUI_ACT_AppShowMainMenu();就可以Show出我们想要Show出的主界面了。
enMainMenuState = STATE_MENU_WAIT;
_eZUIState = E_ZUI_STATE_RUNNING;
3.7、再次调用MApp_Menu_Main时,switch(enMainMenuState)时,就要执行: MApp_ZUI_ProcessKey(u8KeyCode);
u8KeyCode = KEY_NULL;
MApp_ZUI_ACT_ExecuteWndAction(EN_EXE_UPDATE_SIGNAL_INFORMAT); 了;
3.8、MApp_ZUI_ProcessKey调用MApp_ZUI_API_PostMessage(HWND_MAINFRAME, MSG_KEYDOWN, vk_code),Post Message。
3.9、再次调用MApp_TopStateMachine 时执行到 MApp_ZUI_MainTask 时
switch (_eZUIState) eZUIState等于了E_ZUI_STATE_RUNNING,就会调用MApp_ZUI_API_GetMessage(&msg)收到刚才MApp_ZUI_ProcessKey发过来的Message,再通过MApp_ZUI_API_DispatchMessage (&msg);因为我们刚才发的是key的Message所以,执行的以下代码:
if (pMsg->message == MSG_KEYDOWN)
{
//printf("[dispmsg1]\n");
if (_eZUIState == E_ZUI_STATE_RUNNING /*||
_eZUIState == E_ZUI_STATE_MSGBOX_DOMODAL*/)
{
if (!MApp_ZUI_ACT_HandleGlobalKey((VIRTUAL_KEY_CODE)pMsg->wParam)) {
focus = GETWNDFOCUS();
//printf("/focus=%bu\n", (U8)focus);
//printf("[dispmsg2]\n");
if (HWND_INVALID != focus)
{
pMsg->hwnd = focus; //2007/12/24: keydown message for focus iRet = MApp_ZUI_ACT_ExecuteWndProc(GETWNDPROCID(focus), pMsg);
}
}
}
#if ZUI_DBG_RECURSIVE
_bInDispatchMessage = 0;
#endif //ZUI_DBG_RECURSIVE
return iRet;
}
3.10、由focus = GETWNDFOCUS();得到当前Win的Focus
3.11、MApp_ZUI_ACT_ExecuteWndProc(GETWNDPROCID(focus), pMsg)两个参数的说明: GETWNDPROCID(focus),得到当前Win的类型(有EN_ZUI_DEFAULTWINPROC、EN_ZUI_FLIPPAGE_WINPROC 、EN_ZUI_EFFECT_WINPROC等类型)
pMsg:收到的消息,在本例中收到是按键。
3.12、执行到S32 MApp_ZUI_ACT_ExecuteWndProc(U8 u8WinProcID, PMSG msg),根据传过来的参数,执行:EFFECT_WINPROC(msg->hwnd, msg);直接调用:return DEFAULTWINPROC(hWnd, pMsg);
3.13、转到执行:MApp_ZUI_API_DefaultWindowProc
本例会执行以下语句:
if (GETWNDKEYEVENT(focus))
{
KEYEVENT *keyevent;
keyevent = GETWNDKEYEVENT(focus);
while (keyevent->u16VirKey != VK_NULL)
{
if (keyevent->u16VirKey == pMsg->wParam)
{
handled = MApp_ZUI_ACT_ExecuteWndAction(keyevent->u16ExeActID); //we can allow multiple actions... depend on the last one action.. }
keyevent++;
}
对这段代码的理解,由GETWNDKEYEVENT(focus)得到当前focus定义的keyevent,如果有定义当前所按键的事件if (keyevent->u16VirKey == pMsg->wParam)则MApp_ZUI_ACT_ExecuteWndAction(keyevent->u16ExeActID);将定义要执行的事件ID传过去。
For example:
static KEYEVENT _ZUI_TBLSEG _MENU_PICTURE_MODE_KEY[] =
{
{ VK_SELECT, EN_EXE_GOTO_PICTURE_MODE_PAGE},
{ VK_UP, EN_EXE_NOTIFY_PARENT_KEY_UP },
{ VK_DOWN, EN_EXE_NOTIFY_PARENT_KEY_DOWN },
{ VK_UP, EN_EXE_EFFECT_SLIDEITEM },
{ VK_DOWN, EN_EXE_EFFECT_SLIDEITEM },
{ VK_LEFT , EN_EXE_EFFECT_FLIPPAGE_LEFT },
{ VK_RIGHT , EN_EXE_EFFECT_FLIPPAGE_RIGHT },
{ VK_NULL, 0 },
};
3.14、执行到:MApp_ZUI_ACT_ExecuteWndAction
本例只执行:switch(_eActiveOSD)段。当前是E_OSD_MAIN_MENU所以执行MApp_ZUI_ACT_ExecuteMainMenuAction(act);
3.15、以按左右键为例:
switch(act)
case EN_EXE_EFFECT_FLIPPAGE_LEFT:
case EN_EXE_EFFECT_FLIPPAGE_RIGHT:
{
static HWND hwndTop[] =
{
HWND_MENU_CHANNEL_PAGE,
HWND_MENU_PICTURE_PAGE,
HWND_MENU_SOUND_PAGE,
HWND_MENU_TIME_PAGE,
HWND_MENU_OPTION_PAGE,
#if SHOW_LIUBO_ADD_TEST_PAGE
HWND_MENU_TEST_PAGE,
#endif
#if ENABLE_ATV_VCHIP//ENABLE_DTV
HWND_MENU_LOCK_PAGE,
#endif
#if (INPUT_USB_SOURCE == 0)
HWND_MENU_APP_PAGE,
#endif
};
HWND hwndFocus = MApp_ZUI_API_GetFocus();
HWND hwndEffect = hwndFocus;
HWND hwndNext = HWND_INVALID;
EN_FLIPPAGE dir = EN_FLIPPAGE_NONE;
/******若当前不是第0个Index page则 要找到当前功能的首个page 即属性为EN_ZUI_FLIPPAGE_WINPROC的page**************/
while((hwndEffect=MApp_ZUI_API_GetParent(hwndEffect))!= HWND_MAINFRAME ) {
if ( MApp_ZUI_API_GetWindowProcId(hwndEffect) == EN_ZUI_FLIPPAGE_WINPROC ) {
break;
}
}
/******若当前不是第0个Index page则 要找到当前功能的首个page 即属性为EN_ZUI_FLIPPAGE_WINPROC的page**************/
if ( hwndEffect == HWND_MAINFRAME )
return TRUE;
U32 u32Data = MApp_ZUI_API_GetWindowData(hwndEffect);
if ( u32Data == 0 )
return TRUE;
U32 i;
for (i=0; i<COUNTOF(hwndTop); i++)
{
if ( hwndTop[i] == hwndEffect )
break;
}
if ( i >= COUNTOF(hwndTop) )
return TRUE;
if (act == EN_EXE_EFFECT_FLIPPAGE_LEFT)
{
if ( i < 1 )
i = COUNTOF(hwndTop) - 1;
#if ENABLE_DTV
else if((hwndTop[i]==HWND_MENU_APP_PAGE)&&(!IsDTVInUse())) i-=2;
#endif
else
i--;
hwndNext = hwndTop[i];
dir = EN_FLIPPAGE_LEFT;
}
else if (act == EN_EXE_EFFECT_FLIPPAGE_RIGHT)
{
if ( i+1 >= COUNTOF(hwndTop) )
i = 0;
#if ENABLE_DTV
else if((hwndTop[i]==HWND_MENU_OPTION_PAGE)&&(!IsDTVInUse())) i+=2;
#endif
else
i++;
hwndNext = hwndTop[i];
dir = EN_FLIPPAGE_RIGHT;
}
HWND child, last_succ; //2008/4/12: get last successor once HWND listwn = hwndNext+2;
last_succ = MApp_ZUI_API_GetLastSuccessor(listwn);
for (child = listwn+1; child <= last_succ; child++)
{
if (MApp_ZUI_API_GetParent(child) != listwn)
continue;
if (MApp_ZUI_ACT_QueryDynamicListItemStatus(child) != EN_DL_STATE_NORMAL) 这个if语句的作用是:设置下个页面不要显示的win。
continue;
else
break;
}
GUI_DATA_FLIPPAGE *windata = (GUI_DATA_FLIPPAGE *) u32Data; windata->pVarData->hwndCurrent = hwndEffect;
windata->pVarData->hwndNext = hwndNext;
/*
if(windata->pVarData->hwndNext == HWND_MENU_LOCK_PAGE) { // if focus on HWND_MENU_LOCK_PAGE, set focus on HWND_MENU_LOCK_TITLE
// Press Enter to invoke input password dialog and to input password to use HWND_MENU_LOCK_PAGE's functions.
child = windata->pVarData->hwndNext +1;
}
*/
#if ENABLE_DTV
if(windata->pVarData->hwndNext == HWND_MENU_LOCK_PAGE) stGenSetting.g_BlockSysSetting.u8EnterLockPage = 0; #endif
if(child == last_succ)
windata->pVarData->hwndNextFocus = windata->pVarData->hwndNext+3; else
windata->pVarData->hwndNextFocus = child;
windata->pVarData->dir = dir;
//MApp_ZUI_API_PostMessage(windata->pVarData->hwndCurrent, MSG_EFFECT, 0); MApp_ZUI_API_SendMessage(windata->pVarData->hwndCurrent, MSG_EFFECT, 0);
MApp_ZUI_API_InvalidateWindow(HWND_MENU_MAIN_BOTTON_INFO_BAR); return TRUE;
第二篇:Mstar_6M48学习心得之关于DMP
一、InputSource界面的显示:
1、switch(MApp_TV())
MApp_TV_ProcessUserInput();
switch(u8KeyCode)
case KEY_INPUT_SOURCE:
enTVState = STATE_TV_INIT;
enTVRetVal = EXIT_GOTO_INPUTSOURCE;
u8KeyCode = KEY_NULL;
break;
case EXIT_GOTO_INPUTSOURCE:
enTopState = STATE_TOP_INPUTSOURCE;
break;
2、switch ( enTopState )
case STATE_TOP_INPUTSOURCE:
switch(MApp_InputSource_Main())
EN_RET MApp_InputSource_Main(void)
switch(enInputSourceState)
case STATE_INPUTSOURCE_INIT:
MApp_ZUI_ACT_StartupOSD(E_OSD_INPUT_SOURCE); enInputSourceState = STATE_INPUTSOURCE_WAIT; break;
当我们按“上”、“下”键时,执行:
MApp_ZUI_ACT_ExecuteWndProc(GETWNDPROCID(focus), pMsg); 再执行:
MApp_ZUI_API_DefaultWindowProc
再执行:
MApp_ZUI_ACT_ExecuteWndAction
以按下键为例:
执行:
case EN_EXE_NOTIFY_PARENT_KEY_DOWN:
MApp_ZUI_API_PostMessage(
MApp_ZUI_API_GetParent(MApp_ZUI_API_GetFocus()), MSG_NOTIFY_KEYDOWN,
VK_DOWN);
return TRUE;
再执行:
case EN_ZUI_DYNAMICLIST_WINPROC:
return DYNAMICLIST_WINPROC(msg->hwnd, msg); 再执行:
if((windata->pVarData->hwndFirstShown<=next
&&next<= windata->pVarData->hwndLastShown)
&&MApp_ZUI_API_IsWindowVisible(next)
&&MApp_ZUI_API_IsWindowEnabled(next))
{
//shown region: trivial case: focus it
MApp_ZUI_API_SetFocus(next);
printf("[]focus=%u\n", next);
break;
}
return DEFAULTWINPROC(hWnd, pMsg);
选中Input Source的USB项,再按OK键,执行:
case EN_EXE_EXECUTE_APP_USB:
{
MApp_ZUI_ACT_InputSourceSwitch( _MApp_ZUI_ACT_GetSourceType() );
MApp_ZUI_ACT_TransitionEffectBegin(EN_EFFMODE_CLOSE, _ZUI_STATE_TERMINATE); enInputSourceState= STATE_INPUTSOURCE_GOTO_DMP;
}
return TRUE;
再执行到:
MApp_InputSource_Main
switch(enInputSourceState)
case STATE_INPUTSOURCE_GOTO_DMP:
MApp_ZUI_ACT_ShutdownOSD();
enInputSourceState = STATE_INPUTSOURCE_INIT;
enRetVal = EXIT_GOTO_DMP;
break;
再:
switch(MApp_InputSource_Main())
case EXIT_GOTO_DMP:
enTopState = STATE_TOP_DMP;
break;
执行:
MApp_DMP_Main
switch(m_enDmpVar.enDmpState)
case DMP_STATE_INIT:
srand(msAPI_Timer_GetTime0());
MApp_ZUI_ACT_StartupOSD(E_OSD_DMP);
_MApp_DMP_Switch2Dmp();
u32time = msAPI_Timer_GetTime0();
m_enDmpVar.enDmpState = DMP_STATE_CONNECTING;
u8GWinId = MApp_ZUI_API_QueryGWinID();
break;
case DMP_STATE_CONNECTING:
if(msAPI_Timer_DiffTimeFromNow(u32time) > DMP_WAITCONNECT_MS || m_enDmpVar.enDmpFlag & DMP_FLAG_DRIVE_CONNECT_OK) {
m_enDmpVar.enDmpState = DMP_STATE_UI;
}
break;
case DMP_STATE_UI:
MApp_DMP_NotifyUiState(m_enDmpVar.enDmpUiState);
m_enDmpVar.enDmpState = DMP_STATE_WAIT;
break;
我们再一直按右,执行:
switch(pMsg->wParam)
{
case VK_RIGHT:
MApp_ZUI_API_SetFocusByNav(focus, NAV_RIGHT);
break;
}
在影视选项上按OK,执行:
case EN_EXE_DMP_MEDIA_PAGE_SEL:
if(HWND_DMP_MEDIA_TYPE_MOVIE == MApp_ZUI_API_GetFocus())
{
// stop bgm
if(MApp_DMP_GetDmpFlag() & DMP_FLAG_BGM_MODE)
{
MApp_MPlayer_StopMusic();
MApp_DMP_ClearDmpFlag(DMP_FLAG_BGM_MODE);
}
MApp_MPlayer_SetCurrentMediaType(E_MPLAYER_TYPE_MOVIE, TRUE); MApp_DMP_UiStateTransition(DMP_UI_STATE_DRIVE_SELECT);
}
再执行:
case DMP_UI_STATE_DRIVE_SELECT:
{
#if (DMP_PHOTO_THUMBNAIL || DMP_MOVIE_THUMBNAIL)
_MApp_DMP_ThumbCopyRegion_Destroy();
MApp_MPlayer_LeaveThumbnailMode();
MApp_DMP_ClearDmpFlag(DMP_FLAG_THUMBNAIL_MODE);
#endif
U8 i;
for(i=0; i<NUM_OF_MAX_DRIVE; i++)
{
if(MApp_MPlayer_QueryCurrentDriveIndex()== MApp_DMP_GetDriveFromMappingTable(i))
{
MApp_DMP_SetCurDrvIdxAndCalPageIdx(i);
}
}
_MApp_ACTdmp_ShowDrivePage();
U8 u8Idx = (MApp_DMP_GetCurDrvIdx()+1) % DMP_DRIVE_NUM_PER_PAGE;
MApp_ZUI_API_SetFocus(_hwndListDriveItem[u8Idx]);
}
break;
好,现在进入了Drive选择界面。在该界面按右键,通过,Skin Tool里面定义的Navigation,跳转到了,第一个可供选择的Drive。
再在该界面按OK键,执行:
MApp_DMP_UiStateTransition(DMP_UI_STATE_FILE_SELECT);
再调用:MApp_DMP_NotifyUiState
就可以显示出文件列表页面了。
视频的播放流程,待续。