STemwin 实现滑动切换主页 滑动翻页 滑动解锁功能

STM32上实现类似iPhone的解锁和滑屏功能,emwin这个库官方的文档中控件没有一样的,但是有一个上下滑动的,基本上能够完成大致上的功能,但是如果想使用emwin实现类似的效果的话,需要懂这些知识点:

1、内存设备的使用

2、窗口的建立和消息

3、总之需要熟悉这个库的使用

由于本次测试中没有使用到外部SRAM,使用的单一的内部RAM,所以壁纸没有使用内存缓存下来,使用的单调色,基本上还算比较流畅,下面是代码正文,有兴趣的朋友可以参考下。

下面是我自己做的效果视频:

STemwin 实现滑动解锁 翻转主页

摇杆界面的控制视频

主页代码

/*********************************************************************
*                                                                    *
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
*                                                                    *
**********************************************************************
*                                                                    *
* C-file generated by:                                               *
*                                                                    *
*        GUI_Builder for emWin version 5.32                          *
*        Compiled Oct  8 2015, 11:59:02                              *
*        (c) 2015 Segger Microcontroller GmbH & Co. KG               *
*                                                                    *
**********************************************************************
*                                                                    *
*        Internet: www.segger.com  Support: support@segger.com       *
*                                                                    *
**********************************************************************
*/

// USER START (Optionally insert additional includes)
// USER END

#include "DIALOG.h"
#include "GUI_app/gui_thread.h"
#include "GUI.h"
#include "LCD/lcd.h"
#include "config.h"

/*********************************************************************
*
*       注意
*  1、所有图标必须是正方形
*
**********************************************************************
*/

/*********************************************************************
*
*       user config
*
**********************************************************************
*/

#define MAIN_PAGE_SMILE_ICON_Y0   (LCD_ysize/2-STATUS_BAR_HEIGHT)   //笑脸图标的中心点Y方向
#define VIEW_ICON_BK_COLOR        0x00FFC880
#define ICON_BAR_BK_COLOR         0x00F0e6c8
#define ICON_SELECTED_COLOR       (0x22uL<<24)|GUI_LIGHTBLUE
/********VIEW_ICON********/
//锁定画面尺寸定义
#define VIEW_ICON_RATE      0.72f                            //解锁条在界面的比例位置
#define VIEW_ICON_X         0
#define VIEW_ICON_Y         STATUS_BAR_HEIGHT               //滑动图标区的Y起点
#define VIEW_ICON_XSIZE     (LCD_xsize-VIEW_ICON_X)
#define VIEW_ICON_YSIZE     (int)((LCD_ysize-VIEW_ICON_Y)*VIEW_ICON_RATE)
#define VIEW_SCREEN_YSIZE   (LCD_ysize-VIEW_ICON_Y)         //主页的Y尺寸

//显示控制参数
#define VIEW_ICON_POSITIONING_VALUE  6       //复位定位值
#define VIEW_ICON_REFRESH_RATE 5  //主页VIEW_ICON更新率
//图标和主页数量
#define MAIN_PAGE_NUM     2       //主页的数量
#define ICON_NUM_X        3       //每行图标个数
#define ICON_NUM_Y        3       //每列图标个数
#define ICON_X_INTERVAL   10      //每行图标间隔
#define ICON_Y_INTERVAL   10      //每列图标间隔

#define ICON_NUM          (ICON_NUM_X*ICON_NUM_y)   //单页支持的最大图标数量
#define VIEW_ICON_EDGE_XSIZE    0       //图标被选中后的边框距离,单位像素
#define VIEW_ICON_EDGE_YSIZE    4       //图标被选中后的边框距离,单位像素
#define TEXT_EDGE_SIZE    2       //文本和位图间距,单位像素
#define VIEW_ICON_TEXT_OFFSET    2       //文本偏移
#define TEXT_FONT         GUI_FONT_6X8_ASCII  //使用字体
  
//调试
#define VIEW_DEBUG        0

/********ICON_BAR********/
#define ICON_BAR_X         0
#define ICON_BAR_Y         (VIEW_ICON_Y+VIEW_ICON_YSIZE)    //图标条的Y起点,相对于LCD
#define ICON_BAR_XSIZE     (LCD_xsize-ICON_BAR_X)
#define ICON_BAR_YSIZE     (LCD_ysize-ICON_BAR_Y)

#define ICON_BAR_OUTSIDE_INTERVAL      30     	//图标区域X间距
#define ICON_BAR_MIDDLE_INTERVAL      10     	//图标区域X间距
#define ICON_BAR_Y_INTERVAL      10    	//图标区域y间距

#define ICON_BAR_REFRESH_RATE 1000  	//主页 ICON_BAR 更新率
#define ICON_BAR_ICON_NUM_X    	3		//行个数
#define ICON_BAR_ICON_NUM_Y     1		//列个数
#define ICON_BAR_TEXT_EDGE_SIZE    2       //文本和位图间距,单位像素
#define ICON_BAR_TEXT_OFFSET    -1       //文本偏移

#define ICON_BAR_EDGE_SIZE    2       //图标被选中后的边框距离,单位像素
//行为相关
#define MOVE_TRIGGER_DISTANCE   10   //判定为触摸移动的距离,单位像素
/*********************************************************************
*
*       variables
*
**********************************************************************
*/
//函数声明
static void clean_icon_view(void);
static void clean_icon_bar(void);
static void clean_all_icon_flag(void);
static void init_all_mainpage(void);
static void init_mainpage(void);
WM_HWIN CreateTips(void);

//图标位图
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_appstore;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_calculator;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_calendar;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_camera;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_clock;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_compass;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_menssages;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_music;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_phone;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_photos;
extern GUI_CONST_STORAGE GUI_BITMAP bmiconview_weather;


//背景位图
extern GUI_CONST_STORAGE GUI_BITMAP bmicon_smile;

//_icon图标对象表示的是包含位图和文本的所有区域
//由于都是使用GUI等接口进行绘制图形,如果使用窗口管理器,在哪个窗口绘制就是坐标系就是这个窗口原点。
struct _icon {
  //变量
  unsigned char flag;             //图标状态,1:被选择 2:被双击
  signed short icon_x;            //图标左上角点x坐标,
  signed short icon_y;            //图标左上角点y坐标
  unsigned short icon_xsize;        //图标x尺寸
  unsigned short icon_ysize;        //图标y尺寸
  
  signed short text_y;            //文本区域左上角点y坐标,包含位图和文本间距
  signed short text_c_x;          //文本区域中心点x坐标
  signed short text_h_y;          //文本区域顶点Y坐标
  
  signed short bitmap_x;          //位图区域左上角点x坐标
  signed short bitmap_y;          //位图区域左上角点y坐标
  unsigned short bitmap_xsize;      //位图区域x尺寸,起点和图标一致
  unsigned short bitmap_ysize;      //位图区域y尺寸
  unsigned short bitmap_size;       //位图尺寸,图标区域,始终正方形
  
  float bitmap_rate;                //位图缩放比例
  WM_HWIN (*fun)(void);                // 双击后的回调函数
  GUI_MEMDEV_Handle men_handle;
  //赋初值
  const char       * pText;         //图标名称
  const GUI_BITMAP * pBitmap;       //图标位图
};
typedef struct _icon _ICON;
typedef struct _icon* _ICON_T;

struct _page {
  unsigned char init;               //初始化状态
  unsigned char icon_num;           //图标数量
  _ICON_T icon_list;                //图标集
  const GUI_FONT * pFont;
};
typedef struct _page _PAGE;
typedef struct _page* _PAGE_T;

//主页1图标列表
static _ICON icon_list1[]={
  {.pText="calculator",.pBitmap=&bmiconview_calculator,.fun=CreateTips},
  {.pText="calendar",.pBitmap=&bmiconview_calendar,.fun=CreateTips},
  {.pText="camera",.pBitmap=&bmiconview_camera,.fun=CreateTips},
};
//主页2图标列表
static _ICON icon_list2[]={
  {.pText="menssages",.pBitmap=&bmiconview_menssages,.fun=CreateTips},
  {.pText="weather",.pBitmap=&bmiconview_weather,.fun=CreateTips},
};

//icon_bar 图标列表
static _ICON icon_bar_list[]={
  {.pText="phone",.pBitmap=&bmiconview_phone,.fun=CreateTips},
  {.pText="app",.pBitmap=&bmiconview_appstore,.fun=CreateTips},
  {.pText="photo",.pBitmap=&bmiconview_photos,.fun=CreateTips},
};

static _PAGE _main_page[MAIN_PAGE_NUM]={
{.icon_num=GUI_COUNTOF(icon_list1),.icon_list=icon_list1,.pFont=TEXT_FONT},
{.icon_num=GUI_COUNTOF(icon_list2),.icon_list=icon_list2,.pFont=TEXT_FONT},
};

//变量
static signed short scr_offset_c=0;         //屏幕偏移的当前值
static signed short scr_offset_o=0;         //屏幕偏移的目标值
static unsigned char c_page=0;              // 0表示第一页  1表示第二页
static signed char icon_view_bp_offset=0;         //位图偏移到中心点的偏移量 ,注意位图始终为同比例边长   
static signed char icon_bar_bp_offset=0;         //位图偏移到中心点的偏移量 ,注意位图始终为同比例边长   

//移动行为
static signed short move_touch_sxf;             //移动触发时的X起点(加上偏移)
static signed short move_touch_sx;              //移动触发时的X起点
static signed short move_touch_x;               //点击时的x值
static signed short move_touch_c;               //此处触发的移动值
static unsigned char move_touch_f;              //移动触发开始标志位, 1:表示没有触发  2:触摸  3:触摸并滑动

//触摸单击行为
static signed short touch_click_x;               //点击时的x值
static signed short touch_click_y;               //点击时的y值
static unsigned char touch_click_f;              //点击标志,1:触摸单击触发  2:触摸单击已经绘制

