Files
player/Project/Src/MyWin/MyWinCore/mywin_msg.c

979 lines
22 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#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);
}