• emWin(ucGUI)在PC机上模拟的按键响应多次解决办法 worldsing


    emWin(ucgui) 在PC端的模拟器,默认的按键机制是"按抬都Msg",当在按下键盘时,会收到一个key值-1,在按键没有离开时一直维持,当按键松开时还发送一个key值-0的标记。所以在你手速多快的情况下都会有一个 key,1和key,0两个操作。程序中没有对按键的状态做判定,所以在PC上不管是按下,还是按下后离开都会进行响应(两次响应)。

     

    假设有以下的应用场景,一级菜单->(ENTER键)->二级菜单>(ENTER键)->三级菜单,即,在一级菜单是可以用ENTER键进入二级菜单,同样在二级菜单可以用ENTER键进入三级菜单,实现的方式是:响应ENTER键的消息,然后切换菜单。

    /*******************************************************************************

    * Function Name :WIN_Enter

    * Description :进入下一级窗口

    * Input :int id:把进入的ID号

    * Output :void

    * Other :

    * Date :2013/06/02

    *******************************************************************************/

    int WIN_Enter(int id)

    {

    ELEM_BLOCK_TYPE *pElem;

    MENU_INFO_ITEM *pInfo;

    MENU_INFO_ITEM *pCur; //当前的窗口

    WIN_ContextLock();

    if (m_WinList.index < 1) //窗口调度没有初始化

    goto ext;

    if (m_WinList.index >= WIN_LEVEL_LAYER_COUNT - 1)//窗口深度超出最大范围

    goto ext;

    pElem = &m_WinList.elem[m_WinList.index - 1]; //获得当前窗口

    pCur = pInfo = pElem->menu;

    pInfo = BT_GetRightChild(pInfo); //获取下级窗口

    pInfo = BT_GetLChildElem(pInfo, *(int *)id);

    if (pInfo == NULL) //无下级窗口

    goto ext;

    if (pInfo->data == NULL) //下级窗口元素为空

    goto ext;

    pElem->ret.id = *(int *)id; //保存所进入的ID

    if (pInfo->data->win == NULL) //下级窗口无窗口数据

    goto end;

    if (pCur->data->win->destroy) //销毁当前窗口

    (*pCur->data->win->destroy)(NULL);

    if (pInfo->data->win->create) //新窗口建立

    (*pInfo->data->win->create)(pInfo);

    m_WinList.elem[m_WinList.index++].menu = pInfo; //保存新窗口到窗口列表中

    end:

    WIN_ContextUnlock();

    if (pInfo->data->enter) {

    (*pInfo->data->enter)(&id);

    }

    return OK;

    ext:

    WIN_ContextUnlock();

    return FALSE;

    }

     

     

    以上代码是通过提前构造少的菜单树结构,然后在菜单节点响应ENTER键和ESC键完成进入和退出,从代码上看不出有什么问题了,但是在PC实际仿真的过程成发现,在一级菜单按下ENTER键时进入二级菜单,紧接着进入三级菜单。

     

     

     

    所有需要对ENTER键进行判断响应,每次按下ENTER键就响应一次:

    case WM_KEY:

            switch (((WM_KEY_INFO *)(pMsg->Data.p))->Key){

                case GUI_KEY_ENTER:

                 if(((WM_KEY_INFO *)(pMsg->Data.p))->PressedCnt == 0)

                     WIN_Enter(0);

                 break;

            }

         break;

  • 相关阅读:
    进入正在运行的Docker的asp.net core容器
    EF 更新记录发现外键更改但更新又跳回以前值
    远程获取http数据和提交数据
    C# 32位16进制加密
    netcore命令行运行程序
    MD5加密32位16进制
    C# MD5加密32位16进制有时少一位问题
    netcoreMVC中使用Vue模板分页封装(不适合数据量大)
    Vue组件间传值 和 访问
    jenkins部署安装
  • 原文地址:https://www.cnblogs.com/worldsing/p/4165919.html
Copyright © 2020-2023  润新知