//触摸双击行为
static unsigned char double_click;               //双击触发

//页面稳定
static unsigned char page_stability_f=1;    //自动返回触发开始标志位
static unsigned short icon_bar_y=0;      //预计算出icon_bar_y的起点

//窗口刷新标志位
static unsigned char win_refresh;       //标志位 第一位 icon_view 第二位 icon_bar
//窗口句柄
static WM_HWIN icon_view;
static WM_HWIN icon_bar;
static WM_HWIN icon_tips;

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
#define ID_WINDOW_0         (GUI_ID_USER + 0x00)
#define ID_ICONVIEW_0       (GUI_ID_USER + 0x01)
#define ID_TEXT_0           (GUI_ID_USER + 0x02)
#define ID_BUTTON_0         (GUI_ID_USER + 0x03)
#define ID_FRAMEWIN_0       (GUI_ID_USER + 0x04)
#define TIMER_0           0
#define TIMER_1           1

static void init_all_mainpage(void)
{
  double_click=0;
  scr_offset_c=0;
  scr_offset_o=0;
  move_touch_f=0;
  c_page=0;
  clean_all_icon_flag();
}

static void init_mainpage(void)
{
  double_click=0;
  move_touch_f=0;
  clean_all_icon_flag();
}

#if(VIEW_DEBUG==1)
static void debug_view_icon()
{
  unsigned char i;
  unsigned char t;
  for(i=0;i<MAIN_PAGE_NUM;i++){                   //页号
    for(t=0;t<_main_page[i].icon_num;t++) {       //图标号
      //绘制图标区域   
      GUI_SetColor(GUI_WHITE);        
      GUI_DrawRect(_main_page[i].icon_list[t].icon_x, _main_page[i].icon_list[t].icon_y, 
        _main_page[i].icon_list[t].icon_x+_main_page[i].icon_list[t].icon_xsize, 
        _main_page[i].icon_list[t].icon_y+_main_page[i].icon_list[t].icon_ysize);
      
      //绘制位图区域  
      GUI_SetColor(GUI_BLACK);       
      GUI_DrawRect(_main_page[i].icon_list[t].bitmap_x, _main_page[i].icon_list[t].bitmap_y, 
        _main_page[i].icon_list[t].bitmap_x+_main_page[i].icon_list[t].bitmap_size, 
        _main_page[i].icon_list[t].bitmap_y+_main_page[i].icon_list[t].bitmap_size); 
      
      //绘制文本区域
      GUI_SetColor(GUI_ORANGE);
      GUI_DrawRect(_main_page[i].icon_list[t].icon_x, _main_page[i].icon_list[t].text_y, 
        _main_page[i].icon_list[t].icon_x+_main_page[i].icon_list[t].icon_xsize, 
        _main_page[i].icon_list[t].text_y+_main_page[i].pFont->YSize+TEXT_EDGE_SIZE);
      
      //绘制文本中心
      GUI_SetColor(GUI_RED);
      GUI_FillCircle(_main_page[i].icon_list[t].text_c_x, _main_page[i].icon_list[t].text_h_y, 2);
    }
  }
}

static void debug_icon_bar()
{
  unsigned char t;               
  for(t=0;t<GUI_COUNTOF(icon_bar_list);t++) {       //图标号
    //绘制图标区域   
    GUI_SetColor(GUI_WHITE);        
    GUI_DrawRect(icon_bar_list[t].icon_x, icon_bar_list[t].icon_y, 
      icon_bar_list[t].icon_x+icon_bar_list[t].icon_xsize, 
      icon_bar_list[t].icon_y+icon_bar_list[t].icon_ysize);
    
    //绘制位图区域  
    GUI_SetColor(GUI_BLACK);       
    GUI_DrawRect(icon_bar_list[t].bitmap_x, icon_bar_list[t].bitmap_y, 
      icon_bar_list[t].bitmap_x+icon_bar_list[t].bitmap_size, 
      icon_bar_list[t].bitmap_y+icon_bar_list[t].bitmap_size); 
    
    //绘制文本区域
    GUI_SetColor(GUI_ORANGE);
    GUI_DrawRect(icon_bar_list[t].icon_x, icon_bar_list[t].text_y, 
      icon_bar_list[t].icon_x+icon_bar_list[t].icon_xsize, 
      icon_bar_list[t].text_y+_main_page[0].pFont->YSize+ICON_BAR_TEXT_EDGE_SIZE);
    
    //绘制文本中心
    GUI_SetColor(GUI_RED);
    GUI_FillCircle(icon_bar_list[t].text_c_x, icon_bar_list[t].text_h_y, 2);
  }
}
#endif



/*********************************************************************
*
*       viewicon_cbDialog
*/
static void clean_icon_view(void)
{
  unsigned char i;
  unsigned char t;
  //清除VIEW_ICON
  for(i=0;i<MAIN_PAGE_NUM;i++){                   //页号
    for(t=0;t<_main_page[i].icon_num;t++) {       //图标号
      _main_page[i].icon_list[t].flag=0;
    }
  }
}

static void clean_icon_bar(void)
{
  unsigned char t;
  //清除ICON_BAR
  for(t=0;t<ICON_BAR_ICON_NUM_X;t++) {            //图标号
      icon_bar_list[t].flag=0;
  }
}
    
static void clean_all_icon_flag(void)
{
  clean_icon_view();
  clean_icon_bar(); 
}
  
