Files
player/Project/Src/MyWin/MyWinCore/mywin_msg.c
2025-07-06 18:46:13 +08:00

825 lines
24 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
}