OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7844|回复: 5

emwin 实现触摸按钮长按动作【解决方案】

[复制链接]

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2016-9-14 20:22:18 | 显示全部楼层 |阅读模式
在网上以及论坛上,看到很多人都在为 "emwin中实现触摸按钮长按动作" 而迷茫!

那就看看本人是怎么实现的吧!

说明: 本人提供的代码已经在自己的产品上,应用很多年了。在此与大家分享一下!

运行机制说明:
  1、一个任务中,定时向主窗体发送更新消息;
  2、主窗体任务, 实时接收更新消息;
  3、如果按钮长时间按下,对应的变量递增;
  4、持续按下的时间,还没有达到设定时间, 按钮抬起,执行一般的动作;
  5、递增到设定的时间后,响应长时间按下的功能动作;

#define SCREEN_PARAM_SET       10+4
#define SCREEN_CALIB_SET         10+5

#define SCREEN_DISTABOUT        10+6
#define SCREEN_DEVICE_CHK       10+7
#define SCREEN_TEST_RUN          10+8
#define SCREEN_STOP_TEST         10+9


typedef struct tagSendMsgInfo{
    int item;
    char *str[10];       
} SEND_MSG_INFO;


static SEND_MSG_INFO  t_msg;       

u8  curr_screen =0;  

static WM_HWIN _hClinet;     //用户区窗口句柄               
static WM_MESSAGE Msg;     //用户窗体信息



WM_HWIN  ParamSet_hWin;  //参数设置窗口---句柄       

WM_HWIN  Calib_hWin;           //校准窗口--------句柄       


****************************************************************************       
* 功    能:    用户信息更新-------任务
*----------------------------------------------------------------------------------------------------------*
* 入口参数:  p_arg-----A pointer to parameter passed to task.
* 出口参数:  nil
****************************************************************************/       

void Task_UserMsg_Update (void *p_arg)
{
     while (1)
     {
           /*----例如: 发送日期消息----------------------------*/
           // t_msg.item=5;  //显示日期的信息识别号
           //  t_msg.str[5]=(char *)Date_buff;        //发送日期消息内容       

          switch(curr_screen)  //当前的窗口
            {
                    case SCREEN_PARAM_SET: //参数设置屏幕       
                                    Msg.MsgId = WM_USER + 50;
                                  Msg.Data.p = &t_msg; //可以发送附属的信息                               
                                       
                                   _hClinet=WM_GetClientWindow(ParamSet_hWin);//获得用户区窗口句柄                       
                                   WM_SendMessage(_hClinet, &Msg);   
                                          
                                   break;

                     case SCREEN_CALIB_SET: //校准屏幕
                                  Msg.MsgId = WM_USER + 60;
                                  Msg.Data.p = &t_msg;                                       
                                       
                                  _hClinet=WM_GetClientWindow(Calib_hWin);//获得用户区窗口句柄                       
                                  WM_SendMessage(_hClinet, &Msg);                                
                                   break;
                     //.......................................
                     //.......................................
                    //.......................................
            }

         OSTimeDly (200); //每0.2S更新一次
    }
}


/****************************************************************************       
* 功    能:     应用开始主任务
*---------------------------------------------------------------------------*
* 入口参数:pdata        A pointer to parameter passed to task.
* 出口参数:nil
****************************************************************************/       

static  void  AppTaskStart (void *p_arg)

{

    while(1)
     {
            TFT_MainFrame() ;  //主界面窗体
            OSTimeDly(100);
     }
}



static u8     at_status[2]={0,0};
static u8     flag_press_bt[2]={0,0};
static u32   num_press_bt[2]={0,0};



#define  PARAM_SET_MSG_ID     (WM_USER + 50)


/*********************************************************************
*
*       MainFrame
*
**********************************************************************
*/
void TFT_MainFrame(void)
{         
     #if OS_CRITICAL_METHOD == 3   
        OS_CPU_SR  cpu_sr = 0;
     #endif       


     //...............................
     //...............................

      OS_ENTER_CRITICAL();
      curr_screen=SCREEN_PARAM_SET;
      OS_EXIT_CRITICAL();


      ParamSet_hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);                       
       
      WM_SetFocus(WM_GetDialogItem(ParamSet_hWin, GUI_ID_BUTTON2));        //焦点于按钮2       
}



/*
********************************************************************
* ParamSet_hWin窗口下的 回调函数                                                             *
********************************************************************
*/


