【第3版emWin教程】第55章 emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429

第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

本章节为大家讲解按钮控件自定义回调函数,通过其回调函数就可以实现各种按钮效果。这方面的问题也是经常有初学者问,所以专门做一期教程。

55.1 初学者重要提示

55.2 按钮控件自定义回调函数的实现方法

55.3 官方WIDGET_ButtonRound.c实例讲解

55.4 实验例程说明(RTOS)

55.5 实验例程说明(裸机)

55.6 总结

 

 

55.1 初学者重要提示

  1.   很多时候,我们希望设计出不同效果的按钮出来,比如做一个音乐播放器界面将快进,快退,暂停,开始等都通过按钮来实现,这个时候时候按钮的自定义回调函数就派上用场了。希望初学者掌握这个重要的知识点。不仅仅是按钮控件,后面要讲解到的其它控件都是可以设置自定义回调函数。
  2.   按钮控件的所有API函数在emWin手册中都有讲解,下图是中文版手册里面API函数位置:

 【第3版emWin教程】第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

下图是英文版手册里面API函数的位置:

 【第3版emWin教程】第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

 

55.2 按钮控件自定义回调函数的实现方法

按钮控件的本质也是窗口,所以也是有回调函数的,只是被封装了,用户看不到,不像我们使用窗口或者框架窗口的时候还需要专门的设置回调函数。

实现自定义回调函数的关键就是函数WM_SetCallback,通过这个函数就可以重定向按钮的回调函数,从而也就可以实现各种效果的按钮。下面我们通过一个实例给大家介绍如何实现按钮控件的自定义回调函数。完整代码在例子在本章教程配置的例子里面:

#include "DIALOG.h"


/*
*********************************************************************************************************
*                                         图片位图数据
*********************************************************************************************************
*/
static GUI_CONST_STORAGE unsigned long _acpic1[] = {
  0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 
        0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 
        0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 
        /* 后面的数据未列出 */
};

GUI_CONST_STORAGE GUI_BITMAP bmpic1 = { 
  64, // xSize
  64, // ySize
  256, // BytesPerLine
  32, // BitsPerPixel
  (unsigned char *)_acpic1,  // Pointer to picture data
  NULL,  // Pointer to palette
  GUI_DRAW_BMP8888
}

/*
*********************************************************************************************************
*                                         宏定义
*********************************************************************************************************
*/
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0   (GUI_ID_USER + 0x01)
#define ID_BUTTON_1   (GUI_ID_USER + 0x02)


/*
*********************************************************************************************************
*                           GUI_WIDGET_CREATE_INFO类型数组
*********************************************************************************************************
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = 
{
  { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  { BUTTON_CreateIndirect,   "",         ID_BUTTON_0, 30, 30, 64, 64, 0, 0x0, 0 },
  { BUTTON_CreateIndirect,   "",         ID_BUTTON_1, 30, 120, 120, 40, 0, 0x0, 0 },
};


/*
*********************************************************************************************************
*    函 数 名: _cbButton
*    功能说明: 按钮回调函数
*    形    参: pMsg  消息指针
*    返 回 值: 无
*********************************************************************************************************
*/
static void _cbButton(WM_MESSAGE * pMsg) //--------------(3)
{
    WM_HWIN  hWin;

    hWin  = pMsg->hWin;
    switch (pMsg->MsgId) 
    {
        case WM_PAINT:
            if (BUTTON_IsPressed(hWin)) 
            {
                GUI_SetBkColor(GUI_WHITE);
                GUI_Clear();
                GUI_SetAlpha(0xb0);
                GUI_DrawBitmap(&bmpic1, 0,0);
                GUI_SetAlpha(0);        
            } 
            else 
            {
                GUI_DrawBitmap(&bmpic1, 0, 0);        
            }
            break;
            
        default:
            BUTTON_Callback(pMsg);
    }
}