static void viewicon_cbDialog(WM_MESSAGE * pMsg) 
{
//  WM_HWIN hItem;
  unsigned char i;
  unsigned char t;
  unsigned short temp;
  unsigned short temp1;
  GUI_PID_STATE  pState;
  
//  long ram;

  switch (pMsg->MsgId) {
  case WM_CREATE: 
    //初始化页参数
  
    // 优化:后期可以分段创建子窗口
    for(i=0;i<MAIN_PAGE_NUM;i++){                   //页号
      for(t=0;t<_main_page[i].icon_num;t++) {       //图标号
        /*图标区域定位*/
        _main_page[i].icon_list[t].icon_xsize=(VIEW_ICON_XSIZE-(ICON_NUM_X+1)*ICON_X_INTERVAL)/ICON_NUM_X;
        _main_page[i].icon_list[t].icon_ysize=(VIEW_ICON_YSIZE-(ICON_NUM_Y+1)*ICON_Y_INTERVAL)/ICON_NUM_Y;
        temp=t%ICON_NUM_X;                  //所在行
        //图标区域的左上角起点X坐标
        _main_page[i].icon_list[t].icon_x=(temp+1)*ICON_X_INTERVAL+temp*_main_page[i].icon_list[t].icon_xsize+VIEW_ICON_XSIZE*i;
        temp=t/ICON_NUM_X;                //所在列
        _main_page[i].icon_list[t].icon_y=(temp+1)*ICON_Y_INTERVAL+temp*_main_page[i].icon_list[t].icon_ysize;
        //计算尺寸
        _main_page[i].icon_list[t].text_y=_main_page[i].icon_list[t].icon_y+
            _main_page[i].icon_list[t].icon_ysize-
            _main_page[i].pFont->YSize-TEXT_EDGE_SIZE;
        
        _main_page[i].icon_list[t].bitmap_xsize=_main_page[i].icon_list[t].icon_xsize;
        _main_page[i].icon_list[t].bitmap_ysize=_main_page[i].icon_list[t].text_y-_main_page[i].icon_list[t].icon_y;
        
        //文本区域的中心点起点X坐标,由icon_x计算
        _main_page[i].icon_list[t].text_c_x=(_main_page[i].icon_list[t].icon_x+_main_page[i].icon_list[t].bitmap_xsize/2);
        _main_page[i].icon_list[t].text_h_y=_main_page[i].icon_list[t].text_y+TEXT_EDGE_SIZE+VIEW_ICON_TEXT_OFFSET;
        
        //绘制位图比例和选边
        if(_main_page[i].icon_list[t].bitmap_xsize>_main_page[i].icon_list[t].bitmap_ysize){
          //以Y尺寸绘图,y为短边
          temp=(_main_page[i].icon_list[t].bitmap_xsize - _main_page[i].icon_list[t].bitmap_ysize)/2;       //X方向多余部分,绘制正方形图标
          //位图区域的左上角起点X坐标,由icon_x计算
          _main_page[i].icon_list[t].bitmap_x=_main_page[i].icon_list[t].icon_x+temp;
          _main_page[i].icon_list[t].bitmap_y=_main_page[i].icon_list[t].icon_y;
          _main_page[i].icon_list[t].bitmap_rate=
            (float)_main_page[i].icon_list[t].bitmap_ysize/_main_page[i].icon_list[t].pBitmap->XSize;   //缩放图标比例
          _main_page[i].icon_list[t].bitmap_size=_main_page[i].icon_list[t].bitmap_ysize;
        }else{
          //以x尺寸绘图,x为短边
          temp=(_main_page[i].icon_list[t].bitmap_ysize - _main_page[i].icon_list[t].bitmap_xsize)/2;  
          //位图区域的左上角起点X坐标,由icon_x计算
          _main_page[i].icon_list[t].bitmap_x=_main_page[i].icon_list[t].icon_x;
          _main_page[i].icon_list[t].bitmap_y=_main_page[i].icon_list[t].icon_y+temp;
          _main_page[i].icon_list[t].bitmap_rate=
            (float)_main_page[i].icon_list[t].bitmap_xsize/_main_page[i].icon_list[t].pBitmap->XSize;   //缩放图标比例 
          _main_page[i].icon_list[t].bitmap_size=_main_page[i].icon_list[t].bitmap_xsize;
        }  
        
        /*创建内存设备*/    
        //内存设备区域的左上角起点X坐标  ,由icon_x计算        
         _main_page[i].icon_list[t].men_handle=GUI_MEMDEV_CreateFixed(_main_page[i].icon_list[t].bitmap_x, _main_page[i].icon_list[t].bitmap_y,
        _main_page[i].icon_list[t].pBitmap->XSize, _main_page[i].icon_list[t].pBitmap->YSize,
        GUI_MEMDEV_HASTRANS, GUI_MEMDEV_APILIST_16, GUICC_M565);
        //绘制位图
        GUI_MEMDEV_Select(_main_page[i].icon_list[t].men_handle);
        GUI_DrawBitmap(_main_page[i].icon_list[t].pBitmap, 
        _main_page[i].icon_list[t].bitmap_x,
        _main_page[i].icon_list[t].bitmap_y);     
      }
    }
    //提示此时生成位图的正方形边长
    i=0; t=0;
    //对齐到位图区域中心
    icon_view_bp_offset=-(_main_page[i].icon_list[t].pBitmap->XSize-_main_page[i].icon_list[t].bitmap_size)/2;

    xprintf("icon_view bitmap_size:%d\r\n",_main_page[i].icon_list[t].bitmap_size);
//    ram=GUI_ALLOC_GetNumFreeBytes();      //获取GUI剩余内存空间
//    xprintf("icon_view GUI_Free_ram is %d\r\n",ram);
      
    //重新指定LCD输出
    GUI_MEMDEV_Select(0);
    icon_bar_y=VIEW_ICON_Y+VIEW_ICON_YSIZE;
    break;
  
  case WM_PAINT:
    //重绘背景
    GUI_SetBkColor(VIEW_ICON_BK_COLOR);         //自定义调色
    GUI_Clear();
//    GUI_DrawBitmapEx(&bmicon_smile, VIEW_ICON_XSIZE/2, //耗费CPU资源
//    MAIN_PAGE_SMILE_ICON_Y0,bmicon_smile.XSize/2,bmicon_smile.YSize/2,1000,1000);  
#if(VIEW_DEBUG==1)
    debug_view_icon();
#endif

    //绘制滑动图标区域
    for(i=0;i<MAIN_PAGE_NUM;i++){                   //页号
      for(t=0;t<_main_page[i].icon_num;t++) {       //图标号
        //绘制被选择背景
        if(c_page==i && _main_page[i].icon_list[t].flag==1 ){
          GUI_SetColor(ICON_SELECTED_COLOR);
          GUI_FillRect(_main_page[i].icon_list[t].icon_x-c_page*VIEW_ICON_XSIZE - VIEW_ICON_EDGE_XSIZE,
          _main_page[i].icon_list[t].icon_y - VIEW_ICON_EDGE_YSIZE,
          _main_page[i].icon_list[t].icon_x+_main_page[i].icon_list[t].icon_xsize-c_page*VIEW_ICON_XSIZE + VIEW_ICON_EDGE_XSIZE ,
          _main_page[i].icon_list[t].icon_y+_main_page[i].icon_list[t].icon_ysize + VIEW_ICON_EDGE_YSIZE  );
        }

        //绘制图标区域      
        GUI_MEMDEV_WriteAt(_main_page[i].icon_list[t].men_handle,
        _main_page[i].icon_list[t].bitmap_x+icon_view_bp_offset+scr_offset_c
        ,_main_page[i].icon_list[t].bitmap_y+icon_view_bp_offset+VIEW_ICON_Y);
        
//      GUI_MEMDEV_WriteExAt();消耗大
        
        //绘制文本区域
        GUI_SetColor(GUI_BLACK);
        GUI_SetTextMode(GUI_TM_TRANS);          //透明背景
        GUI_DispStringHCenterAt(_main_page[i].icon_list[t].pText, _main_page[i].icon_list[t].text_c_x+scr_offset_c, 
        _main_page[i].icon_list[t].text_h_y);
      }
    }
  break;

  case WM_TIMER:
    if(double_click==1){
      WM_DeleteTimer(pMsg->Data.v);       //双击行为后 main_page 不在更新
      break;
    }
    else{
      WM_RestartTimer(pMsg->Data.v, VIEW_ICON_REFRESH_RATE);
    }
    GUI_PID_GetState(&pState); 
    
    // 移动行为 页面没有达到 单击行为 
    if(move_touch_f==3 || scr_offset_o!=scr_offset_c){
      WM_InvalidateWindow(pMsg->hWin);
    }
    
    // 点击行为刷新
    if( touch_click_f==1 || touch_click_f==2)            //VIEW_ICON 中的图标触发选中
    {
      WM_InvalidateWindow(pMsg->hWin);
      WM_SendMessageNoPara(icon_bar, MSG_WIN_INVAILD);   //发送到 icon_bar ,刷新页面
    }
    /***********行为***********/

    /*行为:点击 和 滑动 */
    if(pState.Pressed==1 && move_touch_f==1 ){
      move_touch_sxf=pState.x-scr_offset_c;      // 添加初始偏移值
      move_touch_sx=pState.x;
      move_touch_f=2;                           // 记忆发生触摸
    }
    if(pState.Pressed==1 && move_touch_f>1){
      move_touch_x=pState.x;
      move_touch_c=move_touch_x-move_touch_sx;      //当前触摸滑动的移动值
      
      //确认是否为 滑动 行为
      if(abs(move_touch_c)>MOVE_TRIGGER_DISTANCE){
        /*行为:滑动 */
        if(pState.y>VIEW_ICON_Y && pState.y<icon_bar_y)     //需要在指定区域滑动
        {            
          clean_all_icon_flag();                        //清除所有的标记
          if(win_refresh&0x2){
            WM_SendMessageNoPara(icon_bar, MSG_WIN_INVAILD);  
            win_refresh&=0x1;                           //清除这个刷新标记
          }

          move_touch_f=3;                               //触发触摸移动标志
          scr_offset_c=move_touch_x-move_touch_sxf;     //在初始偏移值基础上进行增减
          
          //滑动页面两侧极限位置限制
          if(scr_offset_c < (-(MAIN_PAGE_NUM-1)*VIEW_ICON_XSIZE)){
            scr_offset_c = -(MAIN_PAGE_NUM-1)*VIEW_ICON_XSIZE;
            move_touch_c=0;
          }
          if(scr_offset_c > 0){
            scr_offset_c = 0;
            move_touch_c=0;
          } 
        }
        else{       //超出滑动区域
          move_touch_c=0;
        }          
      }
      else
      {
        /*行为:点击图标*/
        //touch_click_f 
        // 0: 一次单击检测开始
        // 1: VIEW_ICON 选中
        // 2: ICON_BAR 选中
        // 3: 都没 选中
        if(move_touch_f==2 && page_stability_f==1 && touch_click_f==0 && double_click==0){          //触发点击行为,没有触发翻页
          touch_click_x =  pState.x;
          touch_click_y =  pState.y;
          
          // 确定 VIEW_ICON 哪个图标被选中
          for(i=0;i<MAIN_PAGE_NUM;i++){                   //页号
            for(t=0;t<_main_page[i].icon_num;t++) {       //图标号
              temp = _main_page[i].icon_list[t].icon_x + VIEW_ICON_X - c_page*VIEW_ICON_XSIZE;   //当前页的图标X起点
              temp1 = _main_page[i].icon_list[t].icon_y + VIEW_ICON_Y;                //当前页的图标Y起点
              if( i==c_page  
              && touch_click_f == 0
              && touch_click_x - temp < _main_page[i].icon_list[t].icon_xsize 
              && touch_click_x > temp 
              && touch_click_y- temp1 < _main_page[i].icon_list[t].icon_ysize 
              && touch_click_y > temp1  )
              {
                /*行为:双击 图标*/
                if(_main_page[i].icon_list[t].flag==1){        
                  double_click=1;                  
                  _main_page[i].icon_list[t].fun();                 //触发回调
                }
                _main_page[i].icon_list[t].flag=1;
                touch_click_f = 1;                                  // VIEW_ICON 中的图标触发选中  
                win_refresh|=0x1;                                   // 标记清除选中需要刷新一次
              }else
              {
                _main_page[i].icon_list[t].flag=0;                  //将 VIEW_ICON 没有选择的标志清除
              }
            }
          }
          
          // 确定 ICON_BAR 哪个图标被选中
          for(t=0;t<ICON_BAR_ICON_NUM_X;t++) {        //图标号
            temp=icon_bar_list[t].icon_x+ICON_BAR_X;
            temp1=icon_bar_list[t].icon_y+ICON_BAR_Y;
            if(touch_click_f == 0
            && touch_click_x-temp < icon_bar_list[t].icon_xsize 
            && touch_click_y-temp1 < icon_bar_list[t].icon_ysize 
            && touch_click_x > temp
            && touch_click_y > temp1 )
            {
              /*行为:双击 图标*/
              if(icon_bar_list[t].flag==1){             
                double_click=1;  
                icon_bar_list[t].fun();     //触发回调
              }
              icon_bar_list[t].flag=1;
              touch_click_f = 2;                      // ICON_BAR 中的图标触发选中  
              win_refresh|=0x2;                       // 标记清除选中需要刷新一次      
            }else
            {
              icon_bar_list[t].flag=0;                //将 ICON_BAR 没有选择的标志清除
            }
          }
          
          // 什么都没有点
          if(touch_click_f!=1 && touch_click_f!=2){   //表示什么都没有点击
            WM_InvalidateWindow(pMsg->hWin);
            WM_SendMessageNoPara(icon_bar, MSG_WIN_INVAILD);   //发送到icon_bar ,刷新页面
            touch_click_f=3;                          // 都没有点到
          }
        } 
      }
    }
    else    
    {    
      move_touch_c=0;
    }   
    
    //用于解锁后防止滑动屏幕
    if(pState.Pressed==0){   
      move_touch_f=1;          // 记忆没有发生触摸
      touch_click_f = 0;
    }

    /* 行为:更改页面目标值 */
    if(move_touch_f==3 && abs(move_touch_c)>VIEW_ICON_XSIZE/4 && page_stability_f==1){
      if(move_touch_c<0 && c_page < MAIN_PAGE_NUM-1)  //切换下一页
      {
        scr_offset_o=scr_offset_o-VIEW_ICON_XSIZE; 
        page_stability_f=0;
        c_page++;
      }else if(move_touch_c>0 && c_page>0){       //切换上一页
        scr_offset_o=scr_offset_o+VIEW_ICON_XSIZE; 
        page_stability_f=0;
        c_page--;
      }
    }

    /*行为:自动定位主页*/
    if( move_touch_f==1 && scr_offset_o>scr_offset_c ){
      if((scr_offset_o-scr_offset_c)<VIEW_ICON_POSITIONING_VALUE)
        scr_offset_c=scr_offset_o;      //防止无法准确到达scr_offset_o值
      else
        scr_offset_c=scr_offset_c+VIEW_ICON_POSITIONING_VALUE;
    }else if( move_touch_f==1 && scr_offset_o<scr_offset_c ){
      if((scr_offset_c-scr_offset_o)<VIEW_ICON_POSITIONING_VALUE)
        scr_offset_c=scr_offset_o;      //防止无法准确到达scr_offset_o值
      else
        scr_offset_c=scr_offset_c-VIEW_ICON_POSITIONING_VALUE;
    }
    //页面稳定
    if(scr_offset_o==scr_offset_c)page_stability_f=1;
    
//    xprintf("move_touch_f:%d\r\n",move_touch_f);
    break;
    
  case WM_DELETE:
    init_all_mainpage(); 
    
    // 删除所有的内存设备
    for(i=0;i<MAIN_PAGE_NUM;i++){                   //页号
      for(t=0;t<_main_page[i].icon_num;t++) {       //图标号
        GUI_MEMDEV_Delete(_main_page[i].icon_list[t].men_handle);
      }
    }
    break;
 
  default:
    WM_DefaultProc(pMsg);
    break;
  }
}