static void _cbCallback(WM_MESSAGE * pMsg)   
{            
     int NCode, Id;       
     WM_HWIN hItem;       
       
      #if OS_CRITICAL_METHOD == 3   
      OS_CPU_SR  cpu_sr = 0;
      #endif                  
         
      WM_HWIN hDlg = pMsg->hWin;
       
       
      switch (pMsg->MsgId)
      {
            //...............................
            //...............................                  
            case PARAM_SET_MSG_ID:  //此窗口下的消息更新

               if(flag_press_bt[0]==1){                       
                   num_press_bt[0]++;                       
                }       

                if(flag_press_bt[1]==1){                       
                   num_press_bt[1]++;                       
                }                                           
               break;
            case WM_NOTIFY_PARENT:
                Id    = WM_GetId(pMsg->hWinSrc);
                NCode = pMsg->Data.v;
                switch(NCode)
                  {                                                         
                      case WM_NOTIFICATION_SEL_CHANGED:
                           //...............................
                           //...............................       
                          break;
                      case WM_NOTIFICATION_CLICKED:  //控件点击---响应
                          switch(Id){                                                                                                                                                    
                                case        GUI_ID_BUTTON40:        //长按作用按钮1
                                         num_press_bt[0]=0; //clear                                                                                                       
                                         flag_press_bt[0]=1;                                                                                 
                                         break;                                                                               
                                case        GUI_ID_BUTTON41:
                                        num_press_bt[1]=0; //长按作用按钮2                                                               
                                        flag_press_bt[1]=1;                               
                                        break;                                                                                       
                                case        GUI_ID_BUTTON3:                                                                         
                                        break;                       
                                case        GUI_ID_BUTTON4:                        
                                        break;                                 
                          }                            
                          break;
                     case  WM_NOTIFICATION_RELEASED: //按钮释放---响应
                           switch(Id){       
                               case        GUI_ID_BUTTON40:         //长按作用按钮1                                                                                                 
                                    if(num_press_bt[0]>15){   //定时3s:  15*0.2s=3s  [ 注: 0.2s更新一次]                                                                 
                                         flag_press_bt[0]=2;   //改变状态
                                         num_press_bt[0]=0; //clear
                                          //...............................
                                          //执行用户自己的功能代码
                                         //...............................       
                                    }else{
                                        flag_press_bt[0]=0;//clear
                                        num_press_bt[0]=0; //clear       
                                         //...............................                                                 //执行用户自己的功能代码                              
                                   }       

                                   break;       
                              case        GUI_ID_BUTTON41:         //长按作用按钮2                                                                                                                                     if(num_press_bt[1]>15){   //定时3s:  15*0.2s=3s  [ 注: 0.2s更新一次]                                                                 
                                         flag_press_bt[1]=2;   //改变状态
                                         num_press_bt[1]=0; //clear
                                          //...............................
                                          //执行用户自己的功能代码
                                         //...............................       
                                    }else{
                                        flag_press_bt[1]=0;//clear
                                        num_press_bt[1]=0; //clear       
                                         //...............................                                                 //执行用户自己的功能代码                              
                                   }       

                                  break;               
       
                               //...............................
                                //其它的功能按钮响应
                               //...............................       
                             }
                          break;                                               
                  }
       }

}







正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

16

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
274
金钱
274
注册时间
2019-8-17
在线时间
57 小时
发表于 2019-11-14 10:05:31 | 显示全部楼层
理论可行,学习了。谢谢!
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2019-4-9
在线时间
30 小时
发表于 2019-11-16 14:05:41 | 显示全部楼层
高手,学习了
回复 支持 反对

使用道具 举报

10

主题

94

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2014-8-14
在线时间
129 小时
发表于 2019-11-18 15:11:52 | 显示全部楼层
emwin中button按下和弹起都有回调的,然后get下时基就可以。这种方式有一个不方便的地方就是必须等到释放才能执行长按动作
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2013-10-8
在线时间
27 小时
发表于 2022-4-30 22:58:27 | 显示全部楼层
厉害了
回复 支持 反对

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
186
金钱
186
注册时间
2017-12-12
在线时间
58 小时
发表于 2022-5-14 23:33:05 | 显示全部楼层
虽然我是新手,我试了下在按下的时候置一个标志位,同时创建一个定时器,在定时器函数里面去处理相关长按动作,能轻松解决!!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 12:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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