硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4734|回复: 24
收起左侧

[emWin] stemwin 升级版本540后,edit焦点控制不兼容老程序

[复制链接]

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
发表于 2018-8-27 16:46:14 | 显示全部楼层 |阅读模式
本帖最后由 caicaptain2 于 2018-8-29 10:20 编辑

原来是528版本,edit控件,disable后,可以通过tab键切换焦点。

换成540后,edit控件,disable后,tab键只能切换button的焦点,不能切换edit的焦点。 但是可以使用WM_Setfocus()切换焦点到edit上。 查了用户手册,没有发现明显区别。

------------------------------------结帖-----2018-8-29------------------------------------

经过反复摸索,找到了emwin中文档没有介绍过,但是在Widget.h内存在的函数。 自定义了两个函数,代替tab和backtab键。
主要使用了WM_GetNextSibling()获得下一个控件,使用WIDGET_GetState()获得控件能否“有效”聚焦。
  1. <div>void User_WidgetNextFocus(const GUI_WIDGET_CREATE_INFO paWidget[],WM_MESSAGE *pMsg,int32_t WidgetNumber)   //用在WM_KEY消息中,选择下一个控件的焦点。
  2. {
  3. WM_HWIN  hItem;
  4.   int     Id;
  5. uint16_t i=0;
  6. hItem=WM_GetFocusedWindow();  //获得当前聚焦的控件句柄
  7. do{  hItem=WM_GetNextSibling(hItem); //获得下一个控件的句柄,相对当前的聚焦控件
  8.       if(hItem==0)  //说明,没有上一个控件的时候,需要设定到最后的控件,以便焦点循环。
  9.           {Id=paWidget[1].Id;hItem=WM_GetDialogItem(pMsg->hWin,Id);} //因为资源列表的第一行是父窗口,不是控件。得从第二行开始。
  10.     i=WIDGET_GetState(hItem);  //获得控件的状态参数。一个16位整形。参考wdiget.h里面的定义States
  11.    } while((i&WIDGET_STATE_FOCUSABLE)==0);
  12.     WM_SetFocus(hItem);
  13. }</div><div>
  14. //WdigetNumber 必须得加上,因为传递数组时,需要知道数组大小。
  15. void User_WidgetPrevFocus(const GUI_WIDGET_CREATE_INFO paWidget[],WM_MESSAGE *pMsg,int32_t WidgetNumber) //用在WM_KEY消息中,选择上一个控件的焦点。
  16. {
  17. WM_HWIN  hItem;
  18.   int     Id;
  19. uint16_t i=0;
  20. hItem=WM_GetFocusedWindow();  //获得当前聚焦的控件句柄
  21. do{  hItem=WM_GetPrevSibling(hItem); //获得上一个控件的句柄,相对当前的聚焦控件
  22.     if(hItem==0)  //说明,没有上一个控件的时候,需要设定到最后的控件,以便焦点循环。
  23.         {Id=paWidget[WidgetNumber-1].Id;hItem=WM_GetDialogItem(pMsg->hWin,Id);}
  24.   i=WIDGET_GetState(hItem);  //获得控件的状态参数。一个16位整形。参考wdiget.h里面的定义States
  25. } while((i&WIDGET_STATE_FOCUSABLE)==0);
  26.   WM_SetFocus(hItem);
  27. }</div>
复制代码
使用的时候,在对话框的回调函数中,找到WM_KEY消息下:(_aDialogCreate是对话框资源列表数组。用GUIBuild创建时的默认名字)
  1. case WM_KEY:
  2. switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
  3.        {   
  4.          case GUI_KEY_LEFT:
  5.         //GUI_SendKeyMsg(GUI_KEY_BACKTAB,1);
  6.                 User_WidgetPrevFocus(_aDialogCreate,pMsg,GUI_COUNTOF(_aDialogCreate));   
  7.         break;
  8.        case GUI_KEY_RIGHT:
  9.         //GUI_SendKeyMsg(GUI_KEY_TAB,1);
  10.                 User_WidgetNextFocus(_aDialogCreate,pMsg,GUI_COUNTOF(_aDialogCreate));
  11.         break;      
  12.         case GUI_KEY_UP:
  13.         //GUI_SendKeyMsg(GUI_KEY_BACKTAB,1);
  14.                 User_WidgetPrevFocus(_aDialogCreate,pMsg,GUI_COUNTOF(_aDialogCreate));
  15.         break;
  16.         case GUI_KEY_DOWN:
  17.         //GUI_SendKeyMsg(GUI_KEY_TAB,1);
  18.                 User_WidgetNextFocus(_aDialogCreate,pMsg,GUI_COUNTOF(_aDialogCreate));
  19.         break;
  20.         }
  21. break;
复制代码