static void iconbar_cbDialog(WM_MESSAGE * pMsg) 
{
//  WM_HWIN hItem;
//  unsigned char i;
  unsigned char t;
  unsigned short temp;
#if(VIEW_DEBUG==1)
  long ram;
#endif  
  switch (pMsg->MsgId) {
  case WM_CREATE:   
    for(t=0;t<GUI_COUNTOF(icon_bar_list);t++) {       //图标号
      /*图标区域定位*/
      icon_bar_list[t].icon_xsize=(ICON_BAR_XSIZE-(ICON_BAR_ICON_NUM_X-1)*ICON_BAR_MIDDLE_INTERVAL-2*ICON_BAR_OUTSIDE_INTERVAL)/ICON_BAR_ICON_NUM_X;
      icon_bar_list[t].icon_ysize=(ICON_BAR_YSIZE-(ICON_BAR_ICON_NUM_Y+1)*ICON_BAR_Y_INTERVAL)/ICON_BAR_ICON_NUM_Y;
      temp=t%ICON_BAR_ICON_NUM_X;                  //所在行
      //图标区域的左上角起点X坐标
      icon_bar_list[t].icon_x=ICON_BAR_OUTSIDE_INTERVAL+ temp*ICON_BAR_MIDDLE_INTERVAL+temp*icon_bar_list[t].icon_xsize;

      temp=t/ICON_BAR_ICON_NUM_X;                //所在列
      icon_bar_list[t].icon_y=(temp+1)*ICON_BAR_Y_INTERVAL+temp*icon_bar_list[t].icon_ysize;
      //计算尺寸
      icon_bar_list[t].text_y=icon_bar_list[t].icon_y+
          icon_bar_list[t].icon_ysize-
          _main_page[0].pFont->YSize-ICON_BAR_TEXT_EDGE_SIZE;
      
      icon_bar_list[t].bitmap_xsize=icon_bar_list[t].icon_xsize;
      icon_bar_list[t].bitmap_ysize=icon_bar_list[t].text_y-icon_bar_list[t].icon_y;
      
      //文本区域的中心点起点X坐标,由icon_x计算
      icon_bar_list[t].text_c_x=(icon_bar_list[t].icon_x+icon_bar_list[t].bitmap_xsize/2);
      icon_bar_list[t].text_h_y=icon_bar_list[t].text_y+ICON_BAR_TEXT_EDGE_SIZE+ICON_BAR_TEXT_OFFSET;
      
      //绘制位图比例和选边
      if(icon_bar_list[t].bitmap_xsize>icon_bar_list[t].bitmap_ysize){
        //以Y尺寸绘图,y为短边
        temp=(icon_bar_list[t].bitmap_xsize - icon_bar_list[t].bitmap_ysize)/2;       //X方向多余部分,绘制正方形图标
        //位图区域的左上角起点X坐标,由icon_x计算
        icon_bar_list[t].bitmap_x=icon_bar_list[t].icon_x+temp;
        icon_bar_list[t].bitmap_y=icon_bar_list[t].icon_y;
        icon_bar_list[t].bitmap_rate=
          (float)icon_bar_list[t].bitmap_ysize/icon_bar_list[t].pBitmap->XSize;   //缩放图标比例
        icon_bar_list[t].bitmap_size=icon_bar_list[t].bitmap_ysize;
      }else{
        //以x尺寸绘图,x为短边
        temp=(icon_bar_list[t].bitmap_ysize - icon_bar_list[t].bitmap_xsize)/2;  
        //位图区域的左上角起点X坐标,由icon_x计算
        icon_bar_list[t].bitmap_x=icon_bar_list[t].icon_x;
        icon_bar_list[t].bitmap_y=icon_bar_list[t].icon_y+temp;
        icon_bar_list[t].bitmap_rate=
          (float)icon_bar_list[t].bitmap_xsize/icon_bar_list[t].pBitmap->XSize;   //缩放图标比例 
        icon_bar_list[t].bitmap_size=icon_bar_list[t].bitmap_xsize;
      }  
      
      /*创建内存设备*/    
      //内存设备区域的左上角起点X坐标  ,由icon_x计算    
      //这里使用的内存创建后没有主动释放
       icon_bar_list[t].men_handle=GUI_MEMDEV_CreateFixed(icon_bar_list[t].bitmap_x, icon_bar_list[t].bitmap_y,
      icon_bar_list[t].pBitmap->XSize, icon_bar_list[t].pBitmap->YSize,
      GUI_MEMDEV_HASTRANS, GUI_MEMDEV_APILIST_16, GUICC_M565);
      //绘制位图
      GUI_MEMDEV_Select(icon_bar_list[t].men_handle);
      GUI_DrawBitmap(icon_bar_list[t].pBitmap, 
      icon_bar_list[t].bitmap_x,
      icon_bar_list[t].bitmap_y);   
    }

    //提示此时生成位图的正方形边长
    //对齐到位图区域中心,使用图片1的,所以要保证图标大小一致,否则其他图标位置错误
    t=0;
    icon_bar_bp_offset=-(icon_bar_list[t].pBitmap->XSize-icon_bar_list[t].bitmap_size)/2+1;
    
      xprintf("icon_bar bitmap_size:%d\r\n",icon_bar_list[t].bitmap_size);
//      ram=GUI_ALLOC_GetNumFreeBytes();      //获取GUI剩余内存空间
//      xprintf("icon_bar GUI_Free_ram is %d\r\n",ram);
      
    //重新指定LCD输出
    GUI_MEMDEV_Select(0);
#if(VIEW_DEBUG==1)
    ram=GUI_ALLOC_GetNumFreeBytes();      //获取GUI剩余内存空间
    xprintf("GUI_Free_ram is %d\r\n",ram);  
#endif   

    break;
  
  case WM_PAINT:
    GUI_SetBkColor(ICON_BAR_BK_COLOR);        
    GUI_Clear();
  
#if(VIEW_DEBUG==1)
    debug_icon_bar();
#endif
    //绘制图标区域
    for(t=0;t<ICON_BAR_ICON_NUM_X;t++) {       //图标号
      //绘制被选择背景
      if(icon_bar_list[t].flag==1){
        GUI_SetColor(ICON_SELECTED_COLOR);
        GUI_FillRect(icon_bar_list[t].icon_x-ICON_BAR_EDGE_SIZE,
        icon_bar_list[t].icon_y-ICON_BAR_EDGE_SIZE,
        icon_bar_list[t].icon_x+icon_bar_list[t].icon_xsize+ICON_BAR_EDGE_SIZE,
        icon_bar_list[t].icon_y+icon_bar_list[t].icon_ysize+ICON_BAR_EDGE_SIZE);
      }
      
      //绘制图标区域      
      GUI_MEMDEV_WriteAt(icon_bar_list[t].men_handle,
      icon_bar_list[t].bitmap_x+icon_bar_bp_offset
      ,icon_bar_list[t].bitmap_y+icon_bar_bp_offset+ICON_BAR_Y);
      
      //绘制文本区域
      GUI_SetColor(GUI_BLACK);
      GUI_SetTextMode(GUI_TM_TRANS);          //透明背景
      GUI_DispStringHCenterAt(icon_bar_list[t].pText,icon_bar_list[t].text_c_x, 
      icon_bar_list[t].text_h_y);
    }
//    xprintf("icon_bar_refresh\r\n");
    break;
    
  case MSG_WIN_INVAILD:
    WM_InvalidateWindow(pMsg->hWin);  
    break;
  
  case WM_DELETE:
    init_all_mainpage(); 
    
    // 删除所有的内存设备
    for(t=0;t<GUI_COUNTOF(icon_bar_list);t++) {       //图标号
        GUI_MEMDEV_Delete(icon_bar_list[t].men_handle);
    }
    break;
    
  default:
    WM_DefaultProc(pMsg);
    break;
  }
}

