硬汉嵌入式论坛

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

[emWin] 求助贴,坑爹的emwin

[复制链接]

6

主题

32

回帖

6

积分

新手上路

积分
6
发表于 2015-1-8 23:32:07 | 显示全部楼层 |阅读模式
首先我们公司的产品采用的是 emwin 522

首先大吐槽:
1.窗口之间传递参数,用的是蹩脚的 XXX_setdata,难道不觉得,为什么不直接在 sendmessage 里面穿俩参数,和 win 一样呢

2.接下来是最最最最最最吐槽的,我在最开始创建一个 desktop,后面创建的窗体全部是 desktop 的子窗体,坑爹的,竟然我模态创建子窗体之后,父窗体竟然还能响应消息,坑爹啊,没见过这么垃圾的UI框架
有这么垃圾的UI么,最后我不得不用create出来,然后 exec show出来。

3.最最最最最最最最最坑爹的来了,当我要切换窗体的时候,因为我们是触摸的窗体,我开的一个触摸任务,测试显示,当多次点击触摸,或者稍微快速滑动的时候,就不断的 halt ()
最后我trace 出来,最后找到以下代码的问题

static
void    _cbTable (const WM_MESSAGE *pmsg)
{
      switch (pmsg->msgId) {
                   case  NOTIFY_PARENT:
                                     switch (Ncode) {
                                     case   CLICKED:
                                               /* 将控件颜色反显 */
                                                break;
                                    
                                     case  RELEASED:
                                     case  MOVED_OUT:
                                    
                                     .......................

                                     /* 创建子窗体 */
                                     create_sub_window (pMsg->hwnd) ;
                                     break;                        
                                      }
      }
}
我的场景是这样的 ,A B C D 四个 BUTTON 控件是父窗体desk 的widget,我将 BUTTON 重绘了,按下 A 则创建一个子窗体,销毁子窗体又回来了A B C D 窗体,就是这么一个简单的需求。
最后发现当我先按住一个窗体,再快速的滑动窗体到另外一个窗体的时候,进入了 创建模态create_sub_window,而且显示了,但竟然父窗口desk还收到一大串的 clicked  消息,emwin 你坑我坑的好惨啊。。。。。。
最后我用了一个 clicked_id ,来判断最后点击的id,问题又来了,死机的问题被我这么解决的

case  CLICKED :
          if (clickedid < 0)  
                    return ;
           clickedid = Id ;    /* 记录最后按下的 clickedid */
          break;

case   RELEASED:
case  MOVED_OUT:
          if (clickedid != Id)
               return;              /* 如果最后按下的id 和弹起的 id不一样,那就直接不要做事了 */
          .............
           break;

等等等等,可是问题又来了,我依旧是快速的在 A B C D 之间滑动,是不会再次创建窗体了,但是反显的窗体竟然还在
场景是这样
A   B   C  D ,窗体,我按住A 窗体,快速的滑到C,C 弹起来,C就创建窗体,可是窗体显示后,一大堆的 A 窗体 clicked 消息发过来了,我艹,最后A窗体一直保持着 clicked 状态,最后我按 D 窗体
这样 A 窗体就变成了 moved_out 了,我艹,A 窗体响应了,然后D 保持着按下的状态,最后,艹艹艹艹。。。。。。。。。。

emwin 的设计者,你大爷的,你坑我坑的好惨啊。。。。。。。。。。
求助啊
回复

使用道具 举报

356

主题

2180

回帖

3253

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3253
发表于 2015-1-9 13:59:42 | 显示全部楼层
相对于微软的窗口管理,emwin做了很多简化。 我也是一边用,一边摸索。

这些简化和修改的地方,一般的文档也讲不清楚,估计得花钱买一套,寻求原厂支持了。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2015-1-9 23:29:55 | 显示全部楼层
emWin的模态的确不好用,楼主要是有时间的话,可以在emWin官方论坛问下这个问题,官方论坛地址:http://forum.segger.com/index.ph ... be4ada0bfaef8d92f6a

另:如果用的是button创建的对话框,打开对话框后将其它button禁能掉。这个应该能够防止误触碰。
回复

使用道具 举报

6

主题

32

回帖

6

积分

新手上路

积分
6
 楼主| 发表于 2015-1-14 14:47:01 | 显示全部楼层
