#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_longTouch_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_longwin,&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_longKey_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_longk_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;ichidWinNum;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); }