/*********************************************************************
*
*       Createwin_mainpage
*/
WM_HWIN Createwin_mainpage(void);
WM_HWIN Createwin_mainpage(void) {
  WM_HWIN win[WIN_MAX_NUM]={0};
  
  //初始化主屏幕参数
  init_all_mainpage();                  
  /*****创建VIEW ICON区域*****/
  win[0]=WM_CreateWindowAsChild(VIEW_ICON_X, VIEW_ICON_Y, VIEW_ICON_XSIZE, VIEW_ICON_YSIZE,
  WM_HBKWIN, WM_CF_SHOW, viewicon_cbDialog, 0);
  //创建VIEW ICON定时器
  WM_CreateTimer(win[0], TIMER_0, VIEW_ICON_REFRESH_RATE, 0);

//  /*****创建ICON BAR区域*****/
  win[1]=WM_CreateWindowAsChild(ICON_BAR_X, ICON_BAR_Y, ICON_BAR_XSIZE, ICON_BAR_YSIZE,
  WM_HBKWIN, WM_CF_SHOW, iconbar_cbDialog, 0);
  
  icon_view = win[0];
  icon_bar = win[1];
  switch_win(win,MIAN_PAGE_WIN_ID);
  return win[0];
}


#define TIPS_WIN_XSIZE    150
#define TIPS_WIN_YSIZE    120
#define TIPS_WIN_X        (LCD_xsize-TIPS_WIN_XSIZE)/2
#define TIPS_WIN_Y        ((LCD_ysize-TIPS_WIN_YSIZE)/2-STATUS_BAR_HEIGHT)

#define TIPS_BUTTON_XSIZE  50
#define TIPS_BUTTON_YSIZE  25    
#define TIPS_BUTTON_X  ((TIPS_WIN_XSIZE-TIPS_BUTTON_XSIZE)/2)
#define TIPS_BUTTON_Y  (int)(TIPS_WIN_YSIZE * 0.65f)
#define TIPS_BUTTON_FONT   GUI_FONT_8X12_ASCII

#define TIPS_TEXT_XSIZE  (TIPS_WIN_XSIZE-20)
#define TIPS_TEXT_YSIZE  (TIPS_WIN_YSIZE-TIPS_BUTTON_YSIZE-60)    //不要覆盖到按钮窗口
#define TIPS_TEXT_X  (TIPS_WIN_XSIZE-TIPS_TEXT_XSIZE)/2
#define TIPS_TEXT_Y  (int)(TIPS_WIN_YSIZE * 0.30f)
#define TIPS_TEXT_TEXT   GUI_FONT_8X12_ASCII

#if(VIEW_DEBUG==1)
static void debug_view_region(void)
{
  //绘制窗口区域   
  GUI_SetColor(GUI_RED);        
  GUI_DrawRect(0,0,
    0+TIPS_WIN_XSIZE-1, 
    0+TIPS_WIN_YSIZE-1);
  
  //绘制文本区域   
  GUI_SetColor(GUI_WHITE);        
  GUI_DrawRect(TIPS_TEXT_X, TIPS_TEXT_Y, 
    TIPS_TEXT_X+TIPS_TEXT_XSIZE, 
    TIPS_TEXT_Y+TIPS_TEXT_YSIZE);

  //绘制按钮区域  
  GUI_SetColor(GUI_BLACK);       
  GUI_DrawRect(TIPS_BUTTON_X, TIPS_BUTTON_Y, 
   TIPS_BUTTON_X+TIPS_BUTTON_XSIZE, 
   TIPS_BUTTON_Y+TIPS_BUTTON_YSIZE); 
}
#endif

//创建提示窗口
static void Tips_cbDialog(WM_MESSAGE * pMsg) {
#if(VIEW_DEBUG==0)
  WM_HWIN hItem;
#endif
  int     NCode;
  int     Id;
//  long ram;

  switch (pMsg->MsgId) {
  case WM_CREATE:
    //显示框架
#if(VIEW_DEBUG==0)
    hItem=FRAMEWIN_CreateEx(0,0,TIPS_WIN_XSIZE,TIPS_WIN_YSIZE,pMsg->hWin,
    WM_CF_SHOW,0,ID_FRAMEWIN_0,"Tips",0);

    hItem=TEXT_CreateEx(TIPS_TEXT_X, TIPS_TEXT_Y,TIPS_TEXT_XSIZE, TIPS_TEXT_YSIZE,
    pMsg->hWin,WM_CF_SHOW,
    TEXT_CF_HCENTER|TEXT_CF_TOP, ID_TEXT_0, "Please set callback function");
    TEXT_SetWrapMode(hItem,GUI_WRAPMODE_WORD);
    WM_SetStayOnTop(hItem,1);                 //文本窗口始终在最上面

    hItem = BUTTON_CreateEx(TIPS_BUTTON_X,TIPS_BUTTON_Y,TIPS_BUTTON_XSIZE,TIPS_BUTTON_YSIZE,pMsg->hWin,WM_CF_SHOW,0,ID_BUTTON_0);
    WM_SetFocus(hItem);
    WM_SetStayOnTop(hItem,1);                 //按钮窗口始终在最上面
    BUTTON_SetFont(hItem, TIPS_BUTTON_FONT);
    BUTTON_SetText(hItem, "OK");
#endif
#if(VIEW_DEBUG==1)
    debug_view_region();
#endif
//    ram=GUI_ALLOC_GetNumFreeBytes();        //获取GUI剩余内存空间
//    xprintf("GUI_Free_ram is %d\r\n",ram);      
    break;
  
  case WM_NOTIFY_PARENT:
    Id    = WM_GetId(pMsg->hWinSrc);
    NCode = pMsg->Data.v;
    switch(Id) {
    case ID_BUTTON_0: // Notifications sent by 'Button'
      switch(NCode) {
      case WM_NOTIFICATION_CLICKED:
        WM_DeleteWindow(pMsg->hWin);
        break;
      case WM_NOTIFICATION_RELEASED:
        break;
      }
      break;
    }
    break;
    
  case WM_PAINT:
#if(VIEW_DEBUG==1)
    debug_view_region();
#endif
   break;
  
  case WM_DELETE:
    init_mainpage(); 
    if(_hLastFrame[0]!=0){
      WM_CreateTimer(icon_view, TIMER_0, VIEW_ICON_REFRESH_RATE, 0);
    }
    break;
  
  default:
    WM_DefaultProc(pMsg);
    break;
  }
}

WM_HWIN CreateTips(void) {

  icon_tips=WM_CreateWindowAsChild(TIPS_WIN_X, TIPS_WIN_Y, TIPS_WIN_XSIZE, TIPS_WIN_YSIZE,
  icon_view, WM_CF_SHOW|WM_CF_HASTRANS, Tips_cbDialog, 0);
  
  return icon_tips;
}
/*************************** End of file ****************************/

解锁页代码

/*********************************************************************
*                                                                    *
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
*                                                                    *
**********************************************************************
*                                                                    *
* C-file generated by:                                               *
*                                                                    *
*        GUI_Builder for emWin version 5.32                          *
*        Compiled Oct  8 2015, 11:59:02                              *
*        (c) 2015 Segger Microcontroller GmbH & Co. KG               *
*                                                                    *
**********************************************************************
*                                                                    *
*        Internet: www.segger.com  Support: support@segger.com       *
*                                                                    *
**********************************************************************
*/

// USER START (Optionally insert additional includes)
// USER END

#include "DIALOG.h"
#include "SCROLLBAR.h"
#include "SCROLLBAR_Private.h"
#include "GUI_app/gui_thread.h"
#include "config.h"

/*********************************************************************
*
*       user config
*
**********************************************************************
*/
//锁定画面尺寸定义
#define LOCK_SCREEN_X         0
#define LOCK_SCREEN_Y         STATUS_BAR_HEIGHT
#define LOCK_SCREEN_XSIZE     (LCD_xsize-LOCK_SCREEN_X)
#define LOCK_SCREEN_YSIZE     (LCD_ysize-LOCK_SCREEN_Y)
//在状态栏的基础上偏移
#define LOCK_BAR_Y0_RATE      0.75f   //解锁条在LCD屏幕的比例位置
#define LOCK_BAR_Y0     (int)(LCD_ysize*LOCK_BAR_Y0_RATE-STATUS_BAR_HEIGHT)    //解锁条的Y方向起点,始终保证在
  
#define TEXT_BAR_Y0     50             //文本框的左上角起点,相对于LOCK_SCREEN为0
#define TEXT_BAR_YSIZE  40
#define SMILE_ICON_Y0   (LOCK_SCREEN_YSIZE)/2     //笑脸图标的中心点Y方向
//锁定界面参数
#define VALUE_NO_TRIGGER  -1      //滑条按钮没有触发下的返回减少的值
#define LOCK_BAR_REFRESH_RATE 30  //解锁条刷新率
#define TIME_REFRESH_RATE 1000    //时间显示刷新率
//解锁条外观调整
#define LOCK_BAR_LIMIT  15        //解锁条超出限制,由于不要左右按钮,需要起点和终点超出界限
#define LOCK_BAR_WIDTH  40        //解锁条的宽度,上下高度
#define SLIDE_STRIP_VALUE 40      //滑条最大值,决定滑块大小
#define LOCK_BAR_OSIZE      1     //解锁条外框尺寸
#define LOCK_BAR_ISIZE      1     //解锁条内框尺寸
#define LOCK_BAR_RSIZE      3     //解锁条中所有圆角尺寸
#define SLIDE_OSIZE           3   //滑块在解锁条中的间距
#define DY_SLIDE_WIDTH        20   //动态滑条宽度
#define DY_SLIDE_OSIZE        3   //动态滑条尺寸
#define DY_SLIDE_SPEED        1   //动态速度

//时间外观调整
#define TIME_Y_OFFSET         100  //时间的垂直位置,越大越往上

#define VIEW_DEBUG            0
/*********************************************************************
*
*       variables
*
**********************************************************************
*/
static float dy_slider_value=0;           //动态滑块的移动值