回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107439
QQ
发表于 2018-8-28 01:34:08 | 显示全部楼层
聚焦问题是STemWin永远的痛,禁止控件后,同时禁止聚焦貌似更合理些。

另外你禁止后,调用这个函数试试WIDGET_SetFocusable,基本所有支持聚焦的控件可以用这个函数单独设置,是5.40新增的。
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-8-28 16:24:44 | 显示全部楼层
eric2013 发表于 2018-8-28 01:34
聚焦问题是STemWin永远的痛,禁止控件后,同时禁止聚焦貌似更合理些。

另外你禁止后,调用这个函数试试W ...

很遗憾,即时加上 EDIT_SetFocussable(hItem,1);
发送tab键,还是没有办法聚焦到edit控件上,这个有点无法理解了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107439
QQ
发表于 2018-8-29 01:04:34 | 显示全部楼层
caicaptain2 发表于 2018-8-28 16:24
很遗憾,即时加上 EDIT_SetFocussable(hItem,1);
发送tab键,还是没有办法聚焦到edit控件上,这个有点 ...

你在此基础上再创建两个EDIT控件,看看是否也无法聚焦。

记得新版emWin,在创建多个EDIT控件的时候,第1个无法聚焦接收消息。后面的没问题,具体挤不太清楚了。
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-8-29 10:09:48 | 显示全部楼层
eric2013 发表于 2018-8-29 01:04
你在此基础上再创建两个EDIT控件,看看是否也无法聚焦。

记得新版emWin,在创建多个EDIT控件的时候, ...

还是不行。只要disable了edit控件,即使强制设定 EDIT_SetFocussable(hItem,ENABLE);也无法通过tab键设定到焦点。

但是,通过WM_SetFocus()可以设定焦点到任何窗口,比如text控件,frame控件,edit等等。只是,某些控件(Text, Frame)的焦点无意义。
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-8-29 10:22:05 | 显示全部楼层
在WM.h中,有两个函数比较有意思,估计有时候用的上。
WM_HWIN   WM_SetFocusOnNextChild  (WM_HWIN hParent);     /* Set the focus to the next child */
WM_HWIN   WM_SetFocusOnPrevChild  (WM_HWIN hParent);     /* Set the focus to the previous child */

disable了的控件无法用以上函数获得焦点。


