diff --git a/Project/Src/MyWin/MyWinCore/mywin.c b/Project/Src/MyWin/MyWinCore/mywin.c index db99f08..0f7fd62 100644 --- a/Project/Src/MyWin/MyWinCore/mywin.c +++ b/Project/Src/MyWin/MyWinCore/mywin.c @@ -193,12 +193,8 @@ int WIN_CreatWindowExt(WIN_WindowStruct *win, WIN_WindowStruct *base, void WIN_DeleteWindow(WIN_WindowStruct *win) { // 调用子窗口的销毁函数 - // for (int i=0;ichidWinNum;i++) - // { - // (win->chidWin[i])->deleteWindow(win->chidWin[i]); - // } while (win->chidWinNum) { - (win->chidWin[0])->deleteWindow(win->chidWin[0]); + (win->chid)->deleteWindow(win->chid); } // 在父窗口的窗口列表中删除 @@ -293,10 +289,12 @@ WIN_WindowStruct *WIN_GetWindowStructById(WIN_WindowStruct *win, u32 id) { if (win->id == id) { return win; } else { + WIN_WindowStruct *prev = WIN_GetLastChidWin(win); for (int i = win->chidWinNum; i > 0; i--) { - if (ret = WIN_GetWindowStructById(win->chidWin[i - 1], id), ret) { + if (ret = WIN_GetWindowStructById(prev, id), ret) { return ret; } + prev = prev->prev; } } return ret; @@ -304,16 +302,23 @@ WIN_WindowStruct *WIN_GetWindowStructById(WIN_WindowStruct *win, u32 id) { // 从子窗口列表中删除指定窗口 int WIN_DelFromChidList(WIN_WindowStruct *win, WIN_WindowStruct *chidWin) { + WIN_WindowStruct *next = win->chid; for (int i = 0; i < win->chidWinNum; i++) { - if (win->chidWin[i] == chidWin) { - win->chidWin[i] = 0; // 删除这一个 - for (; i < win->chidWinNum - 1; i++) // 后面的向前移 - { - win->chidWin[i] = win->chidWin[i + 1]; + if (next == chidWin) { + if(next != win->chid) { + next->prev->next = next->next; + } else { + win->chid = next->next; + } + if(next->next){ + next->next->prev = next->prev; + }else{ + win->chid->prev = next->prev; } win->chidWinNum--; // 子窗口个数减一 return 0; } + next = next->next; } return -1; } @@ -321,17 +326,27 @@ int WIN_DelFromChidList(WIN_WindowStruct *win, WIN_WindowStruct *chidWin) { // 把指定子窗口设置为最高 int WIN_SetChidWinTop(WIN_WindowStruct *win, WIN_WindowStruct *chidWin) { WIN_WindowStruct *t = 0; + WIN_WindowStruct *next = win->chid; for (int i = 0; i < win->chidWinNum; i++) { - if (win->chidWin[i] == chidWin) { - t = win->chidWin[i]; - win->chidWin[i] = 0; // 删除这一个 - for (; i < win->chidWinNum; i++) // 后面的向前移 - { - win->chidWin[i] = win->chidWin[i + 1]; + if (next == chidWin) { + t = next; + if(next != win->chid) { + next->prev->next = next->next; + } else { + win->chid = next->next; } - win->chidWin[win->chidWinNum - 1] = t; // 设置为最后一个 + if(next->next){ + next->next->prev = next->prev; + }else{ + win->chid->prev = next->prev; + } + t->next = 0; + t->prev = win->chid->prev; + win->chid->prev->next = t; + win->chid->prev = t; return 0; } + next = next->next; } return -1; } @@ -339,7 +354,14 @@ int WIN_SetChidWinTop(WIN_WindowStruct *win, WIN_WindowStruct *chidWin) { // 添加窗口到子窗口列表中 int WIN_AddToChidList(WIN_WindowStruct *win, WIN_WindowStruct *chidWin) { if (win->chidWinNum < win->chidWinMaxSize) { - win->chidWin[win->chidWinNum] = chidWin; + chidWin->next = 0; + if(win->chid == 0){ + win->chid = chidWin; + }else{ + chidWin->prev = win->chid->prev; + win->chid->prev->next = chidWin; + } + win->chid->prev = chidWin; win->chidWinNum++; return 0; } else { @@ -349,9 +371,11 @@ int WIN_AddToChidList(WIN_WindowStruct *win, WIN_WindowStruct *chidWin) { // 判断目标窗口是不是子窗口,是返回1 int WIN_CheckChidWin(WIN_WindowStruct *win, WIN_WindowStruct *chid) { + WIN_WindowStruct *next = win->chid; for (int i = 0; i < win->chidWinNum; i++) { - if (win->chidWin[i] == chid) + if (next == chid) return 1; + next = next->next; } return 0; } @@ -429,12 +453,13 @@ WIN_WindowStruct *WIN_GetCurrentWindow(void) { // 找到顶端可控窗口 WIN_WindowStruct *WIN_FindTopWin(WIN_WindowStruct *win) { WIN_WindowStruct *ret = 0; - + WIN_WindowStruct *prev = WIN_GetLastChidWin(win); if (win && (win->chidWinNum)) { for (int i = win->chidWinNum; i > 0; i--) { - ret = WIN_FindTopWin(win->chidWin[i - 1]); + ret = WIN_FindTopWin(prev); if (ret) return ret; + prev = prev->prev; } } // 本窗口接受消息处理并且不是子窗口 @@ -450,10 +475,12 @@ int WIN_FindBlock(WIN_WindowStruct *win) { RECT_Struct r2 = {0}; WIN_WindowStruct *top = 0; WIN_WindowStruct *base = win->baseWin; + WIN_WindowStruct *next = win->chid; + WIN_WindowStruct *prev; // 该窗口被遮挡只可能是其子窗口和其同辈父辈窗口 for (int i = 0; i < win->chidWinNum; i++) { - top = win->chidWin[i]; + top = next; if ((top->keyShield == 1) || (top->keyChid == 1)) continue; r1.x = 0; @@ -467,10 +494,12 @@ int WIN_FindBlock(WIN_WindowStruct *win) { if (POS_RectIntersection(&r1, &r1, &r2)) { return 1; } + next = next->next; } while (base) { + prev = WIN_GetLastChidWin(base); for (int i = base->chidWinNum; i > 0; i--) { - top = base->chidWin[i - 1]; + top = prev; if (top == win) { // 只比较在此窗口之前的窗口 // 若没有被遮挡,则继续判断其父窗口是否被遮挡 @@ -482,6 +511,7 @@ int WIN_FindBlock(WIN_WindowStruct *win) { if (POS_RectIntersection(&r1, &r1, &r2)) { return 1; } + prev = prev->prev; } base = base->baseWin; } @@ -490,8 +520,10 @@ int WIN_FindBlock(WIN_WindowStruct *win) { // 屏蔽和接触屏蔽子窗口的按键和键盘消息 int WIN_SetChildWinkeyShield(WIN_WindowStruct *win, int power) { + WIN_WindowStruct *prev = WIN_GetLastChidWin(win); for (int i = win->chidWinNum - 1; i >= 0; i--) { - win->chidWin[i]->keyShield = power; + prev->keyShield = power; + prev = prev->prev; } return 1; } @@ -503,6 +535,7 @@ WIN_WindowStruct *WIN_FindTopWinByPos(WIN_WindowStruct *win, int x, int y) { int win_y_s = 0; int x_size = win->x_size; int y_size = win->y_size; + WIN_WindowStruct *prev = WIN_GetLastChidWin(win); WIN_GetWinPosOnLcd(win, &win_x_s, &win_y_s, &x_size, &y_size); @@ -512,11 +545,12 @@ WIN_WindowStruct *WIN_FindTopWinByPos(WIN_WindowStruct *win, int x, int y) { // 在本窗口内,查找是否有子窗口 // 从最后开始查找,因为越最后的显示在越前面 for (int i = win->chidWinNum - 1; i >= 0; i--) { - t = WIN_FindTopWinByPos(win->chidWin[i], x, y); + t = WIN_FindTopWinByPos(prev, x, y); if (t) { ret = t; // 找到了最前面的窗口 break; } + prev = prev->prev; } } else { // 指定点不在本窗口之类 @@ -553,13 +587,15 @@ WIN_WindowStruct *WIN_GetWinByTitle(WIN_WindowStruct *win, char *title) { WIN_WindowStruct *ret = 0; if (win == 0) win = WIN_GetBaseWindow(); + WIN_WindowStruct *next = win->chid; if (strcmp(win->winTitle, title) == 0) { ret = win; } else { for (int i = 0; i < win->chidWinNum; i++) { - if (ret = WIN_GetWinByTitle(win->chidWin[i], title), ret) + if (ret = WIN_GetWinByTitle(next, title), ret) break; + next = next->next; } } diff --git a/Project/Src/MyWin/MyWinCore/mywin_msg.c b/Project/Src/MyWin/MyWinCore/mywin_msg.c index 0345c75..d0e4094 100644 --- a/Project/Src/MyWin/MyWinCore/mywin_msg.c +++ b/Project/Src/MyWin/MyWinCore/mywin_msg.c @@ -524,6 +524,8 @@ int WIN_Working(WIN_WindowStruct *win) { WIN_MsgStruct msg = {0}; win->msgLoopEnter++; WIN_WindowStruct *winCurrent_old = WIN_GetWinStruct()->winCurrent; + WIN_WindowStruct *prev; + WIN_WindowStruct *next; WIN_GetWinStruct()->winCurrent = win; void *msgData = 0; while (QUEUE_Out(&win->winMsgQueue, &msg)) { @@ -541,25 +543,27 @@ int WIN_Working(WIN_WindowStruct *win) { continue; // 同时窗口位置的子窗口也要重绘 + prev = WIN_GetLastChidWin(win); 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; + r1.x = prev->x; + r1.y = prev->y; + r1.x_size = prev->x_size; + r1.y_size = prev->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.x -= prev->x; + ret.y -= prev->y; // 减去窗口定位坐标,2020.2.26 + WIN_SetInvalidRect(prev, ret.x, ret.y, ret.x_size, ret.y_size); if (POS_RectSub(&r, &r, &r1) == 0) { // 重绘区为0,余下子窗口无需重绘 break; } } + prev = prev->prev; } // 顶端窗口需要重绘 @@ -604,7 +608,7 @@ int WIN_Working(WIN_WindowStruct *win) { // 把点击的窗口调整到最前面 case MOVE_DATA_TOUCHIN: if (win->baseWin) { - if (win != win->baseWin->chidWin[win->baseWin->chidWinNum - 1]) { + if (win != win->baseWin->chid->prev) { // 不是顶端窗口,重绘整个窗口 if (WIN_SetChidWinTop(win->baseWin, win) == 0) WIN_SetInvalid(win); @@ -630,8 +634,10 @@ int WIN_Working(WIN_WindowStruct *win) { } // while (QUEUE_Out (&win->winMsgQueue,&msg)) // 然后子窗口处理消息 - for (int i = 0; i < win->chidWinNum; i++) { - run |= WIN_Working(win->chidWin[i]); + next = win->chid; + while(next) { + run |= WIN_Working(next); + next = next->next; } WIN_GetWinStruct()->winCurrent = winCurrent_old; diff --git a/Project/Src/MyWin/MyWinCore/mywin_type.h b/Project/Src/MyWin/MyWinCore/mywin_type.h index 2a664c6..b436b16 100644 --- a/Project/Src/MyWin/MyWinCore/mywin_type.h +++ b/Project/Src/MyWin/MyWinCore/mywin_type.h @@ -248,12 +248,17 @@ typedef struct _WIN_WindowStruct { int chidWinMaxSize; int chidWinNum; struct _WIN_WindowStruct *baseWin; - struct _WIN_WindowStruct *chidWin[WIN_CHIDWIN_MAXNUM]; + struct _WIN_WindowStruct *prev; + struct _WIN_WindowStruct *next; + struct _WIN_WindowStruct *chid; void (*msgLoop)(struct _WIN_WindowStruct *win, WIN_MsgStruct *msg); void (*deleteWindow)(struct _WIN_WindowStruct *win); QUEUE_Struct winMsgQueue; } WIN_WindowStruct; +// 定义获取最后一个子窗口的宏 +#define WIN_GetLastChidWin(win) (win->chidWinNum > 0 ? win->chid->prev : 0) + // 定义分发按键和触屏消息需要的工作空间结构体 typedef struct { int Touch_long; // 长按检测计数