extern WM_HWIN _hLastFrame[WIN_MAX_NUM];;	
extern GUI_CONST_STORAGE GUI_BITMAP bmwallpaper_ios15_1;        //失真的IOS壁纸
extern GUI_CONST_STORAGE GUI_BITMAP bmwallpaper_ios15_2;        //全彩的IOS壁纸
extern GUI_CONST_STORAGE GUI_BITMAP bmwallpaper_smile;          //失真的笑脸壁纸
extern GUI_CONST_STORAGE GUI_BITMAP bmicon_unlock_arrow;
extern GUI_CONST_STORAGE GUI_BITMAP bmicon_smile;
extern GUI_CONST_STORAGE GUI_FONT GUI_Fontfont_songti_38_bold_ascii_unicode;

extern RTC_TimeTypeDef RTC_TimeStruct;
extern RTC_DateTypeDef RTC_DateStruct;

extern void init_mainpage(void);
WM_HWIN Createlockwin(void);
WM_HWIN Createwin_mainpage(void);
WM_HWIN lock_handle;

GUI_MEMDEV_Handle icon_arrow_handle;
/*********************************************************************
*
*       Defines
*
**********************************************************************
*/
#define ID_WINDOW_0       (GUI_ID_USER + 0x00)
#define ID_SCROLLBAR_0    (GUI_ID_USER + 0x01)
#define ID_TEXT_0         (GUI_ID_USER + 0x02)

#define TIMER_0           0
#define TIMER_1           1
// USER START (Optionally insert additional defines)
// USER END

/*********************************************************************
*
*       Static code
*
**********************************************************************
*/

#if(VIEW_DEBUG==0)
static signed short but_lcd_xoffset;
static signed short but_lcd_yoffset;
static int SCROLLBAR_0_DrawSkin(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo) {
  static int SCROLLBAR0_state=0;
  static int UNLOCK_BAR_x0=0,UNLOCK_BAR_y0=0,UNLOCK_BAR_x1=0,UNLOCK_BAR_y1=0;
  static unsigned char init=0;
  
  SCROLLBAR_SKINFLEX_INFO * pSkinInfo;
  pSkinInfo = (SCROLLBAR_SKINFLEX_INFO *)pDrawItemInfo->p;
  char text[]="    slide to unlock";
  GUI_RECT pRect;
  int offset;
  int temp;
  
  switch (pDrawItemInfo->Cmd) {
    case WIDGET_ITEM_CREATE:            //创建控件后立即发送
      return SCROLLBAR_DrawSkinFlex(pDrawItemInfo);
    case WIDGET_ITEM_DRAW_BUTTON_L:     //皮肤设置函数将绘制左侧按钮
      if( but_lcd_yoffset==0){
//        offset=pDrawItemInfo->x1-pDrawItemInfo->x0;
        temp=WM_GetWindowOrgX(pDrawItemInfo->hWin);
        but_lcd_xoffset=temp+LOCK_BAR_OSIZE+LOCK_BAR_ISIZE+SLIDE_OSIZE-2;
        but_lcd_yoffset=WM_GetWindowOrgY(pDrawItemInfo->hWin)+LOCK_BAR_OSIZE+LOCK_BAR_ISIZE+SLIDE_OSIZE-5;
//        xprintf("xoffset:%d yoffset:%d \r\n",but_lcd_xoffset,but_lcd_yoffset);
      }
      //不绘制
      return 0;
    case WIDGET_ITEM_DRAW_BUTTON_R:       //皮肤设置函数将绘制右侧按钮
      //不绘制
      return 0;
    case WIDGET_ITEM_DRAW_OVERLAP:      //皮肤设置函数将绘制重叠区域。
      return SCROLLBAR_DrawSkinFlex(pDrawItemInfo);
    
    case WIDGET_ITEM_DRAW_SHAFT_L:      //皮肤设置函数将绘制轴的左侧部分
//      xprintf("SHAFT_L x0:%d y0:%d x1:%d y1:%d \r\n",pDrawItemInfo->x0,pDrawItemInfo->y0,pDrawItemInfo->x1,pDrawItemInfo->y1);
      //绘制外框,外框使用圆角矩形,填充后,下面又覆盖中间区域
      UNLOCK_BAR_x0=pDrawItemInfo->x0;
      UNLOCK_BAR_y0=pDrawItemInfo->y0;
      if(UNLOCK_BAR_x1){
        GUI_SetColor(GUI_GRAY);     //指定外框颜色
        //绘制外框区域
        GUI_FillRoundedRect(UNLOCK_BAR_x0,UNLOCK_BAR_y0,UNLOCK_BAR_x1,UNLOCK_BAR_y1,LOCK_BAR_RSIZE);
        
        //绘制内框,虽然为填充,后面覆盖掉
        offset=LOCK_BAR_OSIZE;
        GUI_DrawGradientRoundedV(UNLOCK_BAR_x0+offset,      //根据外框尺寸偏移
            UNLOCK_BAR_y0+offset,
            UNLOCK_BAR_x1-offset,
            UNLOCK_BAR_y1-offset,
            LOCK_BAR_RSIZE,GUI_DARKGRAY,GUI_LIGHTGRAY);                     //滑条底部渐变为白色
        
        //绘制滑条
        offset=LOCK_BAR_OSIZE+LOCK_BAR_ISIZE;
        GUI_DrawGradientRoundedV(UNLOCK_BAR_x0+offset,
            UNLOCK_BAR_y0+offset,
            UNLOCK_BAR_x1-offset,                 
            UNLOCK_BAR_y1-offset,                 
            LOCK_BAR_RSIZE,GUI_BLACK,GUI_DARKGRAY);
   
        //绘制动态滑条  
        offset=LOCK_BAR_OSIZE+LOCK_BAR_ISIZE+DY_SLIDE_OSIZE;
        pRect.x0=dy_slider_value+UNLOCK_BAR_x0+offset;
        pRect.x1=pRect.x0+DY_SLIDE_WIDTH;
        pRect.y0=UNLOCK_BAR_y0+offset;
        pRect.y1=UNLOCK_BAR_y1-offset;
        if(dy_slider_value<=DY_SLIDE_WIDTH && init==0){         //头部逐渐出现
          pRect.x0=UNLOCK_BAR_x0+offset;
          pRect.x1=UNLOCK_BAR_x0+offset+dy_slider_value;
          if(dy_slider_value==DY_SLIDE_WIDTH){
            init=1;                 //头部出现效果完成
            dy_slider_value=0;      //正常显示开始
          }
        }
        if((pRect.x1)>=UNLOCK_BAR_x1-offset){                   //尾部逐渐消失
          pRect.x1=UNLOCK_BAR_x1-offset;
          if(pRect.x0>=pRect.x1){
            init=0;
            dy_slider_value=0;
          }  
        }   
        // 绘制动态滑条,使用透明效果
        GUI_DrawGradientRoundedH(pRect.x0,pRect.y0,pRect.x1,pRect.y1,                 
        LOCK_BAR_RSIZE,GUI_MAKE_COLOR((0xaauL << 24) | GUI_DARKGRAY),GUI_MAKE_COLOR((0xaauL << 24) | GUI_WHITE));     //制作混合色   
        
        //显示字体
        pRect.x0=UNLOCK_BAR_x0;
        pRect.y0=UNLOCK_BAR_y0;
        pRect.x1=UNLOCK_BAR_x1;
        pRect.y1=UNLOCK_BAR_y1;
        GUI_SetColor(GUI_GRAY);                           //指定外框颜色
        GUI_SetFont(GUI_FONT_8X16_ASCII);
        GUI_SetTextMode(GUI_TM_TRANS|GUI_TM_XOR);        //设置为显示透明文本
        GUI_DispStringInRectEx(text,&pRect,GUI_TA_VCENTER|GUI_TA_HCENTER,sizeof(text),GUI_ROTATE_0); 
      }
      return 0;
    
    case WIDGET_ITEM_DRAW_SHAFT_R:      //皮肤设置函数将绘制轴的右侧部分。
      UNLOCK_BAR_x1=pDrawItemInfo->x1;
      UNLOCK_BAR_y1=pDrawItemInfo->y1;
      return 0;
    
    case WIDGET_ITEM_DRAW_THUMB:          //皮肤设置函数将绘制缩略图
//      xprintf("THUMB x0:%d y0:%d x1:%d y1:%d \r\n",pDrawItemInfo->x0,pDrawItemInfo->y0,pDrawItemInfo->x1,pDrawItemInfo->y1);
      if(SCROLLBAR0_state!=pSkinInfo->State){           //保存中间按钮状态到用户数据
        SCROLLBAR0_state=pSkinInfo->State;
        SCROLLBAR_SetUserData(pDrawItemInfo->hWin,&SCROLLBAR0_state,sizeof(SCROLLBAR0_state));
      }
      //绘制滑块
      GUI_DrawGradientRoundedV(pDrawItemInfo->x0+SLIDE_OSIZE,
          pDrawItemInfo->y0+SLIDE_OSIZE,
          pDrawItemInfo->x1-SLIDE_OSIZE,
          pDrawItemInfo->y1-SLIDE_OSIZE,
          LOCK_BAR_RSIZE,GUI_WHITE,GUI_LIGHTGRAY);                     //滑条底部渐变为白色    

      //绘制箭头
//      GUI_DrawBitmapEx(&bmicon_unlock_arrow, pDrawItemInfo->x0+(pDrawItemInfo->x1-pDrawItemInfo->x0)/2+2, 
//      (pDrawItemInfo->y1-pDrawItemInfo->y0)/2,bmicon_unlock_arrow.XSize/2,bmicon_unlock_arrow.YSize/2,500,500);
      GUI_MEMDEV_WriteAt(icon_arrow_handle,
      but_lcd_xoffset + ((pDrawItemInfo->x1-pDrawItemInfo->x0)-bmicon_unlock_arrow.XSize)/2+pDrawItemInfo->x0,
      but_lcd_yoffset + ((pDrawItemInfo->y1-pDrawItemInfo->y0)-bmicon_unlock_arrow.YSize)/2+pDrawItemInfo->y0);   
      return 0;
      
    case WIDGET_ITEM_GET_BUTTONSIZE:
      return (pSkinInfo->IsVertical) ?
      pDrawItemInfo->x1 - pDrawItemInfo->x0 + 1 :
      pDrawItemInfo->y1 - pDrawItemInfo->y0 + 1;
      
    default:                            //所有其他类型将以默认皮肤执行
      return SCROLLBAR_DrawSkinFlex(pDrawItemInfo);
  }
}
#endif
/*********************************************************************
*
*       _cbDialog
*/
#if(VIEW_DEBUG==1)
static void debug_view_region(void)
{
  //绘制窗口区域  
  GUI_SetColor(GUI_RED);        
  GUI_FillCircle(2,2,2);
  
  GUI_SetColor(GUI_RED);        
  GUI_DrawRect(LOCK_SCREEN_X-LOCK_BAR_LIMIT, LOCK_BAR_Y0,LOCK_SCREEN_X-LOCK_BAR_LIMIT+LOCK_SCREEN_XSIZE+LOCK_BAR_LIMIT*2,
    LOCK_BAR_Y0+(int)LOCK_SCREEN_YSIZE*0.15f);
  
  //绘制文本区域   
  GUI_SetColor(GUI_WHITE);        
  GUI_DrawRect(LOCK_SCREEN_X, TEXT_BAR_Y0, 
    LOCK_SCREEN_X+LOCK_SCREEN_XSIZE, 
    TEXT_BAR_Y0+TEXT_BAR_YSIZE);
}
#endif