/*
*********************************************************************************************************
*    函 数 名: _cbButton1
*    功能说明: 按钮回调函数
*    形    参: pMsg  消息指针
*    返 回 值: 无
*********************************************************************************************************
*/
static void _cbButton1(WM_MESSAGE * pMsg)  //--------------(6)
{
    WM_HWIN  hWin;
    GUI_RECT Rect;
    hWin  = pMsg->hWin;

    switch (pMsg->MsgId) 
    {
        case WM_PAINT:
            WM_GetClientRect(&Rect);
            if (BUTTON_IsPressed(hWin)) 
            {
                GUI_SetColor(GUI_DARKGRAY);
                GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 5);
                GUI_SetBkColor(GUI_DARKGRAY);
                GUI_SetColor(GUI_WHITE); 
            } 
            else 
            {
                GUI_SetColor(GUI_LIGHTBLUE);
                GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 5);
                GUI_SetBkColor(GUI_LIGHTBLUE);
                GUI_SetColor(GUI_WHITE);   
            }
            
            GUI_SetFont(&GUI_Font16_ASCII);
            GUI_DispStringInRect("LED1", &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);
            break;
            
        default:
            BUTTON_Callback(pMsg);
    }
}

/*
*********************************************************************************************************
*    函 数 名: _cbDialog
*    功能说明: 对话框回调函数        
*    形    参: pMsg  回调参数 
*    返 回 值: 无
*********************************************************************************************************
*/
static void _cbDialog(WM_MESSAGE * pMsg) 
{
    WM_HWIN hItem;
    int     NCode;
    int     Id;

    switch (pMsg->MsgId) 
    {
        case WM_INIT_DIALOG:
            //
            // 初始化框架窗口
            //
            hItem = pMsg->hWin;
            FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
            FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
            FRAMEWIN_SetText(hItem, "armfly");
            
            //
            // 初始化按钮控件
            //
            hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
            WM_SetHasTrans(hItem);             //--------------(1)
            WM_SetCallback(hItem, _cbButton);  //--------------(2)


            //
            // 初始化按钮控件
            //
            hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
            WM_SetHasTrans(hItem);             //--------------(4)
            WM_SetCallback(hItem, _cbButton1); //--------------(5)
            break;

        case WM_NOTIFY_PARENT:
            Id    = WM_GetId(pMsg->hWinSrc);
            NCode = pMsg->Data.v;
            switch(Id) 
            {
                case ID_BUTTON_0: 
                    switch(NCode) 
                    {
                        case WM_NOTIFICATION_CLICKED:
                            break;

                        case WM_NOTIFICATION_RELEASED:
                            break;
                    }
                    break;
            }
            break;

        default:
        WM_DefaultProc(pMsg);
        break;
    }
}

/*
*********************************************************************************************************
*    函 数 名: CreateFramewin
*    功能说明: 创建对话框        
*    形    参: 无
*    返 回 值: 返回对话框句柄
*********************************************************************************************************
*/
WM_HWIN CreateFramewin(void) {
  WM_HWIN hWin;

  hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  return hWin;
}

/*
*********************************************************************************************************
*    函 数 名: MainTask
*    功能说明: GUI主函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
void MainTask(void) 
{
     /* 初始化 */
    GUI_Init();

    /* 窗口自动使用存储设备 */
    WM_SetCreateFlags(WM_CF_MEMDEV);

    /* 创建对话框,使用GUIBulder生成的对话框创建函数 */
    CreateFramewin();

    while(1)
    {
        GUI_Delay(10);
    }
}

这个例子在对话框上创建了2个按钮控件,每个按钮都重新设置了回调函数,实现了两种不同的按钮效果,一个是图标按钮,另一个是扁平化效果的按钮。

1、通过函数WM_SetHasTrans设置ID为ID_BUTTON_0的按钮控件的透明效果,调用了这个函数有什么用呢?通过这个函数就可以将按钮回调函数中WM_PAINT消息没有重绘到的区域显示为完全透明,比如我们在按钮控件回调函数的WM_PAINT消息里面绘制了一个填充的圆圈,那么按钮控件所在区域的圆圈以外部分就是完全透明的。

2、通过函数WM_SetCallback重新设置ID为ID_BUTTON_0的按钮控件的回调函数。

3、通过此回调函数就可以设置各种效果的按钮了,这里是将按钮设置成一个图标。这个回调函数只有两个消息,一个是WM_PAINT,一个是默认的default,也就是说除了WM_PAINT消息以外,其它所有消息还是使用按钮控件默认的回调处理机制BUTTON_Callback来实现。这个问题解释清楚了,剩下就是WM_PAINT消息里面实现的功能了,这个消息里面实现了按钮按下和未按下两种状态的显示效果,通过函数BUTTON_IsPressed来区分这两种状态,返回1就是按下了,返回0就是未按下。