官方版 V522  的demo ,skinning 里面,点击select vehicle ,之后还可以点击父窗口,后面我看了代码,原版的代码是这样的,

/*********************************************************************
*
*       _cbDialogOrder
*/
static void _cbDialogOrder(WM_MESSAGE * pMsg) {
  //............
..................
  case WM_NOTIFY_PARENT:
    if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
      int Id = WM_GetId(pMsg->hWinSrc);
      switch (Id) {
      case GUI_ID_BUTTON0:
        hDlg = GUI_CreateDialogBox(_aDialogSelect, GUI_COUNTOF(_aDialogSelect), _cbDialogSelect, pMsg->hWin/*WM_HBKWIN*/, xOff, yOff);
                //WM_HideWin (pMsg->hWin);        /* hide parent */
        //        WM_DisableWindow (pMsg->hWin);
        FRAMEWIN_SetSkin(hDlg, _DrawSkin);
        WM_ClrHasTrans(hDlg);
        GUI_MEMDEV_MoveInWindow(hDlg, 80 + xOff, 190 + yOff, 180, 500);
        while ((_ReadyDialogOrder == 0) && (GUIDEMO_CheckCancel() == 0)) {
          GUI_Delay(100);
          if (_ReadyDialogSelect == 1) {
            //
            // Make sure the dialog is not deleted.
            //
            if (WM_IsWindow(hWin)) {
              _ReadyDialogSelect++;
              hItem = WM_GetDialogItem(hWin, GUI_ID_EDIT0);
              EDIT_SetText(hItem, _acVehicle);
            }
          }
        }
        if (WM_IsWindow(hDlg)) {
          WM_DeleteWindow(hDlg);
        }
        break;
      case GUI_ID_OK:
        hProg = GUI_CreateDialogBox(_aDialogProgress, GUI_COUNTOF(_aDialogProgress), _cbDialogProgress, WM_HBKWIN, xOff, yOff);
        //
        // Make modal to avoid several creations of the progress window.
        //
        WM_MakeModal(hProg);
        FRAMEWIN_SetSkin(hProg, _DrawSkin);
        GUI_MEMDEV_FadeInWindow(hProg, 500);
        WM_InvalidateWindow(hWin);
        GUI_ExecCreatedDialog(hProg);
        //lint -fallthrough // End dialog in both cases
      case GUI_ID_CANCEL:
        //
        // Make sure the dialog is not deleted.
        //
        if (WM_IsWindow(hWin)) {
          GUI_MEMDEV_FadeOutWindow(hWin, 500);
          GUI_EndDialog(hWin, 0);
        }
        _ReadyDialogOrder = 1;
        break;
      }
    }
    break;
  default:
    WM_DefaultProc(pMsg);
  }
}

是设置的 WM_HBKWIN,这样按道理是可以点,因为没有父窗口的概念,但是我改成pMsg->hwin,这样就设置父窗口为创建的父窗口,结果很不幸,依旧可以点父窗口,最后我WM_DisableWindow (pMsg->hwin) ; 结果很残酷,还是可以按,最后我用了一个一劳永逸的办法, WM_Hide (pMsg->hwin); ,我高兴的将这个用法用到我的产品上去,最后是不会吴触发,但是很不辛,当我快速的在 A B C  D 四个窗口之间滑动的时候,A 滑到 C,
C 响应 RELEASED 消息分支,最后在响应之前将pMsg->hwin hid掉,然后我将创建的窗体再销毁,回到  A B C D,这个时候 A 的一大堆的 CLICKED 消息发过来了。我试过在跑 emwin demo的工程里面,所有的在button里按下弹起响应的模式都会有这个问题,结果无一例外的memory leak ,要是内存开的小,直接就 alloc failed ,这个是个严重的BUG。(所有 emwin 这种模式处理的,都会莫名其妙的内存爆满,包括我在内)

