最近在用ucGUI写一个终端的界面,碰到多个对话框之间相互调用,会弹出提示"Max. message nesting exceeded, Message skipped."的错误。分析原因后,发现是由于在对话框的回调函数中调用GUI_ExecDialogBox()这个函数创建对话框的缘故,因为GUI_ExecDialogBox()函数是创建对话框并且马上执行对话框的回调函数,一直到该对话框的动作处理完成之后才返回,所以在对话框的回调函数中调用这个函数就相当调用了一个同步函数。如果在两个对话框的回调函数中利用这个函数相互调创建对方的话,就会导致无限的同步函数嵌套调用,就会进入一个死循环,回调函数就永远无法返回。但是在做界面开发的时候,很容易碰到对话框之间相互创建调用的问题。要解决这个问题,最初我想了一个比较笨的方法,利用一个while死循环来执行所有的对话框创建,对话框之间的切换,利用标志位来设置。大致的流程如下: {
......
int Key = ((WM_KEY_INFO*)(pMsg->Data.p))->Key; switch(Key){
case WM_ENTER:
GUI_EndDialog(); isDlg2 = 1;break; } }
break; ...... }
}
{ {
......
case WM_KEY: int Key = ((WM_KEY_INFO*)(pMsg->Data.p))->Key; switch(Key) { case WM_ENTER: GUI_EndDialog();
isDlg1
= 1; break; }
}
break;
...... } }
int main()
isDlg1 = 0;
isDlg2 = 0;
{ {
...... int Key = ((WM_KEY_INFO*)(pMsg->Data.p))->Key;
switch(Key) {
case
WM_ENTER:
GUI_EndDialog(); hDlg2 =GUI_CreateDialogBox(dialog2);break; }
} break; ...... } }
_cbDialog2(WM_MESSAGE
*pMsg)
{ {
...... int Key = ((WM_KEY_INFO*)(pMsg->Data.p))->Key; switch(Key) { case WM_ENTER:
GUI_EndDialog(); break; } } break; ...... } }
开始我也想不通,后来跟踪GUI_Exec()的代码,发现它掉用了_DrawNext()这个函数, 个人推断此函数会更新画所有以创建过的窗口,没有仔细分析,想了解跟深入的可以自己阅读源代码。 因此,可以创建无数个非模态对话框,然后用这个while(1){GUI_Exec();}来显示这些创建的对话框。 这么一来,对话框之间的切换就不会有嵌套调用的问题了,因为GUI_CreateDialogBox()创建完成之后会马上返回, 对话框回调函数的执行由GUI_Exec()来进行。对于使用ucGUI还需要注意的一点就是消息的发送, ucGUI中所有窗口之间消息的发送都要经过WM_SendMessage(),而这个函数发送的消息全部都是同步消息, 在ucGUI中没有MFC中的PostMessage()消息函数。GUI_EndDialog()函数在对对话框进行关闭的时候, 也是通过对对话框发送同步消息来实现关闭的。 本人使用的ucGUI版本是网上流传的3.90版和3.98版,2个版本都验证过,以上方法可行。 以上这些内容是对近一个月来使用ucGUI碰到问题的分析和总结,由于刚接触ucGUI没多久, 难免有错误,错误之处,还望高手指点迷津,欢迎拍砖。 |
|