979 lines
21 KiB
C
979 lines
21 KiB
C
#include "mywin_inc.h"
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//存储触摸信息,0,成功,非0,失败
|
||
int WIN_StorTouchStruct (WIN_TouchStruct *t)
|
||
{
|
||
static int press=0;
|
||
|
||
//队列还没有初始化
|
||
if (WIN_GetWinStruct()->touchQueue.data==0) return -1;
|
||
if (WIN_GetWinStruct()->keyShield==1) return -2;
|
||
//存储最后一次松开后的触屏数据
|
||
if ((press!=t->pressNum)||t->pressNum)
|
||
{
|
||
press=t->pressNum;
|
||
if (QUEUE_In (&WIN_GetWinStruct()->touchQueue,t)==1)
|
||
return -3;
|
||
else
|
||
return 0;
|
||
}
|
||
return -4;
|
||
}
|
||
|
||
|
||
//存储按键信息,返回0,成功,非0,失败
|
||
int WIN_StorKeyStruct (WIN_KeyStruct *k)
|
||
{
|
||
static int press=0;
|
||
//队列还没有初始化
|
||
if (WIN_GetWinStruct()->keyQueue.data==0) return -1;
|
||
if (WIN_GetWinStruct()->keyShield==1) return -2;
|
||
//存储最后一次按键松开的消息
|
||
if ((press!=k->state)||k->state)
|
||
{
|
||
press=k->state;
|
||
if (QUEUE_In (&WIN_GetWinStruct()->keyQueue,k)==1)
|
||
return -1;
|
||
else
|
||
return 0;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|
||
//清空按键队列
|
||
void WIN_ClearKeyQueue (void)
|
||
{
|
||
WIN_KeyStruct k={0};
|
||
while (QUEUE_Out (&WIN_GetWinStruct()->keyQueue,&k))
|
||
{
|
||
}
|
||
}
|
||
|
||
|
||
//清空触摸队列
|
||
void WIN_ClearTouchQueue (void)
|
||
{
|
||
WIN_KeyStruct k={0};
|
||
while (QUEUE_Out (&WIN_GetWinStruct()->touchQueue,&k))
|
||
{
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//屏蔽按键和触屏
|
||
void WIN_KeyShieldOn (void)
|
||
{
|
||
WIN_GetWinStruct()->keyShield=1;
|
||
}
|
||
|
||
//不屏蔽按键和触屏
|
||
void WIN_KeyShieldOff (void)
|
||
{
|
||
WIN_GetWinStruct()->keyShield=0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//默认的消息处理函数
|
||
void WIN_DefaultMsgLoop (WIN_WindowStruct *win,WIN_MsgStruct *msg)
|
||
{
|
||
switch (msg->msg)
|
||
{
|
||
case WIN_MSG_PAINT:
|
||
WIN_DefaultPaint(win);
|
||
break;
|
||
case WIN_MSG_INIT:
|
||
break;
|
||
case WIN_MSG_KEY:
|
||
// if (win!= WIN_GetBaseWindow())
|
||
// win->deleteWindow(win);
|
||
break;
|
||
case WIN_MSG_TOUCH:
|
||
// if (win != WIN_GetBaseWindow())
|
||
// win->deleteWindow(win);
|
||
break;
|
||
case WIN_MSG_CHID:
|
||
break;
|
||
case WIN_MSG_DELETE:
|
||
break;
|
||
case WIN_MSG_MOVE:
|
||
break;
|
||
case WIN_MSG_EXTMSG:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
//修改窗口的消息循环函数
|
||
void *WIN_SetMsgCallBack (WIN_WindowStruct *win, void (*msgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))
|
||
{
|
||
void *ret=win->msgLoop;
|
||
win->msgLoop=msgLoop;
|
||
return ret;
|
||
}
|
||
|
||
|
||
//设置窗口消息循环
|
||
void *WIN_SetMsgLoopCallBack (WIN_WindowStruct *win,void (*msgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))
|
||
{
|
||
void *ret=0;
|
||
if (win)
|
||
{
|
||
ret=win->msgLoop;
|
||
win->msgLoop=msgLoop;
|
||
}
|
||
else
|
||
{
|
||
ret=WIN_GetBaseWindow()->msgLoop;
|
||
WIN_GetBaseWindow()->msgLoop=msgLoop;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//存储外部消息到活动窗口返回0,成功,非0,失败
|
||
int WIN_StorExtMsg (void *msgData,int size)
|
||
{
|
||
int ret=-1;
|
||
WIN_MsgStruct msg={0};
|
||
//有任务在执行
|
||
if (WIN_GetWinStruct()->BlockWin[0])
|
||
{
|
||
msg.msg=WIN_MSG_EXTMSG;
|
||
msg.data.p=mymalloc (size);
|
||
mymemcpy (msg.data.p,msgData,size);
|
||
ret=WIN_SendMsg (0,WIN_GetWinStruct()->BlockWin[0],&msg);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
//发送外部信息到指定窗口
|
||
int WIN_WinStorExtMsg (WIN_WindowStruct *win,void *msgData,int size)
|
||
{
|
||
int ret=-1;
|
||
WIN_MsgStruct msg={0};
|
||
//有任务在执行
|
||
if (win)
|
||
{
|
||
msg.msg=WIN_MSG_EXTMSG;
|
||
msg.data.p=mymalloc (size);
|
||
mymemcpy (msg.data.p,msgData,size);
|
||
ret=WIN_SendMsg (0,win,&msg);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//发送消息到指定窗口
|
||
int WIN_SendMsg (WIN_WindowStruct *win,WIN_WindowStruct *dscWin,WIN_MsgStruct *msg)
|
||
{
|
||
int ret=-1;
|
||
if (win) msg->srcWin=win;
|
||
if (dscWin) //目标窗口为0,不发送消息
|
||
{
|
||
//不能向已销毁的窗口发消息
|
||
if (dscWin->memFree) ret=-1;
|
||
else ret=QUEUE_In (&dscWin->winMsgQueue,msg);
|
||
}
|
||
//发送失败
|
||
if (ret!=0)
|
||
{
|
||
//释放这些消息在构建时申请的内存
|
||
switch (msg->msg)
|
||
{
|
||
case WIN_MSG_KEY:
|
||
case WIN_MSG_TOUCH:
|
||
case WIN_MSG_EXTMSG:
|
||
case WIN_MSG_MOVE:
|
||
myfree(msg->data.p);
|
||
break;
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//发送消息到父窗口
|
||
int WIN_SendMsgToPrent (WIN_WindowStruct *win,u32 type,u32 data)
|
||
{
|
||
WIN_MsgStruct msg1={0};
|
||
msg1.msg=WIN_MSG_CHID;
|
||
msg1.data.v=type;
|
||
msg1.data2.v=data;
|
||
return WIN_SendMsg (win,win->baseWin,&msg1);
|
||
}
|
||
|
||
|
||
|
||
|
||
//清空消息队列
|
||
void WIN_ClearMsgQueue (WIN_WindowStruct *win)
|
||
{
|
||
WIN_MsgStruct msg={0};
|
||
while (QUEUE_Out (&win->winMsgQueue,&msg))
|
||
{
|
||
switch (msg.msg)
|
||
{
|
||
//释放构建消息时申请的内存
|
||
case WIN_MSG_KEY:
|
||
case WIN_MSG_TOUCH:
|
||
case WIN_MSG_EXTMSG:
|
||
case WIN_MSG_MOVE:
|
||
myfree(msg.data.p);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//查找指定消息
|
||
WIN_MsgStruct *WIN_CheckMsg (WIN_WindowStruct *win,u32 msgType)
|
||
{
|
||
WIN_MsgStruct *msg=0;
|
||
QUEUE_CheckStart (&win->winMsgQueue);
|
||
while (msg=QUEUE_Check (&win->winMsgQueue),msg)
|
||
{
|
||
if (msg->msg==msgType)
|
||
{
|
||
return msg;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//发送按键消息,同时发送给父窗口
|
||
void WIN_SendKeyMsg (WIN_WindowStruct *win,WIN_KeyStruct *k)
|
||
{
|
||
WIN_MsgStruct msg={0};
|
||
if(win->keyShield==0)
|
||
{
|
||
msg.msg=WIN_MSG_KEY;
|
||
//要保证数据一直有效,消息读取后要free这段内存,否侧内存溢出
|
||
msg.data.p=mymalloc(sizeof (WIN_KeyStruct));
|
||
mymemcpy (msg.data.p,k,sizeof (WIN_KeyStruct));
|
||
WIN_SendMsg (0,win,&msg);
|
||
}
|
||
|
||
if ((win->baseWin)&&(win->baseWin!=WIN_GetBaseWindow())&&(win->intercept==0))
|
||
{
|
||
WIN_SendKeyMsg (win->baseWin,k);
|
||
}
|
||
else if (win->baseWin)
|
||
{
|
||
//所有按键消息都要发送到基础窗口
|
||
if (WIN_GetWinStruct()->BlockWinNum==0)
|
||
WIN_SendKeyMsg (WIN_GetBaseWindow(),k);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//发送触摸消息,同时发送给窗口所在的父窗口
|
||
void WIN_SendTouchMsg (WIN_WindowStruct *win,int lcd_x,int lcd_y)
|
||
{
|
||
WIN_TouchStruct t={0};
|
||
WIN_MsgStruct msg={0};
|
||
if(win->keyShield==0)
|
||
{
|
||
msg.msg=WIN_MSG_TOUCH;
|
||
//要保证数据一直有效,消息读取后要free这段内存,否侧内存溢出
|
||
msg.data.p=mymalloc(sizeof (WIN_TouchStruct));
|
||
int x,y,xs,ys;
|
||
WIN_GetWinPosOnLcd(win,&x,&y,&xs,&ys);//把屏幕上的绝对坐标转化为窗口的相对坐标
|
||
t.x[0]=lcd_x-x;t.y[0]=lcd_y-y;
|
||
mymemcpy (msg.data.p,&t,sizeof (WIN_TouchStruct));
|
||
WIN_SendMsg (0,win,&msg);
|
||
}
|
||
|
||
if ((win->baseWin)&&(win->intercept==0))
|
||
{
|
||
WIN_SendTouchMsg (win->baseWin,lcd_x,lcd_y);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
//发送滑动信息,同时发送给父窗口
|
||
void WIN_SendTouchMove (WIN_WindowStruct *win,int move_x,int move_y)
|
||
{
|
||
WIN_MoveStruct m={0};
|
||
WIN_MsgStruct msg={0};
|
||
|
||
if(win->keyShield==0)
|
||
{
|
||
msg.msg=WIN_MSG_MOVE;
|
||
msg.data.p=mymalloc (sizeof (WIN_MoveStruct));
|
||
m.moveType=MOVE_DATA_MOVED;
|
||
m.x_move=move_x;
|
||
m.y_move=move_y;
|
||
mymemcpy (msg.data.p,&m,sizeof (WIN_MoveStruct));
|
||
WIN_SendMsg (0,win,&msg);
|
||
}
|
||
|
||
if ((win->baseWin)&&(win->intercept==0))
|
||
{
|
||
WIN_SendTouchMove (win->baseWin,move_x,move_y);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//广播触屏消息
|
||
int WIN_TouchMsgBroad (WIN_WindowStruct *base)
|
||
{
|
||
int have_msg=0;//返回值
|
||
WIN_TouchStruct t={0};
|
||
WIN_KeyStruct k={0};
|
||
WIN_MoveStruct m={0};
|
||
WIN_MsgStruct msg={0};
|
||
WIN_MsgBroadStruct *broad=&WIN_GetWinStruct()->msgBroad;
|
||
while (QUEUE_Out (&WIN_GetWinStruct()->touchQueue,&t)==1)
|
||
{
|
||
have_msg=1;
|
||
//有触屏数据
|
||
broad->win=WIN_FindTopWinByPos (base,t.x[0],t.y[0]);
|
||
// while(broad->win&&broad->win->keyShield) broad->win=broad->win->baseWin;
|
||
if (broad->win)
|
||
{
|
||
//移动检测在两次都是按下的情况下才成立
|
||
if (broad->t_old.pressNum&&t.pressNum)
|
||
{
|
||
if (broad->win_old!=broad->win)
|
||
{
|
||
//上一个窗口不是现在的窗口
|
||
//上一个窗口移出,现在的窗口移入
|
||
if (broad->win_old)
|
||
{
|
||
int x,y,xs,ys;
|
||
msg.msg=WIN_MSG_MOVE;
|
||
msg.data.p=mymalloc (sizeof (WIN_MoveStruct));
|
||
m.moveType=MOVE_DATA_MOVEOUT;
|
||
WIN_GetWinPosOnLcd(broad->win_old,&x,&y,&xs,&ys);//把屏幕上的绝对坐标转化为窗口的相对坐标
|
||
m.x_move=t.x[0]-x;
|
||
m.y_move=t.y[0]-y;
|
||
mymemcpy (msg.data.p,&m,sizeof (WIN_MoveStruct));
|
||
WIN_SendMsg (0,broad->win_old,&msg);
|
||
|
||
msg.msg=WIN_MSG_MOVE;
|
||
msg.data.p=mymalloc (sizeof (WIN_MoveStruct));
|
||
m.moveType=MOVE_DATA_MOVEIN;
|
||
WIN_GetWinPosOnLcd(broad->win,&x,&y,&xs,&ys);//把屏幕上的绝对坐标转化为窗口的相对坐标
|
||
m.x_move=t.x[0]-x;
|
||
m.y_move=t.y[0]-y;
|
||
mymemcpy (msg.data.p,&m,sizeof (WIN_MoveStruct));
|
||
WIN_SendMsg (0,broad->win,&msg);
|
||
broad->Touch_long=WIN_LONGTOUCH_CHECK;//已经移动了,不再检测长按
|
||
}
|
||
else
|
||
{
|
||
//松开屏幕后的第一次点击
|
||
}
|
||
broad->win_old=broad->win;
|
||
}//if (win_old!=win)
|
||
WIN_WindowStruct *win_move=0;
|
||
if (win_move=WIN_FindPrent(broad->win_old,broad->win),win_move!=0)
|
||
{
|
||
//两次触摸值没超过抖动范围
|
||
if (POS_RoundPix(1,broad->t_old.x[0],broad->t_old.y[0],t.x[0],t.y[0])!=0)
|
||
{
|
||
//在同一个窗口内移动
|
||
WIN_SendTouchMove (win_move,t.x[0]-broad->t_old.x[0],t.y[0]-broad->t_old.y[0]);
|
||
broad->Touch_long=WIN_LONGTOUCH_CHECK+10;//已经移动了,不再检测长按
|
||
}
|
||
else
|
||
{
|
||
//多次触摸都没有移动,记录长按
|
||
if (broad->Touch_long<WIN_LONGTOUCH_CHECK)
|
||
{
|
||
broad->Touch_long++;
|
||
if (broad->Touch_long>=WIN_LONGTOUCH_CHECK)
|
||
{
|
||
//发送一次长按消息
|
||
msg.msg=WIN_MSG_MOVE;
|
||
msg.data.p=mymalloc (sizeof (WIN_MoveStruct));
|
||
m.moveType=MOVE_DATA_LONG;
|
||
int x,y,xs,ys;
|
||
WIN_GetWinPosOnLcd(broad->win,&x,&y,&xs,&ys);//把屏幕上的绝对坐标转化为窗口的相对坐标
|
||
m.x_move=t.x[0]-x;
|
||
m.y_move=t.y[0]-y;
|
||
mymemcpy (msg.data.p,&m,sizeof (WIN_MoveStruct));
|
||
WIN_SendMsg (0,broad->win_old,&msg);
|
||
}
|
||
}
|
||
}
|
||
}//if (win_move=WIN_FindPrent(win_old,win),win_move!=0)
|
||
}//if (t_old.pressNum&&t.pressNum)
|
||
else
|
||
{
|
||
//触摸没有移动并且没有触发长按
|
||
if (broad->Touch_long&&(broad->Touch_long<WIN_LONGTOUCH_CHECK))
|
||
{
|
||
//发送短按消息
|
||
msg.msg=WIN_MSG_MOVE;
|
||
msg.data.p=mymalloc (sizeof (WIN_MoveStruct));
|
||
m.moveType=MOVE_DATA_SHORT;
|
||
int x,y,xs,ys;
|
||
WIN_GetWinPosOnLcd(broad->win,&x,&y,&xs,&ys);//把屏幕上的绝对坐标转化为窗口的相对坐标
|
||
m.x_move=t.x[0]-x;
|
||
m.y_move=t.y[0]-y;
|
||
mymemcpy (msg.data.p,&m,sizeof (WIN_MoveStruct));
|
||
WIN_SendMsg (0,broad->win_old,&msg);
|
||
}
|
||
//屏幕松开了,长按检测复位
|
||
broad->Touch_long=0;
|
||
//屏幕松开了,窗口间滑动复位
|
||
broad->win_old=0;
|
||
if (t.pressNum==0)
|
||
{
|
||
//屏幕松开了
|
||
msg.msg=WIN_MSG_MOVE;
|
||
msg.data.p=mymalloc (sizeof (WIN_MoveStruct));
|
||
m.moveType=MOVE_DATA_TOUCHOUT;
|
||
int x,y,xs,ys;
|
||
WIN_GetWinPosOnLcd(broad->win,&x,&y,&xs,&ys);//把屏幕上的绝对坐标转化为窗口的相对坐标
|
||
m.x_move=t.x[0]-x;
|
||
m.y_move=t.y[0]-y;
|
||
mymemcpy (msg.data.p,&m,sizeof (WIN_MoveStruct));
|
||
WIN_SendMsg (0,broad->win,&msg);
|
||
}
|
||
else
|
||
{
|
||
//松开屏幕后的第一次点击
|
||
msg.msg=WIN_MSG_MOVE;
|
||
msg.data.p=mymalloc (sizeof (WIN_MoveStruct));
|
||
m.moveType=MOVE_DATA_TOUCHIN;
|
||
int x,y,xs,ys;
|
||
WIN_GetWinPosOnLcd(broad->win,&x,&y,&xs,&ys);//把屏幕上的绝对坐标转化为窗口的相对坐标
|
||
m.x_move=t.x[0]-x;
|
||
m.y_move=t.y[0]-y;
|
||
mymemcpy (msg.data.p,&m,sizeof (WIN_MoveStruct));
|
||
WIN_SendMsg (0,broad->win,&msg);
|
||
}
|
||
}
|
||
broad->t_old.x[0]=t.x[0];broad->t_old.y[0]=t.y[0];
|
||
broad->t_old.pressNum=t.pressNum;
|
||
|
||
//发送触控消息
|
||
WIN_SendTouchMsg (broad->win,t.x[0],t.y[0]);
|
||
}//if (win)
|
||
else
|
||
{
|
||
if (broad->t_old.pressNum==0&&t.pressNum)
|
||
{
|
||
//触摸不在指定窗口内
|
||
msg.msg=WIN_MSG_MOVE;
|
||
msg.data.p=mymalloc (sizeof (WIN_MoveStruct));
|
||
m.moveType=MOVE_DATA_OUTSIDE;
|
||
m.x_move=0;
|
||
m.y_move=0;
|
||
mymemcpy (msg.data.p,&m,sizeof (WIN_MoveStruct));
|
||
WIN_SendMsg (0,base,&msg);
|
||
}
|
||
broad->t_old.x[0]=t.x[0];broad->t_old.y[0]=t.y[0];
|
||
broad->t_old.pressNum=t.pressNum;
|
||
}
|
||
}//while (QUEUE_Out (&g_win_touchQueue,&t)==1)
|
||
|
||
return have_msg;
|
||
}
|
||
|
||
|
||
//广播按键消息
|
||
int WIN_KeyMsgBroad (WIN_WindowStruct *base)
|
||
{
|
||
int have_msg=0;//返回值
|
||
WIN_TouchStruct t={0};
|
||
WIN_KeyStruct k={0};
|
||
WIN_MoveStruct m={0};
|
||
WIN_MsgStruct msg={0};
|
||
WIN_MsgBroadStruct *broad=&WIN_GetWinStruct()->msgBroad;
|
||
while (QUEUE_Out (&WIN_GetWinStruct()->keyQueue,&k)==1)
|
||
{
|
||
have_msg=1;
|
||
WIN_WindowStruct *win_key=0;
|
||
if (win_key =WIN_FindTopWin(base),win_key!=0)
|
||
{
|
||
//按键没有松开过
|
||
if ((broad->k_old.key==k.key)&&k.key)
|
||
{
|
||
//按键是按下的
|
||
if (k.state)
|
||
{
|
||
if (broad->Key_long<WIN_LONGTOUCH_CHECK)
|
||
{
|
||
broad->Key_long++;
|
||
if (broad->Key_long>=WIN_LONGTOUCH_CHECK)
|
||
{
|
||
//触发长按
|
||
k.longPress|=k.key;
|
||
k.shortPress=0;
|
||
k.firstPress=0;
|
||
k.unPress=0;
|
||
WIN_SendKeyMsg (win_key,&k);
|
||
}
|
||
else
|
||
{
|
||
//按键按下中
|
||
k.longPress=0;
|
||
k.shortPress=0;
|
||
k.firstPress=0;
|
||
k.unPress=0;
|
||
WIN_SendKeyMsg (win_key,&k);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//已经触发过长按,按键还没有松开,
|
||
broad->Key_long++;
|
||
if (broad->Key_long%WIN_LONGTOUCH_CHECK==0)
|
||
{
|
||
k.longPressNum=broad->Key_long/WIN_LONGTOUCH_CHECK;
|
||
if (k.longPressNum !=broad->k_old.longPressNum)
|
||
{
|
||
//再次触发长按
|
||
broad->k_old.longPressNum=k.longPressNum;
|
||
k.longPress|=k.key;
|
||
k.shortPress=0;
|
||
k.firstPress=0;
|
||
k.unPress=0;
|
||
WIN_SendKeyMsg (win_key,&k);
|
||
}
|
||
}
|
||
}
|
||
}//if (k.state)
|
||
else
|
||
{
|
||
//按键从按下变为松开,并且没有触发长按
|
||
if (broad->Key_long<WIN_LONGTOUCH_CHECK)
|
||
{
|
||
//短按
|
||
k.shortPress|=k.key;
|
||
k.longPress=0;
|
||
k.firstPress=0;
|
||
k.unPress=0;
|
||
WIN_SendKeyMsg (win_key,&k);
|
||
}
|
||
else
|
||
{
|
||
//松开了按键,并且触发过长按
|
||
//长按触发次数清零
|
||
broad->k_old.longPressNum=0;
|
||
}
|
||
k.unPress=k.key;
|
||
k.firstPress=0;
|
||
k.longPress=0;
|
||
k.shortPress=0;
|
||
WIN_SendKeyMsg (win_key,&k);
|
||
broad->Key_long=0;
|
||
k.key=0;
|
||
}
|
||
}//if ((k_old.key==k.key)&&k.key)
|
||
else if ((broad->k_old.state==0)&&(k.state))
|
||
{
|
||
//按键第一次按下
|
||
broad->Key_long=0;
|
||
k.firstPress=k.key;
|
||
k.longPress=0;
|
||
k.shortPress=0;
|
||
WIN_SendKeyMsg (win_key,&k);
|
||
}
|
||
broad->k_old.key=k.key;
|
||
broad->k_old.state=k.state;
|
||
}//if (win_key =WIN_FindTopWin(win),win_key!=0)
|
||
}
|
||
return have_msg;
|
||
}
|
||
|
||
|
||
|
||
|
||
//广播按键和触屏消息,处理过消息,返回1,否则返回0
|
||
int WIN_MsgBroad (WIN_WindowStruct *base)
|
||
{
|
||
return WIN_KeyMsgBroad(base)|WIN_TouchMsgBroad (base);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//窗口运行
|
||
int WIN_Working (WIN_WindowStruct *win)
|
||
{
|
||
|
||
WIN_MoveStruct *m=0;
|
||
RECT_Struct r={0};
|
||
int run=0; //此项为1,则消息没处理完
|
||
//自己先处理消息
|
||
WIN_MsgStruct msg={0};
|
||
win->msgLoopEnter++;
|
||
WIN_WindowStruct *winCurrent_old=WIN_GetWinStruct()->winCurrent;
|
||
WIN_GetWinStruct()->winCurrent=win;
|
||
void *msgData=0;
|
||
while (QUEUE_Out (&win->winMsgQueue,&msg))
|
||
{
|
||
run=1;
|
||
//先复制一份消息,然后释放消息指针,防止在消息循环中执行窗口删除操作之后产生野指针
|
||
msgData=msg.data.p;
|
||
|
||
switch (msg.msg)
|
||
{
|
||
//这些类型的消息在交给窗口处理之前要先设置好环境
|
||
case WIN_MSG_PAINT:
|
||
mymemcpy(&r,&win->invaldRect,sizeof(RECT_Struct));
|
||
|
||
//窗口不需要重绘
|
||
if (win->invald==0) continue;
|
||
|
||
//同时窗口位置的子窗口也要重绘
|
||
for (int i=win->chidWinNum;i>0;i--)
|
||
{
|
||
//判断这些窗口是否被遮挡
|
||
//设置为窗口相对坐标
|
||
RECT_Struct ret={0};
|
||
RECT_Struct r1={0};r1.x=win->chidWin[i-1]->x;r1.y=win->chidWin[i-1]->y;
|
||
r1.x_size=win->chidWin[i-1]->x_size;r1.y_size=win->chidWin[i-1]->y_size;
|
||
if (POS_RectIntersection(&ret,&r1,&r))
|
||
{
|
||
ret.x-=win->chidWin[i-1]->x;ret.y-=win->chidWin[i-1]->y;//减去窗口定位坐标,2020.2.26
|
||
WIN_SetInvalidRect(win->chidWin[i-1],ret.x,ret.y,ret.x_size,ret.y_size);
|
||
if(POS_RectSub(&r,&r,&r1)==0)
|
||
{
|
||
//重绘区为0,余下子窗口无需重绘
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
//顶端窗口需要重绘
|
||
WIN_TopWinPaint(win);
|
||
|
||
//清除窗口重绘标志
|
||
win->invald=0;
|
||
//需要重绘的窗口-1
|
||
if (WIN_GetWinStruct()->numOfWindowToPrint) WIN_GetWinStruct()->numOfWindowToPrint--;
|
||
else while (1);//不可能运行到的位置
|
||
|
||
//绘图区已经不存在,无需绘制
|
||
if(r.x_size<=0||r.y_size<=0) continue;
|
||
|
||
//设置绘图区域
|
||
WIN_EnterPaint (win);
|
||
//设置无效区
|
||
WIN_SetWinInvalidRect(win,&r);
|
||
|
||
//进入绘制缓冲区
|
||
WIN_GetWinStruct()->lcd->enterLayerBuff();
|
||
break;//case WIN_MSG_PAINT:
|
||
}//switch (msg.msg)
|
||
|
||
//运行窗口消息循环
|
||
win->msgLoop(win,&msg);
|
||
|
||
switch (msg.msg)
|
||
{
|
||
//这些类型的消息在发送时使用了malloc,这里释放掉
|
||
case WIN_MSG_KEY:
|
||
case WIN_MSG_TOUCH:
|
||
case WIN_MSG_EXTMSG:
|
||
myfree(msgData);
|
||
break;
|
||
case WIN_MSG_MOVE:
|
||
m=msg.data.p;
|
||
switch (m->moveType)
|
||
{
|
||
//把点击的窗口调整到最前面
|
||
case MOVE_DATA_TOUCHIN:
|
||
if (win->baseWin)
|
||
{
|
||
if (win!=win->baseWin->chidWin[win->baseWin->chidWinNum-1])
|
||
{
|
||
//不是顶端窗口,重绘整个窗口
|
||
if (WIN_SetChidWinTop (win->baseWin,win)==0)
|
||
WIN_SetInvalid(win);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
myfree(msgData);
|
||
break;//case WIN_MSG_MOVE:
|
||
//绘图操作已经完成,刷新屏幕
|
||
case WIN_MSG_PAINT:
|
||
if (WIN_GetWinStruct()->numOfWindowToPrint==0) //LCD_ExitLayerBuff();
|
||
WIN_GetWinStruct()->lcd->exitLayerBuff();
|
||
break;
|
||
//这些类型的消息需要绘制背景
|
||
case WIN_MSG_DELETE:
|
||
if (win->baseWin)
|
||
{
|
||
//父窗口要重绘
|
||
//WIN_SetInvalidRect(win->baseWin,win->x,win->y,win->x_size,win->y_size);
|
||
}//if (win->baseWin)
|
||
break;
|
||
}//switch (msg.msg)
|
||
}//while (QUEUE_Out (&win->winMsgQueue,&msg))
|
||
|
||
//然后子窗口处理消息
|
||
for (int i=0;i<win->chidWinNum;i++)
|
||
{
|
||
run|=WIN_Working(win->chidWin[i]);
|
||
}
|
||
|
||
WIN_GetWinStruct()->winCurrent=winCurrent_old;
|
||
if (win->msgLoopEnter)
|
||
win->msgLoopEnter--;
|
||
//这是最后一层消息循环,并且窗口已销毁
|
||
if ((win->msgLoopEnter==0)&&(win->memFree))
|
||
{win->memFree(win);}
|
||
|
||
return run;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//以非阻塞方式运行所有窗口
|
||
void WIN_Delay (int ms)
|
||
{
|
||
WIN_GetWinStruct()->delay_ms=ms;
|
||
WIN_Delay_ms(WIN_GetWinStruct()->delay_ms);
|
||
if (WIN_GetWinStruct()->runCallBack) WIN_GetWinStruct()->runCallBack();
|
||
WIN_TimerWork ();
|
||
while(WIN_MsgBroad(WIN_GetBaseWindow()));
|
||
while(WIN_Working (WIN_GetBaseWindow()));
|
||
}
|
||
|
||
//以阻塞方式运行指定窗口
|
||
int WIN_RunBlock (WIN_WindowStruct *win)
|
||
{
|
||
WIN_WindowStruct *win_save=win;
|
||
|
||
//是否超出了最大嵌套层数
|
||
if (WIN_GetWinStruct()->BlockWinNum>=WIN_BLOCK_MAXNUM)
|
||
{
|
||
win->deleteWindow(win);
|
||
return -1;
|
||
}
|
||
|
||
//窗口栈入栈
|
||
for (int i=WIN_GetWinStruct()->BlockWinNum;i>0;i--)
|
||
{
|
||
WIN_GetWinStruct()->BlockWin[i]=WIN_GetWinStruct()->BlockWin[i-1];
|
||
}
|
||
WIN_GetWinStruct()->BlockWin[0]=win;
|
||
WIN_GetWinStruct()->BlockWinNum++;
|
||
|
||
//开始运行
|
||
while (WIN_GetWinStruct()->BlockWin[0]==win_save)
|
||
{
|
||
WIN_Delay_ms(WIN_GetWinStruct()->delay_ms);
|
||
if (WIN_GetWinStruct()->runCallBack) WIN_GetWinStruct()->runCallBack();
|
||
WIN_TimerWork ();
|
||
while(WIN_MsgBroad(WIN_GetWinStruct()->BlockWin[0]));
|
||
//WIN_Working (WIN_GetBaseWindow());
|
||
while(WIN_Working (WIN_GetBaseWindow()));
|
||
}
|
||
|
||
//返回窗口的返回值
|
||
return WIN_GetWinStruct()->BlockWinReturn;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//把窗口设置为无效
|
||
void WIN_SetInvalid (WIN_WindowStruct *win)
|
||
{
|
||
WIN_SetInvalidRect(win,0,0,win->x_size,win->y_size);
|
||
}
|
||
|
||
|
||
//当窗口是最顶窗口时,设置为无效
|
||
void WIN_SetInvalidWhenTop (WIN_WindowStruct *win)
|
||
{
|
||
WIN_SetInvalidRectWhenTop(win,0,0,win->x_size,win->y_size);
|
||
}
|
||
|
||
|
||
|
||
//把窗口指定区域设置为无效,以窗口的坐标为原点
|
||
void WIN_SetInvalidRect (WIN_WindowStruct *win,int x,int y,int x_size,int y_size)
|
||
{
|
||
RECT_Struct *r;
|
||
if (win->memFree) return; //不给已销毁的窗口发消息
|
||
//发送paint消息
|
||
WIN_MsgStruct msg={0};
|
||
msg.msg=WIN_MSG_PAINT;
|
||
r=mymalloc (sizeof (RECT_Struct));
|
||
|
||
|
||
WIN_GetWinPosOnLcd(win, &r->x, &r->y, &r->x_size, &r->y_size);
|
||
RECT_Struct r_win = { 0 };
|
||
r_win.x = r->x; r_win.y = r->y;
|
||
|
||
//设置无效区在窗口范围内
|
||
WIN_WindowStruct *t = win;
|
||
RECT_Struct r_now = { 0 };
|
||
do {
|
||
WIN_GetWinPosOnLcd(t, &r_now.x, &r_now.y, &r_now.x_size, &r_now.y_size);
|
||
|
||
POS_RectIntersection(r, r, &r_now);
|
||
t = t->baseWin;
|
||
} while (t);
|
||
r->x -= r_win.x; r->y -= r_win.y;
|
||
RECT_Struct r_in={0};
|
||
r_in.x=x;r_in.y=y;r_in.x_size=x_size;r_in.y_size=y_size;
|
||
POS_RectIntersection (r,r, &r_in);
|
||
|
||
|
||
|
||
if (win->invald==0)
|
||
{
|
||
WIN_SendMsg (0,win,&msg);
|
||
mymemcpy (&win->invaldRect,r,sizeof (RECT_Struct));
|
||
win->invald=1;
|
||
WIN_GetWinStruct()->numOfWindowToPrint++;//需要绘制的窗口加1
|
||
}
|
||
else
|
||
{
|
||
POS_RectContain (&win->invaldRect,&win->invaldRect,r);
|
||
}
|
||
|
||
|
||
myfree(r);
|
||
|
||
}
|
||
|
||
|
||
|
||
//当窗口是最顶窗口时,设置为无效
|
||
void WIN_SetInvalidRectWhenTop (WIN_WindowStruct *win,int x,int y,int x_size,int y_size)
|
||
{
|
||
if (WIN_FindBlock(win)==0)
|
||
{
|
||
WIN_SetInvalidRect (win,x,y,x_size,y_size);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
//窗口移动
|
||
void WIN_Move(WIN_WindowStruct *win,int x_move,int y_move)
|
||
{
|
||
|
||
RECT_Struct r1={0};
|
||
RECT_Struct r2={0};
|
||
r1.x=win->x;r1.y=win->y;r1.x_size=win->x_size;r1.y_size=win->y_size;
|
||
mymemcpy(&r2,&r1 ,sizeof(RECT_Struct));
|
||
win->x+=x_move;
|
||
win->y+=y_move;
|
||
r2.x=win->x;r2.y=win->y;
|
||
|
||
POS_RectContain(&r1,&r1,&r2);
|
||
|
||
if(win->baseWin)
|
||
WIN_SetInvalidRect(win->baseWin,r1.x,r1.y,r1.x_size,r1.y_size);
|
||
|
||
// WIN_SetInvalid(win);
|
||
}
|
||
|
||
//设置窗口坐标
|
||
void WIN_SetPos(WIN_WindowStruct *win,int x,int y)
|
||
{
|
||
RECT_Struct r1={0};
|
||
RECT_Struct r2={0};
|
||
r1.x=win->x;r1.y=win->y;r1.x_size=win->x_size;r1.y_size=win->y_size;
|
||
mymemcpy(&r2,&r1 ,sizeof(RECT_Struct));
|
||
win->x=x;
|
||
win->y=y;
|
||
r2.x=win->x;r2.y=win->y;
|
||
|
||
POS_RectContain(&r1,&r1,&r2);
|
||
|
||
if(win->baseWin)
|
||
WIN_SetInvalidRect(win->baseWin,r1.x,r1.y,r1.x_size,r1.y_size);
|
||
|
||
// WIN_SetInvalid(win);
|
||
|
||
}
|
||
|
||
|
||
|
||
//设置窗口尺寸
|
||
void WIN_SetSize(WIN_WindowStruct *win,int x_size,int y_size)
|
||
{
|
||
RECT_Struct r1={0};
|
||
RECT_Struct r2={0};
|
||
r1.x=win->x;r1.y=win->y;r1.x_size=win->x_size;r1.y_size=win->y_size;
|
||
mymemcpy(&r2,&r1 ,sizeof(RECT_Struct));
|
||
win->x_size=x_size;
|
||
win->y_size=y_size;
|
||
r2.x_size=win->x_size;r2.y_size=win->y_size;
|
||
|
||
POS_RectContain(&r1,&r1,&r2);
|
||
|
||
if(win->baseWin)
|
||
WIN_SetInvalidRect(win->baseWin,r1.x,r1.y,r1.x_size,r1.y_size);
|
||
|
||
// WIN_SetInvalid(win);
|
||
|
||
}
|
||
|
||
|
||
|