制作emwin个性化控件

在之前的某个项目中用到了emwin图形库,有些想要的效果官方的控件无法实现,所以就研究了一下,自己做了几个可以嵌入到emwin官方库的控件.

本文实现的check button和这个有些像(原谅我随便在网上截了个图,硬件暂时不在,等硬件到了会补)没有选中是是一个空心框,选中后是一个实心框,功能和emwin中的checkbox相同,可以认为是checkbox的重写版本,相对官方控件这个更大比较适合触屏的界面,风格也简洁些,更没有旁边一坨丑了吧唧的文字。接口命名和官方保持一致,支持xx_CreateEx和资源列表等所有控件创建方式,还有一些常用参数设置函数。

Check button继承自父控件windows,通过覆盖windows的callback函数实现自定义效果,除父控件windows自身的参数外, check button新增加的相关数据通过userdata的方式存储,另外还需实现check button自身xx_GetUserData和xx_SetUserData函数,用于check button的子类派生。

Checkbutton自身参数结构体如下,主要是控件尺寸和颜色,及开关状态信息。

控件直接创建函数如下,主要是通过传来的参数创建了一个window控件,控件回调使用checkbutton默认回调函数。

注意127行,这个是check button的默认参数,在未设置check button显示参数时会使用这组值。

下面是以资源列表方式创建check button控件的入口函数,相对复杂一点,因为emwin会传入一个资源列表的结构体,需要从结构体中提取出需要的参数。

我们再来看看核心的回调函数是如何实现的

/*********************************************************************
*
*       CheckButton工具默认回调函数
*/
void CHECKBUTTON_Callback(WM_MESSAGE *pMsg)
{
//  WM_HWIN hItem;
//  int     NCode;
//  int     Id;
  static unsigned char tsign=0;
  GUI_RECT area;
  GUI_PID_STATE *pPID;
  CHECK_BUTTON_ITEM RBItem;
  
  WINDOW_GetUserData(pMsg->hWin,&RBItem,sizeof(CHECK_BUTTON_ITEM));//获取自定义数据
  

  switch (pMsg->MsgId) {
  
  case WM_TOUCH:
    pPID=(GUI_PID_STATE *)pMsg->Data.p;
    //点击事件
    if(pPID->Pressed==1)
    {
      //检查是否首次点击
      if(tsign==0)
      {
        WM_NotifyParent(pMsg->hWin,WM_NOTIFICATION_CLICKED);  //发送点击消息
        tsign=1;
        
        //切换状态
        if(RBItem.SWITCH_STATUS==CHECKBUTTON_ON)
          RBItem.SWITCH_STATUS=CHECKBUTTON_OFF;
        else if(RBItem.SWITCH_STATUS==CHECKBUTTON_OFF)
          RBItem.SWITCH_STATUS=CHECKBUTTON_ON;
        //写入数据
        WINDOW_SetUserData(pMsg->hWin,&RBItem,sizeof(CHECK_BUTTON_ITEM));  //写入具体数据
        WM_InvalidateWindow(pMsg->hWin);  //无效化窗口
        WM_NotifyParent(pMsg->hWin,WM_NOTIFICATION_VALUE_CHANGED);  //发送选择更改消息
      }
    }
    //释放事件
    if(pPID->Pressed==0)
    {
      WM_NotifyParent(pMsg->hWin,WM_NOTIFICATION_RELEASED);  //发送释放消息
      tsign=0;//归零点击标志
    }
    break;
  case WM_PAINT:
    //关闭状态时
    if(RBItem.SWITCH_STATUS==0)
    {
      //绘制空白区域
      GUI_SetColor(RBItem.BACK_COLOR);
      area.x0=1;
      area.x1=RBItem.WIN_XSIZE-2;
      area.y0=1;
      area.y1=RBItem.WIN_YSIZE-2;
      GUI_FillRectEx(&area);
      //绘制边框
      GUI_SetColor(RBItem.BORDER_COLOR);
      area.x0=0;
      area.x1=RBItem.WIN_XSIZE-1;
      area.y0=0;
      area.y1=RBItem.WIN_YSIZE-1;
      GUI_DrawRectEx(&area);
    }
    //开启状态时
    else if(RBItem.SWITCH_STATUS==1)
    {
      //绘制空白区域
      GUI_SetColor(RBItem.BACK_COLOR);
      area.x0=1;
      area.x1=RBItem.WIN_XSIZE-2;
      area.y0=1;
      area.y1=RBItem.WIN_YSIZE-2;
      GUI_FillRectEx(&area);
      //绘制中心矩形
      GUI_SetColor(RBItem.CENTER_COLOR);
      area.x0=2;
      area.x1=RBItem.WIN_XSIZE-3;
      area.y0=2;
      area.y1=RBItem.WIN_YSIZE-3;
      GUI_FillRectEx(&area);
      //绘制边框
      GUI_SetColor(RBItem.BORDER_COLOR);
      area.x0=0;
      area.x1=RBItem.WIN_XSIZE-1;
      area.y0=0;
      area.y1=RBItem.WIN_YSIZE-1;
      GUI_DrawRectEx(&area);
    }
    break;
  case WM_DELETE:
    break;
  default:
    BUTTON_Callback(pMsg);
    break;
  }
}

 

