查看: 2984|回复: 2

[分享] 如何实现emWin按键窗体消息响应

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32003
    最后登录
    2024-4-9
    发表于 2021-3-25 10:21:28 | 显示全部楼层 |阅读模式
    如何实现emWin按键窗体消息响应
    前言

    十年之前,随着NXP带内置LCD控制器系列LPC的推出,emWin成了当年的“流量小鲜肉”。如今,MCU越做越高端,GUI应用越来越多,GUI软件也如雨后春笋般涌现,emWin变成“老腊肉”了。而且,乍看也会觉得这个话题“如何实现按键窗体消息响应”,很基础很简单呢——是很基础但或许并不如想象那么简单。


    想聊此话题的直接原因是有人来咨询过。一些刚开始用emWin的工程师首先自然就是找我们的SDK例程参考,但我们的SDK没提供此例程。而emWin提供的例程和手册太“浩瀚”了,对于入门者亦难查找。
    当年我们推广时期做的各种培训资料,也未介绍过。因此,感觉还是有必要讲讲,给初步使用的单片机工程师一个指引,以少走弯路。
    emWin一瞥

    首先,我们先简单过一下emWin相关背景知识。
    emWin是一款由Segger公司提供的,用于嵌入式系统的GUI(图形用户界面)软件。它是属于中间件,即不依赖于处理器和显示控制器。


    在我们提供的有内置LCD控制器的MCU的SDK中,都提供了emWin的例程。


    emWin是可根据应用需求配置搭建的。且配套提供了些小工具,比如图形转C文件,可视化开发工具等等……


    本文介绍内容和窗体管理有关,而emWin的窗体管理基本框架是窗体消息处理机制,简单说,就是某个窗体内的事务处理,都是将各个事件作为窗体消息来响应执行,比如,本文要聊的按键响应。

    按钮窗体消息响应

    先问问各位,上图是不是就是本文要介绍的“按键”呢?—— 非也。


    先让我们区分此概念。在emWin窗体管理中,有一个易于与按键混淆的“李鬼“——按钮(button)。它和按键(key)是不同的。
    按钮是窗体管理中的一个控件(如上图就是大家熟悉的一个很典型的‘OK’按钮)。使用者看到的是它直接显示在屏幕上,通过触摸屏,点击它来进行交互。
    它的实现很简单,也提供了很多实现例程(可能因为直接点击屏幕更显“高大上”)。它的一个简单实现方法是通过可视化开发工具,将按钮控件直接放置/拖入窗体中,就能直接产生窗体按钮消息响应相关的C代码。而按键消息的响应则不同,详情见下节。

    按键窗体消息响应

    虽然点击屏幕上按钮的交互更“时尚”,但是不少产品也提供了外部按键来结合GUI窗体进行人机交互。


    那么,如何实现按键窗体消息响应呢?这主要包含两个环节:
    一、传递按键消息给窗体
    这可通过emWin提供的以下API:


    GUI_SendKeyMsg(int Key, int Pressed)来进行。它的参数定义如下:
    25.png
    其中的按键码正是来自硬件驱动层,这个emWin API和硬件驱动层接口,驱动层扫描到按键事件,获取到按键码,即可赋给Key参数,通过此API将按键消息传递给窗体。


    接下来是如何实现窗体响应这个按键消息。
    二、窗体响应按键消息
    前面提到,emWin GUI的窗体管理基本框架是消息响应机制。它的基本API是一个窗体回调函数,通过它来实现窗体管理,包括消息响应。
    其中一个基本数据结构就是消息数据结构体,主要包含了消息类型和数据,来响应各类消息,比如,最基本的WM_CREATE消息类型,通过它对当前窗体进行初始化;WM_PAINT,来刷新显示当前窗体。
    而按键消息类型定义为WM_KEY,具体的按键码则通过消息结构体的数据指针Data.p来传递。
    这样,就可以响应处理不同的按键事件了。
    下面通过一个实例来感性体验如何实现按键的窗体消息响应的:

    假如从底层硬件驱动层,获取到了一个按键码KEY_CODE1,通过如下调用传递按键消息GUI_SendKeyMsg(KEY_CODE1, 1),并在某窗体回调函数中做如下实现即可:
    1. static void WinCallback(WM_MESSAGE* pMsg)
    2. {
    3.    WM_KEY_INFO* key_flag;

    4.    switch (pMsg->MsgId)
    5.    {
    6.       case WM_CREATE:
    7.       {
    8.          ……
    9.       }
    10.       break;
    11.       case WM_PAINT:
    12.       {
    13.         ……
    14.       }
    15.       break;
    16.       case WM_KEY:
    17.       {
    18.          key_flag = (WM_KEY_INFO * )(pMsg->Data.p);
    19.          {
    20.             switch(key_flag->PressedCnt)
    21.             {  /*注:对应于由GUI_SendKeyMsg()传递的按键状态*/
    22.                 case 0:
    23.                 {
    24.                        
    25.                 }
    26.                 break;
    27.                        
    28.                 case 1: /*按下状态*/
    29.                    switch(key_flag->Key) /*以下响应各个按键事件消息*/
    30.                    {
    31.                       case KEY_CODE1:
    32.                       {
    33.                          /*对按键码KEY_CODE1进行处理*/
    34.                       }
    35.                    …… (以下省略)
    复制代码
    一点拓展


    实际上,以上对外部按键的窗体消息响应实现方法,同样适用于其他类似的外部输入事件,比如旋钮的实现方法也一样,在硬件驱动层获取到旋钮码值后,通过以上方式传递和响应处理。

    签到签到
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-10 22:38
  • 签到天数: 1335 天

    [LV.10]以坛为家III

    88

    主题

    4292

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9049
    最后登录
    2024-4-13
    发表于 2021-3-25 10:49:34 | 显示全部楼层
    这种将消息处理回调函数绑定到控件上面,我觉得非常实用。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    72

    帖子

    0

    注册会员

    Rank: 2

    积分
    78
    最后登录
    2023-1-28
    发表于 2022-11-6 21:00:28 | 显示全部楼层
    本帖最后由 kwcha333 于 2022-12-31 20:09 编辑

    感谢分享









    維修快
    電腦 維修 價目價格公道且實惠,不會無故加收除上門檢查費、零件費和基本維修費等額外的費用
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-19 22:20 , Processed in 0.130746 second(s), 24 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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