/* 
按下状态,按下后,我们通过函数GUI_SetAlpha设置图片显示出来的透明效果,
这样就将按下和未按下两种状态区分开了。
*/
if (BUTTON_IsPressed(hWin)) 
{
/* 
先将按钮显示区清为白色,清为白色是因为按钮所在的对话框客户端窗口背景色是白色的 
       另一个作用是背景图片是要跟这个白色区域做alpha融合,所以要清成白色。
*/
    GUI_SetBkColor(GUI_WHITE);
    GUI_Clear();
     /* 设置图片的透明程度是0xb0,设置为0xFF表示完全透明,0x00表示完全不透明 */
    GUI_SetAlpha(0xb0);
    GUI_DrawBitmap(&bmpic1, 0,0);
     /* 显示完毕图片后设置为默认的完全不透明 */
    GUI_SetAlpha(0);        
} 
/* 未按下状态,显示一个图标 */
else 
{
    GUI_DrawBitmap(&bmpic1, 0, 0);        
}

通过上面的代码就实现了按钮未按下时显示的是一个图标,按下时是一个有透明效果的图标。

4、通过函数WM_SetHasTrans设置ID为ID_BUTTON_1的按钮控件的透明效果。

5、通过函数WM_SetCallback重新设置ID为ID_BUTTON_1的按钮控件的回调函数。

6、通过此回调函数就可以设置各种效果的按钮了,这里是将按钮设置成圆角矩形。这里我们重点看WM_PAINT消息,其它跟第3条讲解的是一样的。

/* 获取按钮的显示区坐标,即左上角坐标和右下角坐标 */
WM_GetClientRect(&Rect);

/* 按下状态,*/
if (BUTTON_IsPressed(hWin)) 
{
     /* 设置前景色用于绘制圆角矩形 */
    GUI_SetColor(GUI_DARKGRAY);
     /* 圆角矩形绘制函数 */
    GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 5);
    /* 设置背景色和前景色用于函数GUI_DispStringInRect 显示文本LED1使用 */
    GUI_SetBkColor(GUI_DARKGRAY);
    GUI_SetColor(GUI_WHITE); 
} 
/* 未按下状态  */
else 
{
/* 设置前景色用于绘制圆角矩形 */
    GUI_SetColor(GUI_LIGHTBLUE);
     /* 圆角矩形绘制函数 */
    GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 5);
     /* 设置背景色和前景色用于函数GUI_DispStringInRect 显示文本LED1使用 */
    GUI_SetBkColor(GUI_LIGHTBLUE);
    GUI_SetColor(GUI_WHITE);   
}
/* 设置文本显示字体 */
GUI_SetFont(&GUI_Font16_ASCII);
/* 将文本显示到按钮区域的垂直居中和水平居中 */
GUI_DispStringInRect("LED1", &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);

通过上面的代码就实现了按钮未按下和按下时两种不同的按钮颜色。实际显示效果如下,分辨率800*480:

 【第3版emWin教程】第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

通过学习这个实例,建议大家尝试设置各种其它的按钮显示效果。

55.3 官方WIDGET_ButtonRound.c实例讲解

这个DEMO在模拟器中的位置:

 【第3版emWin教程】第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

主要功能介绍:

这个例子演示了按钮自定义回调函数的实现,通过其回调函数实现了一个圆形的按钮,由于是官方做的例子,所以细节的处理上更专业些。学习这个例子前务必先学习前面47.2小节的讲解。

程序代码如下:

#include <stddef.h>
#include <string.h>
#include "WM.h"
#include "FRAMEWIN.h"
#include "BUTTON.h"

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
//
// Recommended memory to run the sample with adequate performance
//
#define RECOMMENDED_MEMORY (1024L * 5)

/*********************************************************************
*
*       Static data
*
**********************************************************************
*/
static int _Color;
static int _Font;
static int _Pressed;

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  { FRAMEWIN_CreateIndirect, "Round button sample", 0,      50,  60, 200, 120, FRAMEWIN_CF_MOVEABLE },
  { BUTTON_CreateIndirect,   "Button",   GUI_ID_BUTTON0,   100,  10,  80,  80 },
  { BUTTON_CreateIndirect,   "Callback", GUI_ID_BUTTON1,    10,  10,  60,  20 },
  { BUTTON_CreateIndirect,   "Font",     GUI_ID_BUTTON2,    10,  30,  60,  20 },
  { BUTTON_CreateIndirect,   "Color",    GUI_ID_BUTTON3,    10,  50,  60,  20 },
  { BUTTON_CreateIndirect,   "Cancel",   GUI_ID_CANCEL,     10,  70,  60,  20 }
};