PS: 今天和群里一群SB争论RGB和BGR 设置的问题,最搞笑的是,我说明了我用的是emwin lib 自带的那个驱动ili9341,他竟然还追着我问LCD驱动写错了,我去,还自称是看过man手册,拜托,发言之前好好验证一下好不好,丢人不? 还有人说自带驱动在emwin内部不会发控制命令,这不扯淡么,人家为什么能集成,就是因为 比如ILI9335 ILI9341 ILIXXX   这类控制器都是有公用的命令字,还说emwin 只调用 读写点函数,拜托大哥,不带这么丢人的,连基本常识都不懂,还自以为是呢,仔细想想看,要是我要设置一个点的颜色,我从哪儿调?扯J8淡。。。
回复

使用道具 举报

6

主题

32

回帖

6

积分

新手上路

积分
6
 楼主| 发表于 2015-1-14 14:59:43 | 显示全部楼层
哇靠,太浮躁了,看到了emwin 官方说明了,有 skinning_nestedmodal.c 这个文件,浮躁浮躁了。。。。。。。。。,手册还是要看清楚看清楚,反省啊。。。。。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2015-1-14 15:38:19 | 显示全部楼层

回 true_casey 的帖子

true_casey:哇靠,太浮躁了,看到了emwin 官方说明了,有 skinning_nestedmodal.c 这个文件,浮躁浮躁了。。。。。。。。。,手册还是要看清楚看清楚,反省啊。。。。。 (2015-01-14 14:59) 
[s:149][s:149]
回复

使用道具 举报

6

主题

32

回帖

6

积分

新手上路

积分
6
 楼主| 发表于 2015-1-14 15:50:37 | 显示全部楼层
那个点击父窗口的问题解决了,但是我前面提的问题还在 ,A B C D ,A 快速的滑到C,C 弹起,创建窗体后M,然后M返回,M销毁,回到  A B C D ,此时A的clicked 消息被一直发过来了,唉,空欢喜一场。。。。
回复

使用道具 举报

6

主题

32

回帖

6

积分

新手上路

积分
6
 楼主| 发表于 2015-1-14 15:56:18 | 显示全部楼层
有没有像 win 一样的,可以清楚消息队列消息的那种API啊,比如可以像 win的非模态对话框中的,不断  while (getmessage (&msg,0,0,0))  ,然后我发一个 USER_CMD , 从这个命令之后,接到一个 msg,就丢掉这种,就是可以清楚掉消息的
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2015-1-14 21:40:22 | 显示全部楼层

回 true_casey 的帖子

true_casey:有没有像 win 一样的,可以清楚消息队列消息的那种API啊,比如可以像 win的非模态对话框中的,不断  while (getmessage (&msg,0,0,0))  ,然后我发一个 USER_CMD , 从这个命令之后,接到一个 msg,就丢掉这种,就是可以清楚掉消息的 (2015-01-14 15:56) 
刚才查了一下手册,emWin应该没有这样的功能。
回复

使用道具 举报

6

主题

32

回帖

6

积分

新手上路

积分
6
 楼主| 发表于 2015-1-15 14:02:07 | 显示全部楼层
被我神奇的搞定了,emwin确实是太弱了,不过也不能要求太多,那个解决的方法实在是很蹩脚
使用的方法是检测物理的触摸,这是偏门方法

case  clicked :
if (GUI_PID_IsPressed ()) {
执行正常的 pressed 状态
} else {
  //强制store 为unpressed 状态
}


case released:

if (clicked) {
//执行弹起消息
} else {
   // bypass
}

这样在任何的测试都是OK的,不会死机,不会多个-release ,不会多个反显

emwin 即使是 使用 WM_MakeModal () 这样的函数, blocking其他显示的窗体,也是没有避免这样的BUG
我觉得可能emwin 这里确实是值得商榷的,应该要这样,当快速的按键来之后,创建modal 子窗体,那么一切一切的父窗口消息全部将会拒绝掉,我出现那个的BUG,就是因为上一次click的消息被缓存,下一次show 之后
被无情的发过来了,

emwin 实在是需要做很多严格的测试,BUG实在太多了
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2015-1-16 21:17:36 | 显示全部楼层

回 true_casey 的帖子

true_casey:被我神奇的搞定了,emwin确实是太弱了,不过也不能要求太多,那个解决的方法实在是很蹩脚
使用的方法是检测物理的触摸,这是偏门方法

case  clicked :
if (GUI_PID_IsPressed ()) {
....... (2015-01-15 14:02) 
谢谢告知,后面我也试试。[s:151]
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-14 04:16 , Processed in 0.043698 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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