static void _cbDialog(WM_MESSAGE * pMsg) {
  WM_HWIN hItem;
  int SCROLLBAR0_state=0;
  int SCROLLBAR0_value=0;
  char time_id;
  char tbuf[40];

  // USER START (Optionally insert additional variables)
  // USER END
  switch (pMsg->MsgId) {
  case WM_CREATE : 
#if(VIEW_DEBUG==0)
    //创建解锁条
    hItem=SCROLLBAR_CreateUser(LOCK_SCREEN_X-LOCK_BAR_LIMIT, LOCK_BAR_Y0,LOCK_SCREEN_XSIZE+LOCK_BAR_LIMIT*2,(int)LOCK_SCREEN_YSIZE*0.15f,
        pMsg->hWin,WM_CF_SHOW, SCROLLBAR_CF_FOCUSSABLE ,ID_SCROLLBAR_0, sizeof(SCROLLBAR0_state));
    SCROLLBAR_SetNumItems(hItem, SLIDE_STRIP_VALUE);
    SCROLLBAR_SetWidth(hItem,LOCK_BAR_WIDTH);
    SCROLLBAR_SetSkin(hItem,SCROLLBAR_0_DrawSkin);        //设置控件的皮肤回调
    WM_SetFocus(hItem);
   
    //创建文本框,显示时间
    sprintf((char*)tbuf,"%02d:%02d",RTC_TimeStruct.RTC_Hours,RTC_TimeStruct.RTC_Minutes); 
    hItem=TEXT_CreateEx(LOCK_SCREEN_X, TEXT_BAR_Y0,LOCK_SCREEN_XSIZE, TEXT_BAR_YSIZE,
      pMsg->hWin,WM_CF_SHOW,TEXT_CF_HCENTER|TEXT_CF_TOP, ID_TEXT_0,tbuf);
    TEXT_SetFont(hItem,&GUI_Fontfont_songti_38_bold_ascii_unicode);
    TEXT_SetBkColor(hItem, GUI_INVALID_COLOR);            //使用背景颜色,透明字体
    
    /*创建内存设备*/    
    //内存设备区域的左上角起点X坐标  ,由icon_x计算        
    icon_arrow_handle=GUI_MEMDEV_CreateFixed(100,100,
    bmicon_unlock_arrow.XSize,bmicon_unlock_arrow.YSize,
    GUI_MEMDEV_HASTRANS, GUI_MEMDEV_APILIST_16, GUICC_M565);
    //绘制位图
    GUI_MEMDEV_Select(icon_arrow_handle);
    GUI_DrawBitmap(&bmicon_unlock_arrow, 100,100);     
    
    //重新指定LCD输出
    GUI_MEMDEV_Select(0);
#endif    
    break; 

  case WM_PAINT:
    //绘制图标区域
    GUI_SetBkColor(0x00FFC880);         //自定义调色
    GUI_Clear();
    GUI_DrawBitmap(&bmicon_smile, 
    LOCK_SCREEN_XSIZE/2-bmicon_smile.XSize/2, 
    SMILE_ICON_Y0 - bmicon_smile.YSize/2);        
#if(VIEW_DEBUG==1)
    debug_view_region();
#endif 
  break;
 
  case WM_TIMER:
    time_id=WM_GetTimerId(pMsg->Data.v);
    switch(time_id){
      case TIMER_0:           //解锁条的刷新率
        WM_RestartTimer(pMsg->Data.v, LOCK_BAR_REFRESH_RATE);
        //高刷新率刷新解锁条
        //如果滑条按钮没有被按,自动回退
        hItem=WM_GetDialogItem(pMsg->hWin, ID_SCROLLBAR_0);
        WM_InvalidateWindow(hItem);                                                   //单独刷新解锁条
        SCROLLBAR_GetUserData(hItem,&SCROLLBAR0_state,sizeof(SCROLLBAR0_state));      //可以使用全局变量
        if(!(SCROLLBAR0_state & PRESSED_STATE_THUMB)){
          SCROLLBAR_AddValue(hItem,VALUE_NO_TRIGGER);     //中间按钮返回
        }
        dy_slider_value=dy_slider_value+DY_SLIDE_SPEED;
        SCROLLBAR0_value=SCROLLBAR_GetValue(hItem);
        //xprintf("SCROLLBAR0_value:%d\r\n",SCROLLBAR0_value);
        if(SCROLLBAR0_value==(SLIDE_STRIP_VALUE-10)){       //解锁屏幕
          detete_last_win();
          Createwin_mainpage();
        }
        break;
        
      case TIMER_1:                 //时间的刷新率
        sprintf((char*)tbuf,"%02d:%02d",RTC_TimeStruct.RTC_Hours,RTC_TimeStruct.RTC_Minutes); 
        hItem=WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
        TEXT_SetText(hItem,tbuf);
        WM_RestartTimer(pMsg->Data.v, TIME_REFRESH_RATE);
        break;
    }
    break; 
    
  case WM_DELETE:
    GUI_MEMDEV_Delete(icon_arrow_handle);
    break;
  
  default:
    WM_DefaultProc(pMsg);
    break;
  }
}

/*********************************************************************
*
*       Public code
*
**********************************************************************
*/
/*********************************************************************
*
*       Createunlockwin
*/
WM_HWIN Createlockwin(void) {
  WM_HWIN win[WIN_MAX_NUM]={0};
  win[0]=WM_CreateWindowAsChild(LOCK_SCREEN_X, LOCK_SCREEN_Y, LOCK_SCREEN_XSIZE, LOCK_SCREEN_YSIZE,
  WM_HBKWIN, WM_CF_SHOW, _cbDialog, 0);
  lock_handle=win[0];
  
  WM_CreateTimer(win[0], TIMER_0, LOCK_BAR_REFRESH_RATE, 0);
  WM_CreateTimer(win[0], TIMER_1, TIME_REFRESH_RATE, 0);
  switch_win(win,LOCK_WIN_ID);
  return win[0];
}

// USER START (Optionally insert additional public code)
// USER END

/*************************** End of file ****************************/

GUI线程代码 gui_thread.c

#include "GUI_app/gui_thread.h"
#include "stm32f4xx.h"
#include "GUI.h"
#include "WM.h"
#include "serial.h"
#include "LCD/lcd.h"

/*********************************************************************************************
* GUI全局配置变量
*********************************************************************************************/

WM_HWIN _hLastFrame[WIN_MAX_NUM]={0};											//当前所在窗口的句柄,全局
unsigned char Last_win_id;								//当前所在窗口的ID,全局
GUI_MEMDEV_Handle    hMempic;
GUI_PID_STATE pid_state;
unsigned short LCD_xsize;
unsigned short LCD_ysize;

extern GUI_CONST_STORAGE GUI_BITMAP bmIOS15_1;
extern struct graphic_device g_dev;
extern WM_HWIN Createlockwin(void);
extern WM_HWIN Createwin_mainpage(void);
extern WM_HWIN CreateFramewin(void);
extern WM_HWIN Createstatus_bar(void);
extern GUI_CONST_STORAGE GUI_BITMAP bmicon_smile;

/*********************************************************************************************
* 声明
*********************************************************************************************/
#if(USE_GUI_EXAMPLE==2)
static void touch_app_1(void);
static void gui_app_1(void);
static void gui_app_2(void);
#endif
#if(USE_GUI_EXAMPLE==1)
static void gui_alloc_GetNumFreeBytes(void);
#endif

void switch_win(WM_HWIN* win,unsigned char id)
{
  memcpy(_hLastFrame,win,sizeof(WM_HWIN)*WIN_MAX_NUM);
  Last_win_id=id;
}

void detete_last_win(void)
{
  char i;
  WM_HWIN temp;
  for(i=0;i<WIN_MAX_NUM;i++){
    if(_hLastFrame[i]!=0){
      temp=_hLastFrame[i];
      _hLastFrame[i]=0;           //在父窗口删除前,先清理掉标志位。防止硬件错误。
      WM_DeleteWindow(temp);
    } 
  }
}      
/*********************************************************************************************
* 名称:emwin_init()
* 功能:emWin初始化
* 参数:无
* 返回:无
* 修改:
* 注释:
*********************************************************************************************/
static void emwin_init(void)
{                                 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);           // 开启CRC时钟
  GUI_Init();                                                   // emWin初始化
  WM_SetCreateFlags(WM_CF_MEMDEV);                              // 窗口启用内存设备
  GUI_UC_SetEncodeUTF8();                                       // 使用UTF-8编码
  GUI_EnableAlpha(1);                                           // 开启透明效果