/*********************************************************************
*
*       Static functions
*
**********************************************************************
*/
/*********************************************************************
*
*       _OnPaint
*
* Function description
*   Paints the owner drawn button
*/
static void _OnPaint(BUTTON_Handle hObj) { //--------------(1)
  int Index;
  char ac[50];
  GUI_RECT Rect;

  Index = (WIDGET_GetState(hObj) & BUTTON_STATE_PRESSED) ? 1 : 0; //--------------(2)
  WM_GetClientRect(&Rect); 
  //
  // Draw filled ellipse with button background color
  //
  GUI_SetColor(BUTTON_GetBkColor(hObj, Index));
  GUI_FillEllipse(Rect.x1 / 2, Rect.y1 / 2, Rect.x1 / 2, Rect.y1 / 2);
  //
  // Draw black shape
  //
  GUI_SetColor(GUI_BLACK);
  GUI_DrawEllipse(Rect.x1 / 2, Rect.y1 / 2, Rect.x1 / 2, Rect.y1 / 2);
  //
  // Draw button text with widget attributes
  //
  GUI_SetColor(BUTTON_GetTextColor(hObj, Index));
  GUI_SetBkColor(BUTTON_GetBkColor(hObj, Index));
  GUI_SetFont(BUTTON_GetFont(hObj));
  BUTTON_GetText(hObj, ac, sizeof(ac));
  if (_Pressed) {                              //--------------(3)
    strcpy(ac + strlen(ac), "\npressed");
  }
  GUI_DispStringInRect(ac, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);
}

/*********************************************************************
*
*       _cbButton
*
* Function description 
*  1. Calls the owner draw function if the WM_PAINT message has been send
*  2. Calls the original callback for further messages
*  3. After processing the messages the function evaluates the pressed-state
*     if the WM_TOUCH message has been send
*/
static void _cbButton(WM_MESSAGE * pMsg) {  //--------------(4)
  switch (pMsg->MsgId) {
    case WM_PAINT:                          //--------------(5)
      _OnPaint(pMsg->hWin);
      break;
    default:                                //--------------(6)
      BUTTON_Callback(pMsg); // The original callback
      break;
  }

  if (pMsg->MsgId == WM_TOUCH) {           //--------------(7)
    if (BUTTON_IsPressed(pMsg->hWin)) {
      if (!_Pressed) {
        _Pressed = 1;
      }
    } else {
      _Pressed = 0;
    }
  }
}

