首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ucgui 中有关消息处理机制的问题(4)

ucgui 中有关消息处理机制的问题(4)

void MainTask(void) {
GUI_Init();
WM_SetDesktopColor(GUI_RED);
WM_SetCreateFlags(WM_CF_MEMDEV);
GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate),&_cbCallback, 0, 0, 0);
/ while (_cb) {
while (checkHasDialog()) {
if (!GUI_Exec())
GUI_X_ExecIdle();
}
}
在上面的流程说明中,认识到是有必要将窗口消息LOOP放到创建对话框这外的,因为我们是要创建多个独立窗体,那么LOOP当中要分发消息的对象也就是多个窗体,而不是其中的一个,所以要从创建对话框函数中拿出,由用户来写,如同WIN下面一样。
2、在第三节中第2点还说到,要分别调用各个独立窗体的窗口消息函数,必须注意消息的分发,下面我们看一下具体如何分发:
static void _cbDialog(WM_MESSAGE* pMsg)
{
char buf[100];


int i = 0;
WM_LOCK();
for(i = 0; i < MAX_DIALOG; i ){
if(_cb[i]._cb != (WM_CALLBACK*)0){
if (WM__IsWindow(pMsg->hWin))
{
if(pMsg->hWin == _cb[i].hwin || _cb[i].hclient ==pMsg->hWin)
{
sprintf(buf, "has call the i = %d hwin = %d, msgid = %d _cb[i].hwin= %d _cb[i].hclient = %d \n", i, pMsg->hWin,pMsg->MsgId, _cb[i].hwin, _cb[i].hclient);
(*(_cb[i]._cb))(pMsg);
}else
{
sprintf(buf, "not call the i = %d hwin = %d, msgid = %d _cb[i].hwin= %d _cb[i].hclient = %d \n", i, pMsg->hWin,pMsg->MsgId, _cb[i].hwin, _cb[i].hclient);
}
SIM_Log(buf);
}
}

}
WM_UNLOCK();
}
_cbDialog是在对话框的FRAMEWIN__cbClient中调用的,如下形式:
if (cb) {
pMsg->hWin = hParent;
(*cb)(pMsg);
}
每个独立对话框窗体均是这样,通过其FRAMEWIN来调用用户指定的窗口消息处理函数,在分发消息时,其实只须要根据消息中的窗体句柄来分发,因为我们对于每个独立窗体,均记载了它的窗体句柄及客户句柄。所有创建的独立窗体的消息均是在_cbDialog中顺序进行处理的,如果任何一个窗体的消息处理函数有问题,那么就会导致知所有窗体均没有反应。

3、第三节中所说的第3点,独立窗体退出的处理:
void GUI_EndDialog(WM_HWIN hWin, int r) {
/ _cb = NULL;
int i = 0;
char buf[255];
if (!hWin)
return;
WM_LOCK();
if (WM__IsWindow(hWin))
{
for(i = 0; i < MAX_DIALOG; i ){
if(hWin == _cb[i].hwin || _cb[i].hclient == hWin){
_cb[i]._cb = NULL;
_cb[i].hwin = 0;
_cb[i].hclient = 0;
sprintf(buf, "not call the i = %d hWin = %d, _cb[i].hwin = %d_cb[i].hclient = %d \n", i, hWin, _cb[i].hwin,_cb[i].hclient);
SIM_Log(buf);
}
}

}
WM_UNLOCK();
_r = r;
WM_DeleteWindow(hWin);
}
同样也是根据窗口句柄来找到要清除的独立窗体。
4、关于MOUSE点击消息处理的WM_HandlePID()函数
这个函数是专门负责处理MOUSE消息的,即WM_TOUCH消息,当你点击或是在触摸屏上点击上,产生此消息;它当中有两个变量,一个静态的旧消息变量,一个是局部新消息变量,每次均从MOUSE的接口(GUI_PID_GetState())中取新的,每次处理一次最新消息就将最新消息更新到旧消息变量上,下一次处理消息时会比较新旧消息,以避免对相同消息的处理。
说明上面的问题,我们是为了说明这样一个问题,如果我们没有将窗口消息LOOP放到GUI_ExecDialogBox函数之外,那么存在一个问题就是在点击OK一次后会重复创建N多的消息框,原因其实是相同的消息进行了重复处理,不是每处理完一次消息就更新了旧消息吗?为什么还会重复处理?这里面根本的问题就是旧消息还未更新,是因为在一创建消息框后,每一个消息框都进行自己的消息LOOP,而将上面一次的消息LOOP挂起来了,那么一直要等到结束返回到上一次消息LOOP,才会更新旧消息。如果将消息LOOP放出GUI_ExecDialogBox之处,即MainTask当中,即不存在此问题,如果硬是不把消息LOOP放出来,也可以在WM_SendMessage之前就更新旧消息,这样也可以避免由于旧消息未更新而重复处理同一消息。
继承事业,薪火相传
返回列表