回调函数入口处会首先提取自己的私有数据,然后主要需要处理两个消息事件,分别是WM_TOUCH和WM_PAINT,这里采用事件处理和显示刷新分离的方式,当有鼠标或者触屏点击控件时,emwin会向callback发送WM_TOUCH消息,callback通过读取私有数据中控件事件状态和WM_TOUCH消息中具体内容完成事件处理,并把处理结果写回到私有数据中,随后通过WM_InvalidateWindow向调度器发送失效消息无效化自己的显示,并通过WM_NotifyParent向父窗口发送WM_NOTIFICATION_VALUE_CHANGED消息告知父窗口自己的状态已经发送了改变。到这里就完成了事件处理的部分,随后开始显示刷新,emwin在接收到无效化消息并处理完其他的事件后,会再次向窗口发送WM_PAINT消息,然后又是一轮相似的操作,读私有数据,根据数据刷新显示,到这里屏幕上控件显示就已经变化了,一次输入事件处理完成。

除WM_TOUCH和WM_PAINT外,callback还需处理WM_DELETE消息,主要是避免窗口的缺省函数乱删东西,缺省函数使用的BUTTON_Callback,因为我测试发现使用WINDOWS_Callback有时会出现问题,所以使用了一个现成控件的。

核心的部分讲完了,其他的就是一些补充的函数。

Check button用于派生子类的两个函数,子控件可以通过使用xx_GetUserData和xx_SetUserData继承check button全部特征并实现自身特征。

两个和参数读写有关的函数,CHECKBUTTON_GetState和CHECKBUTTON_SetState,其他的参数读写函数,比如说设置边框颜色,设置中心颜色,间距,宽度等等也都是大同小异。

控件使用的方式和emwin官方的控件完全一样,可以直接在资源列表中插入一个check button控件,然后正常使用即可。

到这里制作emwin控件就算基本讲完了,check button控件是一种相对来说比较简单的控件,所有我以它为例讲解了一下控件实现的大体结构,以后有时间可能会讲解一下其他比较复杂的控件。

源码链接:https://download.csdn.net/download/CSDN1344789841/15611114

文章链接:https://blog.csdn.net/CSDN1344789841/article/details/114435225

转载需标明出处

### 推荐的STM32 UI设计软件 对于STM32单片机的用户界面(UI)设计,存在多种工具可以帮助开发者创建直观且高效的图形化用户界面。以下是几种常用的STM32 UI设计软件: #### 1. TouchGFX TouchGFX 是一款专为嵌入式系统设计的强大GUI开发框架,特别适合于基于ARM Cortex-M内核的微控制器,包括STM32系列。该工具提供了丰富的控件库、动画效果以及优化后的渲染引擎,能够显著提升用户体验。 - **特点**: - 支持多语言显示 - 提供可视化编辑器以便快速构建界面布局 - 集成了字体生成功能以适应不同分辨率屏幕需求 ```cpp // 示例:初始化TouchGFX应用 #include "touchgfx/Platform.hpp" using namespace touchgfx; void setup() { Platform::setup(); } ``` [^1] #### 2. Embedded Wizard Embedded Wizard是一款专业的嵌入式图形用户界面开发环境,适用于各种类型的MCU和MPU设备。它允许设计师通过拖拽组件来轻松搭建复杂的UI场景,并可通过代码自动生成机制将其无缝集成至目标平台上运行。 - **特点**: - 所见即所得(WYSIWYG)的设计模式简化了原型制作过程 - 自动生成C/C++源文件方便移植到实际产品中去 - 内置模拟器可以在不依赖真实硬件的情况下预览最终效果 [^2] #### 3. emWin (Segger) emWin是由SEGGER公司推出的轻量级而高效的小型操作系统配套使用的窗口管理库之一。此解决方案不仅限于特定品牌处理器,但针对STM32有着良好的适配性和性能表现,在资源受限环境下仍保持流畅操作体验。 - **特点**: - 占用极低内存空间从而节省成本开支 - 可定制性强满足个性化外观要求 - 完善的技术文档和支持体系帮助解决问题 [^3]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值