/*********************************************************************
*
*       _cbDialog
*
* Function description
*   Dialog callback routine
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
  int           NCode;
  int           Id;
  WM_HWIN       hDlg;
  BUTTON_Handle hButton;

  hDlg = pMsg->hWin;
  switch (pMsg->MsgId) {
    case WM_PAINT:
      WM_DefaultProc(pMsg); // Handle dialog items    //--------------(8)
      //
      // After drawing the dialog items add some user drawn items to the window
      //
      GUI_SetPenSize(10);
      GUI_SetColor(GUI_GREEN);
      GUI_DrawLine( 95,  5, 185, 95);
      GUI_SetColor(GUI_RED);
      GUI_DrawLine( 95, 95, 185,  5);
      break;
    case WM_INIT_DIALOG:
      hButton = WM_GetDialogItem(hDlg, GUI_ID_BUTTON0); 
      WM_SetHasTrans(hButton);              // Set transparency flag for button   //--------------(9)
      break;
    case WM_KEY:
      switch (((WM_KEY_INFO *)(pMsg->Data.p))->Key) {
        case GUI_KEY_ESCAPE:
          GUI_EndDialog(hDlg, 1);
          break;
        case GUI_KEY_ENTER:
          GUI_EndDialog(hDlg, 0);
          break;
      }
      break;
    case WM_NOTIFY_PARENT:
      Id    = WM_GetId(pMsg->hWinSrc);      // Id of widget
      NCode = pMsg->Data.v;                 // Notification code
      switch (NCode) {
        case WM_NOTIFICATION_RELEASED:      // React only if released  //--------------(10)
          hButton = WM_GetDialogItem(hDlg, GUI_ID_BUTTON0);
          if (Id == GUI_ID_BUTTON1) {       // Toggle callback //--------------(11)
            if (WM_GetCallback(hButton) == _cbButton) { 
              WM_SetCallback(hButton, BUTTON_Callback);
            } else {
              WM_SetCallback(hButton, _cbButton);
            }
            WM_InvalidateWindow(hButton);
          }
          if (Id == GUI_ID_BUTTON2) {       // Toggle font //--------------(12)
            if (_Font) {
              BUTTON_SetFont(hButton, &GUI_Font13_1);
            } else {
              BUTTON_SetFont(hButton, &GUI_Font8x16);
            }
            _Font ^= 1;
          }
          if (Id == GUI_ID_BUTTON3) {       // Toggle color //--------------(13)
            if (_Color) {
              BUTTON_SetBkColor(hButton, 0, 0xaaaaaa);
              BUTTON_SetBkColor(hButton, 1, GUI_WHITE);
              BUTTON_SetTextColor(hButton, 0, GUI_BLACK);
              BUTTON_SetTextColor(hButton, 1, GUI_BLACK);
            } else {
              BUTTON_SetBkColor(hButton, 0, GUI_BLUE);
              BUTTON_SetBkColor(hButton, 1, GUI_RED);
              BUTTON_SetTextColor(hButton, 0, GUI_WHITE);
              BUTTON_SetTextColor(hButton, 1, GUI_YELLOW);
            }
            _Color ^= 1;
          }
          if (Id == GUI_ID_OK) {            // OK Button //--------------(14)
            GUI_EndDialog(hDlg, 0);
          }
          if (Id == GUI_ID_CANCEL) {        // Cancel Button //--------------(15)
            GUI_EndDialog(hDlg, 1);
          }
          break;
      }
      break;
    default:
      WM_DefaultProc(pMsg);
  }
}

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       MainTask
*/
void MainTask(void) {
  GUI_Init();
  //
  // Check if recommended memory for the sample is available
  //
  if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
    GUI_ErrorOut("Not enough memory available."); 
    return;
  }
  //
  // Use memory devices for all windows
  //
  #if GUI_SUPPORT_MEMDEV
    WM_SetCreateFlags(WM_CF_MEMDEV);
    WM_EnableMemdev(WM_HBKWIN);
  #endif
  WM_SetDesktopColor(GUI_GREEN);
  while(1) {
    _Font = _Color = 0;
    GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, 0, 0, 0);
    GUI_Delay(1000);
  }
}

/*************************** End of file ****************************/
  1. 按钮自定义回调函数中WM_PAINT消息的处理。
  2. 通过函数(WIDGET_GetState(hObj) & BUTTON_STATE_PRESSED) ? 1 : 0返回当前按钮是按下还是未按下,按下的话,返回数值1,未按下返回数值0。根据这个返回值,在WM_PIANT消息里面绘制按钮按下和未按下两种状态的显示效果。
  3. 根据变量_Pressed的数值设置是否显示字符,如果变量数值非0表示按钮被按下,显示字符Button pressed,如果未按下,仅显示字符Button。变量_Pressed数值的改变是在按钮回调函数_cbButton里面修改的。其实这里直接使用第2条中函数(WIDGET_GetState(hObj) & BUTTON_STATE_PRESSED) ? 1 : 0的返回值就可以的,官方这里设计的稍有些啰嗦了。
  4. 按钮自定义的回调函数。
  5. 按钮自定义回调函数中WM_PAINT消息的处理。
  6. 按钮回调函数中,除了WM_PIANT消息,其它消息的处理继续使用系统默认的函数BUTTON_Callback(pMsg)来实现。
  7. 如果按钮被按下,回调函数首先收到的就是这个WM_TOUCH消息,然后才是WM_PAINT消息的处理,这样的话,就可以通过这个消息配合函数BUTTON_IsPressed(pMsg->hWin)来设置变量_Pressed,赋值为1表示按下,赋值为0表示未按下。
  8. 函数WM_DefaultProc(pMsg)放在这里比较巧妙,先调用这个函数的话,系统就会按照默认配置先重绘对话框,然后用户在这个基础上再绘制自己需要的内容。
  9. 通过函数WM_SetHasTrans设置ID为GUI_ID_BUTTON0的按钮控件的透明效果。
  10. 按钮释放后的消息处理。
  11. 按钮ID为GUI_ID_BUTTON1的按钮释放消息处理,这里实现对ID为GUI_ID_BUTTON0按钮的回调函数切换。
  12. 按钮ID为GUI_ID_BUTTON2的按钮释放消息处理,这里实现对ID为GUI_ID_BUTTON0按钮显示字体的切换。
  13. 按钮ID为GUI_ID_BUTTON3的按钮释放消息处理,这里实现对ID为GUI_ID_BUTTON0按钮显示文本的背景色和前景色的切换。
  14. 按钮ID为GUI_ID_OK的按钮释放消息处理,此按钮在本程序未用到,因为没有创建ID为GUI_ID_OK的按钮。
  15. 按钮ID为GUI_ID_CANCEL的按钮释放消息处理,这里实现关闭阻塞式对话框。如果关闭了,1秒后会重新创建这个对话框,如此循环。