//  WM_MULTIBUF_Enable(1);                                        // 开启多缓存
  WM_MOTION_Enable(1);                                          // 窗口移动支持
}

static void emwin_init_parameter(void)
{
  LCD_xsize=LCD_GetXSize();
  LCD_ysize=LCD_GetYSize(); 
}
/*********************************************************************************************
* 函 数 名: _cbBkWindow
* 功能说明: 桌面窗口回调函数
* 形    参:pMsg  参数指针
* 返 回 值: 无
*********************************************************************************************/
static void _cbBkWindow(WM_MESSAGE* pMsg)
{

  switch (pMsg->MsgId)
  {
    case WM_PAINT:
      GUI_SetBkColor(GUI_WHITE);         //自定义调色
      GUI_Clear();
    break;
    
    case MSG_LOCK:
      detete_last_win();
      Createlockwin();
      break;
    
    default:
      WM_DefaultProc(pMsg);
  }
}

/*********************************************************************************************
* 名称:gui_thread_entry()
* 功能:GUI线程入口函数
* 参数:*parameter -> 入口参数(暂无)
* 返回:无
* 修改:
* 注释:
*********************************************************************************************/
void gui_thread_Task(void *parameter)
{
  (void)parameter;
  unsigned int time=0;

  emwin_init();
  emwin_init_parameter();
  WM_SetCallback(WM_HBKWIN, &_cbBkWindow);    //设置桌面窗口的回调函数 
  
  Createstatus_bar();
//  Createlockwin();
  Createwin_mainpage();
  while(1)
  {
#if(USE_GUI_EXAMPLE==1)
    gui_alloc_GetNumFreeBytes();      // 获取GUI VM管理器的剩余内存        
//    gui_app_1();                            // 测试DEMO
//    touch_app_1();                          // 测试DEMO
#endif
    GUI_TOUCH_Exec();                         // 触摸刷新
    GUI_Delay(GUI_TASK_DELAY);                            // GUI刷新并延时
    
    // 触发锁屏
    if(Last_win_id!=LOCK_WIN_ID){
      time++;
      if(time*GUI_TASK_DELAY>=(unsigned int)LOCK_DELAY*1000){
        WM_SendMessageNoPara(WM_HBKWIN,MSG_LOCK);
        time=0;
      }
      // 重置计时
      if(time%20==0){       //降低消耗
        GUI_TOUCH_GetState(&pid_state); 
      }
      if(pid_state.Pressed){              
        time=0;
        pid_state.Pressed=0;
      }  
    }
  }  
//  vTaskDelete(NULL);
}

#if(USE_GUI_EXAMPLE==1)
// 获取GUI当前的剩余内存
static void gui_alloc_GetNumFreeBytes(void)
{
    uint32_t ram;
    static uint32_t times;
    times++;
    if(times%1000==0){
      ram=GUI_ALLOC_GetNumFreeBytes();      //获取GUI剩余内存空间
      xprintf("ram is %d\r\n",ram);
    }
}
#endif
#if(USE_GUI_EXAMPLE==2)
//测试验证读点函数
static void gui_app_2(void)
{
  GUI_SetColor(GUI_YELLOW);
  GUI_SetDefaultFont(&GUI_Font8x16);
  GUI_SetFont(&GUI_Font8x16);
  GUI_SetBkColor(GUI_BLUE);
  GUI_Clear();
  GUI_SetPenSize(10);
  GUI_SetColor(GUI_RED);
  GUI_DrawLine(20, 10, 180, 90);        //某个指定起点到某个指定终点之间的线,前面是点1的XY
  GUI_DrawLine(20, 90, 180, 10);
  GUI_SetBkColor(GUI_BLACK);
  GUI_SetColor(GUI_WHITE);
  GUI_SetTextMode(GUI_TM_NORMAL);       //设置为显示正常文本
  GUI_DispStringHCenterAt("GUI_TM_NORMAL", 100, 10);
  GUI_SetTextMode(GUI_TM_REV);          //设置为显示反转文本,就是字体和背景颜色反转颜色
  GUI_DispStringHCenterAt("GUI_TM_REV", 100, 26);
  GUI_SetTextMode(GUI_TM_TRANS);        //设置为显示透明文本
  GUI_DispStringHCenterAt("GUI_TM_TRANS", 100, 42);
  GUI_SetTextMode(GUI_TM_XOR);          //设置为反相显示的文本,会存在读点颜色
  GUI_DispStringHCenterAt("GUI_TM_XOR", 100, 58);
  GUI_SetTextMode(GUI_TM_TRANS | GUI_TM_REV);   //反转文本和透明背景
  GUI_DispStringHCenterAt("GUI_TM_TRANS | GUI_TM_REV", 100, 74);
}

//验证
static void gui_app_1(void)
{
  static const GUI_COLOR color[3][2] = {
  {0x00FFFF, 0x0000FF},                                         // 黄色 -> 红色
  {0xFFFF00, 0x00FF00},                                         // 青色 -> 绿色
  {0xFF00FF, 0xFF0000},                                         // 紫色 -> 蓝色
  };
  static short x = 0, y = 0;
  static unsigned char num = 0;
  if(x >= g_dev.lcd_dev->width)                                                // 制造位移变色效果
  {
    x = -60;            //X复位
    y += 20;            //Y方向下移
    if(y >= g_dev.lcd_dev->height)
    {
      num++;            //变化颜色
      if(num >= 3)
        num = 0;
      y = 0;            //Y复位
    }
  }
  // 绘制用水平颜色梯度填充的矩形
  GUI_DrawGradientH(x, y, x+60, y+20, color[num][0], color[num][1]);
  x++;
}

//验证emwin是否正常回调触摸刷新
static void touch_app_1(void)
{
  int x_value=GUI_TOUCH_GetxPhys();
  int y_value=GUI_TOUCH_GetyPhys();
  xprintf("x:%d,y:%d\r\n",x_value,y_value);
}
#endif

gui_thread.h

#ifndef __GUI_THREAD_H_
#define __GUI_THREAD_H_
#include "GUI.h"
#include "WM.h"

// 窗口消息定义
#define MSG_SWITCH            (WM_USER + 1)
#define MSG_MAIN_PAGE_SWITCH  (WM_USER + 2)
#define MSG_WIN_INVAILD       (WM_USER + 3)
#define MSG_LOCK              (WM_USER + 4)

// 通知父窗口消息定义
#define NOTIFICATION_UNLOCK (WM_NOTIFICATION_USER+1)

// 窗口ID
#define LOCK_WIN_ID         1
#define MIAN_PAGE_WIN_ID    2

#define WIN_MAX_NUM       5    //页面支持的最大窗口数量

// 外部引用声明
extern WM_HWIN _hLastFrame[WIN_MAX_NUM];										//当前所在窗口的句柄,全局
extern unsigned char Last_win_id;								//当前所在窗口的ID,全局
extern unsigned short LCD_xsize;
extern unsigned short LCD_ysize;

// 函数声明
void gui_thread_Task(void *parameter);
void lock(void);              //创建解锁画面
void switch_win(WM_HWIN* win,unsigned char id);    //切换窗口需要引用
void detete_last_win(void);
#endif //__GUI_THREAD_H_

config.h

#ifndef __CONFIG_H__
#define __CONFIG_H__
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
#include "stdio.h"
#include "string.h"
/* Hardware and starter kit includes. */
#include "stm32f4xx.h"
#include "stm32f4xx_conf.h"
/*************全局config文件*************/

/*************ESP32配置*************/
//#define CAR_MACADDR     "40:22:d8:eb:49:bc"        	//设置小车的目标地址
#define CAR_MACADDR     ""        	//设置小车的目标地址

/*************STemWin532*************/
#define PKG_STEMWIN_MEM_SIZE    120									//STemWin532使用的动态内存大小,内存设备需要较大的RAM
#define GUI_NUMBYTES  (PKG_STEMWIN_MEM_SIZE * 1024)
/* Define the average block size */
#define GUI_BLOCKSIZE 0x80                          //块大小

/* 电阻触摸屏的AD定义 校准使用 */
#define TOUCH_AD_LEFT       170
#define TOUCH_AD_RIGHT      3850
#define TOUCH_AD_TOP        265
#define TOUCH_AD_BOTTOM     3950

/* GUI线程 */
#define GUI_TASK_DELAY      5      //GUI主线程延时,单位ms
#define LOCK_DELAY          120       //屏幕没有触发后时间锁定,单位s
#define USE_GUI_EXAMPLE     0       //GUI开启示例

#define STATUS_BAR_HEIGHT   15      //单位像素 

/*************微秒级函数*************/
void hw_us_delay(unsigned int us);    //微秒级延时
unsigned int xtime(void);             //获取系统的运行时间us

/*************中断优先级配置*************/
#define USART1_INT_PRIORITY       7
#define USART3_INT_PRIORITY       7
#define RTC_ALARM_INT_PRIORITY    10
#define CPU_USAGE_TIMER_PRIORITY  6

/*************CLI示例命令*************/
#define CLI_USE_EXAMPLE           0

/*************CPU使用率统计*************/
#define CPU_USAGE_USE_TIM         0
/*************定时器使用*************/
#if(CPU_USAGE_USE_TIM==1)
#define CPU_USAGE_TIMER           TIM6
#define CPU_USAGE_TIMER_RCC       RCC_APB1Periph_TIM6
#define CPU_USAGE_TIMER_IRQ       TIM6_DAC_IRQn
#endif
#endif

源代码链接:

https://download.csdn.net/download/W809291634/88362696

因没有时间去优化,是一个测试代码,此源码存在以下问题:

1、没有使用带OS enwin库,所以建议单线程使用emwin的API,比如,不要在两个线程中使用到emwin的API,否则可能会出现硬件错误

2、串口DMA接收处理使用的其中的一种方法,可以使用环形缓存区进行改进

3、基本上测试稳定,有很大的优化空间

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值