回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-8-29 10:25:33 | 显示全部楼层
caicaptain2 发表于 2018-8-29 10:22
在WM.h中,有两个函数比较有意思,估计有时候用的上。
WM_HWIN   WM_SetFocusOnNextChild  (WM_HWIN hPare ...

备注:
/*********************************************************************
*
*       States
*/

#define WIDGET_STATE_FOCUS              (1 << 0)
#define WIDGET_STATE_VERTICAL           (1 << 3)
#define WIDGET_STATE_FOCUSABLE          (1 << 4)

#define WIDGET_STATE_USER0              (1 << 8)    /* Freely available for derived widget */
#define WIDGET_STATE_USER1              (1 << 9)    /* Freely available for derived widget */
#define WIDGET_STATE_USER2              (1 << 10)   /* Freely available for derived widget */

#define WIDGET_STATE_FOCUSSABLE         WIDGET_STATE_FOCUSABLE

/*********************************************************************
/*********************************************************************
*
*       API routines
*
**********************************************************************
*/
void  WIDGET_SetState     (WM_HWIN hObj, int State);
void  WIDGET_AndState     (WM_HWIN hObj, int State);
void  WIDGET_OrState      (WM_HWIN hObj, int State);
int   WIDGET_HandleActive (WM_HWIN hObj, WM_MESSAGE* pMsg);
int   WIDGET_GetState     (WM_HWIN hObj);
int   WIDGET_SetWidth     (WM_HWIN hObj, int Width);
void  WIDGET_SetFocusable (WM_HWIN hObj, int State);
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-8-29 10:33:40 | 显示全部楼层
本帖最后由 caicaptain2 于 2018-8-29 10:35 编辑

emwin中,我最爱edit控件,它特别的灵活方便,适用于最常用的人机数据交换。 所以研究的也比较多。edit还可以当作TEXT控件来用,表示加重框框显示的文字/数据说明
emwin中找不出另一个控件可以如此简洁便利。

比如,经常需要设定10个参数,有字符的,有浮点的,有整数的。edit全部可以搞定,修改数字的过程也非常人性化。小数点位置,数据范围,光标指示,字体,颜色等都可以自由设定。
创建10个edit控件,每个默认都是disable的,使用上下左右来切换焦点(选择某个edit控件),然后按enter(确认键)enable它,可以开始修改它。此刻上下左右就是控制数字和光标。修改好了以后,再按enter键,确认更新的数据,disable它。又可以选择其他edit控件了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107439
QQ
发表于 2018-8-29 12:38:18 | 显示全部楼层
你楼主位提供的这段函数User_WidgetNextFocus的意思是:

通过函数WIDGET_GetState(hItem)可以获得聚焦状态,但是无法使用。
调用了函数 WM_SetFocus(hItem);就可以正常使用了。
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-8-29 15:28:49 | 显示全部楼层
eric2013 发表于 2018-8-29 12:38
你楼主位提供的这段函数User_WidgetNextFocus的意思是:

通过函数WIDGET_GetState(hItem)可以获得聚焦状 ...

不是这个意思。。。。
WIDGET_GetState(hItem)的作用是,判断当前控件的聚焦是否有意义。 因为有一些控件的聚焦是没有意义的。 比如text控件。 text控件一样可以使用wm_setfocus()来设定聚焦,只是没有任何显示。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107439
QQ
发表于 2018-8-29 15:34:59 | 显示全部楼层
caicaptain2 发表于 2018-8-29 15:28
不是这个意思。。。。
WIDGET_GetState(hItem)的作用是,判断当前控件的聚焦是否有意义。 因为有一些控 ...

明白了,还有这个功效。

判断后,然后通过wm_setfocus()就可以往禁能的EDIT上聚焦了?
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-8-29 16:05:47 | 显示全部楼层
eric2013 发表于 2018-8-29 15:34
明白了,还有这个功效。

判断后,然后通过wm_setfocus()就可以往禁能的EDIT上聚焦了?

是的。 禁止的控件,不响应按键,因为按键消息都发送给父窗口了(对话框),但是控件可以聚焦。
回复

使用道具 举报

12

主题

33

回帖

69

积分

初级会员

积分
69
发表于 2018-10-29 11:57:06 | 显示全部楼层
本帖最后由 wx_ZvqJUIdV 于 2018-10-29 11:59 编辑
caicaptain2 发表于 2018-8-29 10:33
emwin中,我最爱edit控件,它特别的灵活方便,适用于最常用的人机数据交换。 所以研究的也比较多。edit还可 ...

这位大神,我只有键盘,edit控件聚焦的时候怎么明显一点啊,一圈浅蓝都看不出来啊,还有,你上下左右是怎么切换聚焦的,tab键吗,还是自己设置啊,怎么确定上下左右啊,要一大堆if判断吗
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-10-29 14:04:46 | 显示全部楼层
wx_ZvqJUIdV 发表于 2018-10-29 11:57
这位大神,我只有键盘,edit控件聚焦的时候怎么明显一点啊,一圈浅蓝都看不出来啊,还有,你上下左右是怎 ...

如果用tab键,最方便。 只需要在创建窗口的资源列表的时候注意控件的顺序。 但是,如果控件是矩形排列,焦点移动不够人性化。 做工业产品,这个人性化要求不高,可以用这个方法。

如果用上下左右键任意切换控件,需要建立一个资源控件ID的2维数组,每次根据方向键来变更数组下标,然后用Setfocus主动设定焦点。 这个比较麻烦点,但是控制人性化一点。

回复

使用道具 举报

12

主题

33

回帖

69

积分

初级会员

积分
69
发表于 2018-10-29 14:44:27 | 显示全部楼层
eric2013 发表于 2018-8-28 01:34
聚焦问题是STemWin永远的痛,禁止控件后,同时禁止聚焦貌似更合理些。

另外你禁止后,调用这个函数试试W ...

大神啊,spinbox 跟edit有什么区别啊
回复

使用道具 举报

12

主题

33

回帖

69

积分

初级会员

积分
69
发表于 2018-10-29 14:48:41 | 显示全部楼层
caicaptain2 发表于 2018-10-29 14:04
如果用tab键,最方便。 只需要在创建窗口的资源列表的时候注意控件的顺序。 但是,如果控件是矩形排列, ...

大神啊,spinbox 跟edit有什么区别啊,我设置个调整带小数点的怎么就这么麻烦呢,各种不正常,还有啊,你说的edit enable和disable上下左右的功能是怎么变得啊,怎么就自动切换聚焦和编辑内部的,是不是还是得判断一下啊
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-10-30 08:30:19 | 显示全部楼层
wx_ZvqJUIdV 发表于 2018-10-29 14:48
大神啊,spinbox 跟edit有什么区别啊,我设置个调整带小数点的怎么就这么麻烦呢,各种不正常,还有啊,你 ...

给你一个自定义的edit回调函数。 因为edit一旦有焦点,上下左右就只能变更它的内容,不能切换焦点了。所以,通过enter键来使能/禁止edit,禁止后的edit就不会响应上下左右了。
//自定义EDIT控件回调函数,可响应enter和取消按键。 2015-10-18
void User_EDIT_Callback(WM_MESSAGE *pMsg)
{
    WM_HWIN hItem;
    hItem=pMsg->hWin;
    switch (pMsg->MsgId)
    {
    case WM_KEY:
        switch((((WM_KEY_INFO*)(pMsg->Data.p))->Key))
        {
        case GUI_KEY_ENTER:
            if(WM_IsEnabled(hItem))
            {
                WM_DisableWindow(hItem);
                WM_NotifyParent(hItem,WM_NOTIFICATION_CONFIRM);
            }
            else
            {
                WM_EnableWindow(hItem);
                WM_NotifyParent(hItem,WM_NOTIFICATION_ENABLE);
            }
            break;
        case GUI_KEY_ESCAPE:

            WM_DisableWindow(hItem);
            WM_NotifyParent(hItem,WM_NOTIFICATION_CANCEL);
            break;
        default:
            EDIT_Callback(pMsg);
            break;
        }
        break;
    default:
        EDIT_Callback(pMsg);
        break;
    }
}
回复

使用道具 举报

12

主题

33

回帖

69

积分

初级会员

积分
69
发表于 2018-10-30 09:00:04 | 显示全部楼层
caicaptain2 发表于 2018-10-30 08:30
给你一个自定义的edit回调函数。 因为edit一旦有焦点,上下左右就只能变更它的内容,不能切换焦点了。所 ...

大神啊,既然这样,你是在有焦点的时候映射成上下左右,没有焦点的时候自定义成tab吗,不然上下左右怎么切换焦点的,你是怎么判断的啊
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2018-10-30 11:16:36 | 显示全部楼层
本帖最后由 caicaptain2 于 2018-10-30 11:18 编辑
wx_ZvqJUIdV 发表于 2018-10-30 09:00
大神啊,既然这样,你是在有焦点的时候映射成上下左右,没有焦点的时候自定义成tab吗,不然上下左右怎么 ...

简便的方法是,切换焦点的时候,把左和上键的消息用backtab发出去,右键和下键用tab发出去。
你识别到按键的时候,可以发送别的按键消息。比如:
case GUI_KEY_LEFT:  
        GUI_SendKeyMsg(GUI_KEY_BACKTAB,1);
        break;

回复

使用道具 举报

12

主题

33

回帖

69

积分

初级会员

积分
69
发表于 2018-10-30 13:21:59 | 显示全部楼层
caicaptain2 发表于 2018-10-30 11:16
简便的方法是,切换焦点的时候,把左和上键的消息用backtab发出去,右键和下键用tab发出去。
你识别到按 ...

这位大神,EDIT收到backtab能识别成left吗,其实我想问的是怎么在上下左右和tab backtab之间切换的
回复

使用道具 举报

613

主题

3067

回帖

4926

积分

至尊会员

积分
4926
发表于 2018-11-1 14:34:49 | 显示全部楼层
你好,请教下,在使用输入法时,直接吧输入的内容增加到 edit 的控件里面,edit 控件貌似不能够显示 英文的 感叹号 ! 还有 英文的 单双 引号 " ,其他的字符都可以正常显示,请问这是怎么个情况啊 ???
回复

使用道具 举报

29

主题

514

回帖

606

积分

金牌会员

积分
606
QQ
发表于 2018-11-13 09:01:16 | 显示全部楼层
楼上的同学,标准的ASCII有这两个符号,你当前是否用了自定义的字库,恰好没有这两个需要使用的符号?!
ASCII有英文感叹号,双引号.png
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2021-5-27 16:11:41 | 显示全部楼层
大佬,最新在学习使用STM32f429+FreeRTOS +EMWIN,创建EDIT BUTTON 时,遇到稀奇的问题,希望大神给予解惑,万分感谢!!!详细描述间附件。

readme.c

12.62 KB, 下载次数: 3

详细描述内容

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107439
QQ
发表于 2021-5-27 19:09:22 | 显示全部楼层
asus0725 发表于 2021-5-27 16:11
大佬,最新在学习使用STM32f429+FreeRTOS +EMWIN,创建EDIT BUTTON 时,遇到稀奇的问题,希望大神给予解惑 ...

自定义回调去掉试试

                        hItem = WM_GetDialogItem(pMsg->hWin, ID_EDIT_0);
                       
                        if (!_pEditCallback)
                        {
                                _pEditCallback = WM_SetCallback(hItem, _cbEdit);
                        }
                        else
                        {
                                WM_SetCallback(hItem, _cbEdit);   
                        }
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2021-5-31 09:40:39 | 显示全部楼层
eric2013 发表于 2021-5-27 19:09
自定义回调去掉试试

                        hItem = WM_GetDialogItem(pMsg->hWin, ID_EDIT_0);

去掉自定义回调函数,还是不行,假若BUTTON0-button6 全部设置BUTTON_SetFocusable(hItem,0); 窗体不能正常显示;
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-31 19:37 , Processed in 0.338741 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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