显示效果如下:

【第3版emWin教程】第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

 

55.4 实验例程说明(RTOS)

配套例子:

V7-574_emWin6.x实验_Button按钮控件通过自定义回调函数实现各种按钮消息(RTOS)

实验目的:

  1. 本实验主要学习通过按钮自定义回调函数实现各种按钮效果。这里实现了两种按钮效果,一个是图标按钮,一个是扁平化效果的按钮。
  2. emWin功能的实现在MainTask.c文件里面。

实验内容:

1、K1按键按下,串口或者RTT打印任务执行情况(串口波特率115200,数据位8,奇偶校验位无,停止位1)。

2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。

(2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。

3、默认上电是通过串口打印信息,如果使用RTT打印信息:

MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可

#define Enable_RTTViewer  1

4、各个任务实现的功能如下:

App Task Start   任务 :启动任务,这里用作BSP驱动包处理。

App Task MspPro任务 :消息处理,这里用作LED闪烁。

App Task UserIF  任务 :按键消息处理。

App Task COM   任务 :暂未使用。

App Task GUI    任务 :GUI任务。

μCOS-III任务调试信息(按K1按键,串口打印):

【第3版emWin教程】第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果 

RTT 打印信息方式:

【第3版emWin教程】第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果 

程序设计:

任务栈大小分配:

μCOS-III任务栈大小在app_cfg.h文件中配置:

#define  APP_CFG_TASK_START_STK_SIZE                      512u

#define  APP_CFG_TASK_MsgPro_STK_SIZE                     2048u

#define  APP_CFG_TASK_COM_STK_SIZE                        512u

#define  APP_CFG_TASK_USER_IF_STK_SIZE                    512u

#define  APP_CFG_TASK_GUI_STK_SIZE                        2048u

任务栈大小的单位是4字节,那么每个任务的栈大小如下:

App Task Start   任务 :2048字节。

App Task MspPro任务 :8192字节。

App Task UserIF  任务 :2048字节。

App Task COM   任务 :2048字节。

App Task GUI    任务 :8192字节。

系统栈大小分配:

μCOS-III的系统栈大小在os_cfg_app.h文件中配置:

#define  OS_CFG_ISR_STK_SIZE                      512u     

系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB

emWin动态内存配置:

GUIConf.c文件中的配置如下:

#define EX_SRAM   1/*1 used extern sram, 0 used internal sram */

#if EX_SRAM
#define GUI_NUMBYTES  (1024*1024*24)
#else
#define GUI_NUMBYTES  (100*1024)
#endif

通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

#define  EX_SRAM     1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

#define  EX_SRAM     0 表示使用内部SRAM作为emWin动态内存,大小100KB。

默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

emWin界面显示效果:

800*480分辨率界面效果。

 【第3版emWin教程】第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

 

55.5 实验例程说明(裸机)

配套例子:

V7-573_emWin6.x实验_Button按钮控件通过自定义回调函数实现各种按钮消息(裸机)

实验目的:

  1. 本实验主要学习通过按钮自定义回调函数实现各种按钮效果。这里实现了两种按钮效果,一个是图标按钮,一个是扁平化效果的按钮。
  2. emWin功能的实现在MainTask.c文件里面。

emWin界面显示效果:

800*480分辨率界面效果。

【第3版emWin教程】第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果 

emWin动态内存配置:

GUIConf.c文件中的配置如下:

#define EX_SRAM   1/*1 used extern sram, 0 used internal sram */

#if EX_SRAM
#define GUI_NUMBYTES  (1024*1024*24)
#else
#define GUI_NUMBYTES  (100*1024)
#endif

通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

#define  EX_SRAM     1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

#define  EX_SRAM     0 表示使用内部SRAM作为emWin动态内存,大小100KB。

默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

55.6 总结

本章节主要为大家讲解了按钮控件自定义回调函数的实现方法,对于这种方法,望初学者一定要掌握,后面章节学习其它控件做自定义回调函数,方法是相同的。

 

上一篇:The Path to Learning WR Python FPE.3


下一篇:springboot DispatcherServlet