硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4026|回复: 4
收起左侧

[emWin] 注意函数GUI_SendKeyMsg和GUI_StoreKeyMs的区别

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115728
QQ
发表于 2016-11-27 02:35:42 | 显示全部楼层 |阅读模式
先来看下我们新版教程的说明:
7.png

===============================
为什么函数GUI_SendKeyMsg不能在中断里面调用,且看下面早期UCGUI3.98的源码
/*********************************************************************
*
*       GUI_StoreKeyMsg
*/
void GUI_StoreKeyMsg(int Key, int PressedCnt) {
  #if GUI_WINSUPPORT    /* If 0, WM will not generate any code */
  _KeyMsg.Key = Key;
  _KeyMsg.PressedCnt = PressedCnt;
  _KeyMsgCnt = 1;
  #ifdef GUI_X_ON_UNPROCESSED_KEY
    if (!WM_IsActive) {
      /* If the WM is deactivated, key messages are not polled by the WM.
         So call the macro in this case here.
      */
      GUI_X_ON_UNPROCESSED_KEY(Key, PressedCnt);
    }
  #endif
  GUI_X_SIGNAL_EVENT();
  #else
    GUI_USE_PARA(PressedCnt);
    GUI_StoreKey(Key);
    #ifdef GUI_X_ON_UNPROCESSED_KEY
      GUI_X_ON_UNPROCESSED_KEY(Key, PressedCnt);
    #endif
  #endif
}
/*********************************************************************
*
*       GUI_SendKeyMsg
*
* Purpose:
*   Send the key to a window using the window manager (if available).
*   If no window is ready to take the input, we call the store routine
*   and wait for somebody to poll the buffer.
*/
void GUI_SendKeyMsg(int Key, int PressedCnt) {
  #if GUI_WINSUPPORT    /* If 0, WM will not generate any code */
    if (!WM_OnKey(Key, PressedCnt)) {
      #ifdef GUI_X_ON_UNPROCESSED_KEY
        GUI_X_ON_UNPROCESSED_KEY(Key, PressedCnt);
      #endif
      GUI_StoreKeyMsg(Key, PressedCnt);
    }
  #else
    GUI_StoreKeyMsg(Key, PressedCnt);
  #endif
}


其中的关键就在函数WM_OnKey里面了,这个函数里面有调用GUI锁,而锁的实现是基于RTOS的pend函数
这些函数一般都是不允许在中断里面调用的。
/*********************************************************************
*
*       WM_OnKey


  Returns:
    0 if message could not be handled
*/
int WM_OnKey(int Key, int Pressed) {
  int r = 0;
  WM_MESSAGE Msg;
  WM_LOCK();
  if (WM__hWinFocus != 0) {
    WM_KEY_INFO Info;
    Info.Key = Key;
    Info.PressedCnt = Pressed;
    Msg.MsgId = WM_KEY;
    Msg.Data.p = &Info;
    WM__SendMessage(WM__hWinFocus, &Msg);
    r = 1;
  }
  WM_UNLOCK();
  return r;
}


上面这个函数WM__SendMessage会直接执行被聚焦窗口的回调函数,所以
用于调用函数GUI_SendKeyMsg会让聚焦的窗口的按键消息得到立即执行,这点特别注意:
/*********************************************************************
*
*       WM__SendMessage
*/
void WM__SendMessage(WM_HWIN hWin, WM_MESSAGE* pMsg) {
  static int _EntranceCnt;
  WM_Obj* pWin;
  if (_EntranceCnt < GUI_MAX_MESSAGE_NESTING) {
    pWin = WM_HANDLE2PTR(hWin);
    pMsg->hWin = hWin;
    if (pWin->cb != NULL) {
      _EntranceCnt++;
      (*pWin->cb)(pMsg);
      _EntranceCnt--;
    } else {
      WM_DefaultProc(pMsg);
    }
  }
  #if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_PARA
  else {
    GUI_DEBUG_ERROROUT("Max. message nesting exceeded, Message skipped.");
  }
  #endif
}
回复

使用道具 举报

354

主题

2164

回帖

3231

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3231
发表于 2016-11-27 09:46:09 | 显示全部楼层
啊?以前没有特别关注呢。
回复

使用道具 举报

268

主题

597

回帖

1401

积分

至尊会员

积分
1401
发表于 2016-11-27 10:15:47 | 显示全部楼层
应该是有控件焦点时,用GUI_SendKeyMsg()发送至指定控件
没有焦点时,会用GUI_StoreKeyMsg()存储至缓冲
回复

使用道具 举报

3

主题

22

回帖

31

积分

新手上路

积分
31
发表于 2016-11-29 17:14:21 | 显示全部楼层
在多任务情况下,如果UI主任务和按键任务相互独立,那么在按键任务中调用GUI_SendKeyMsg会导致死机,而GUI_StoreKeyMsg不会。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115728
QQ
 楼主| 发表于 2016-11-30 11:05:05 | 显示全部楼层
已更新。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-14 18:53 , Processed in 0.244827 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表