📄 desktop.c
字号:
RECT rcTemp; pNode = zorder->pTopMost; while (pNode) { if (pNode->hWnd == (HWND)pWin) break; pTemp = (PMAINWIN)(pNode->hWnd); if (pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); SubtractClipRect (&pGCRInfo->crgn, &rcTemp); } pNode = pNode->pNext; }}// When show an invisible new main window, // call this function to update all other windows' GCRInfo.//// Window functions which lead to calling this function:// ShowWindow: show an invisible main window with a SW_SHOW parameter.// // this main window is a normal main window.static void dskUpdateGCRInfoOnShowNewMainWin (MAINWIN* pWin){ RECT rcWin; dskGetWindowRectInScreen (pWin, &rcWin); start_clip_window (pWin); clip_by_windows (&TopMostWinZOrder, pWin); end_clip_window (pWin); clip_windows_under_this (&MainWinZOrder, pWin, &rcWin); clip_desktop (&rcWin);}// this main window is a top most window.static void dskUpdateGCRInfoOnShowNewMainWinEx(MAINWIN* pWin){ RECT rcWin; dskGetWindowRectInScreen (pWin, &rcWin); clip_windows_under_this (&TopMostWinZOrder, pWin, &rcWin); clip_windows (&MainWinZOrder, &rcWin); clip_desktop (&rcWin);}// When show a main window, all main windows which are covered by// this showing main window will be updated.// // Window functions which lead to calling this function:// ShowWindow: show an invisible main window with a SW_SHOW parameter.//// this is a normal main window.static void dskUpdateGCRInfoOnShowMainWin (MAINWIN* pWin){ RECT rcWin; dskGetWindowRectInScreen (pWin, &rcWin); start_clip_window (pWin); reset_window (pWin, &rcWin); clip_by_windows (&TopMostWinZOrder, pWin); clip_by_all_above_this (&MainWinZOrder, pWin); end_clip_window (pWin); clip_windows_under_this (&MainWinZOrder, pWin, &rcWin); clip_desktop (&rcWin);}// this window is a main window with WS_EX stylestatic void dskUpdateGCRInfoOnShowMainWinEx(MAINWIN* pWin){ RECT rcWin; // update this showing window's clip region info. dskGetWindowRectInScreen (pWin, &rcWin); start_clip_window (pWin); reset_window (pWin, &rcWin); clip_by_all_above_this (&TopMostWinZOrder, pWin); end_clip_window (pWin); clip_windows_under_this (&TopMostWinZOrder, pWin, &rcWin); clip_windows (&MainWinZOrder, &rcWin); clip_desktop (&rcWin);}static BOOL dskDoesCoverOther (PMAINWIN pWin1, PMAINWIN pWin2){ PZORDERNODE pNode; if (pWin1 == NULL) return FALSE; if (pWin2 == NULL) return TRUE; pNode = MainWinZOrder.pTopMost; while(pNode) { if (pNode->hWnd == (HWND)pWin1) return TRUE; if (pNode->hWnd == (HWND)pWin2) return FALSE; pNode = pNode->pNext; } return FALSE;}static BOOL dskIsTopMost (PMAINWIN pWin){ if (pWin->dwExStyle & WS_EX_TOPMOST) return ((HWND)pWin == TopMostWinZOrder.pTopMost->hWnd); else return ((HWND)pWin == MainWinZOrder.pTopMost->hWnd);}static PMAINWIN dskChangActiveWindow (PMAINWIN pWin){ PMAINWIN pOldActive; if (sg_hIMEWnd && (sg_hIMEWnd == (HWND)pWin)) return pActiveMainWnd; if (pWin == pActiveMainWnd) return pActiveMainWnd; pOldActive = pActiveMainWnd; DesktopSetActiveWindow (pWin); if (pWin) { SendAsyncMessage ((HWND)pWin, MSG_NCACTIVATE, TRUE, 0); SendNotifyMessage ((HWND)pWin, MSG_ACTIVE, TRUE, 0); SendNotifyMessage ((HWND)pWin, MSG_SETFOCUS, 0, 0); } if (pOldActive && (pOldActive->dwStyle & WS_VISIBLE)) { SendAsyncMessage ((HWND)pOldActive, MSG_NCACTIVATE, FALSE, 0); SendNotifyMessage ((HWND)pWin, MSG_ACTIVE, FALSE, 0); SendNotifyMessage ((HWND)pOldActive, MSG_KILLFOCUS, 0, 0); } return pOldActive;}// This function called when a window was shown.// return: the new active window.// when return value is NULL, the active window not changed.//static PMAINWIN dskShowMainWindow(PMAINWIN pWin, BOOL bActive){ if (pWin->dwStyle & WS_VISIBLE) return NULL; if (pWin->dwExStyle & WS_EX_TOPMOST) dskUpdateGCRInfoOnShowMainWinEx (pWin); else dskUpdateGCRInfoOnShowMainWin (pWin); pWin->dwStyle |= WS_VISIBLE; SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, 0); InvalidateRect ((HWND)pWin, NULL, TRUE); if (pWin->dwExStyle & WS_EX_TOPMOST) return dskChangActiveWindow (pWin); // if the showing window cover the current active window // set this window as the active one. if (bActive && dskDoesCoverOther (pWin, pActiveMainWnd)) return dskChangActiveWindow (pWin); return NULL; }// Main window hosting.//// Add new hosted main window.//void dskAddNewHostedMainWindow (PMAINWIN pHosting, PMAINWIN pHosted){ PMAINWIN head, prev; pHosted->pNextHosted = NULL; head = pHosting->pFirstHosted; if (head) { while (head) { prev = head; head = head->pNextHosted; } prev->pNextHosted = pHosted; } else pHosting->pFirstHosted = pHosted; return;}// Main Window hosting.//// Remove a hosted main window.//void dskRemoveHostedMainWindow (PMAINWIN pHosting, PMAINWIN pHosted){ PMAINWIN head, prev; head = pHosting->pFirstHosted; if (head == pHosted) { pHosting->pFirstHosted = head->pNextHosted; return; } while (head) { prev = head; head = head->pNextHosted; if (head == pHosted) { prev->pNextHosted = head->pNextHosted; return; } } return;}static void init_gcrinfo (PMAINWIN pWin){ RECT rcWin, rcTemp; dskGetWindowRectInScreen (pWin, &rcWin); pthread_mutex_init (&pWin->pGCRInfo->lock, NULL); pWin->pGCRInfo->age = 0; InitClipRgn (&pWin->pGCRInfo->crgn, &sg_FreeClipRectList); IntersectRect (&rcTemp, &rcWin, &g_rcScr); SetClipRgn (&pWin->pGCRInfo->crgn, &rcTemp);}static void init_invrgn (PMAINWIN pWin){ pthread_mutex_init (&pWin->InvRgn.lock, NULL); InitClipRgn (&pWin->InvRgn.rgn, &sg_FreeInvRectList); EmptyClipRgn (&pWin->InvRgn.rgn);}static void add_new_window (ZORDERINFO* zorder, PZORDERNODE pNode){ pNode->pNext = zorder->pTopMost; zorder->pTopMost = pNode; zorder->nNumber++;}static void remove_window (ZORDERINFO* zorder, PMAINWIN pWin){ PZORDERNODE pNode, pTemp; pNode = zorder->pTopMost; if (pNode->hWnd == (HWND)pWin) { zorder->pTopMost = pNode->pNext; } else { while (pNode->pNext) { if (pNode->pNext->hWnd == (HWND)pWin) { pTemp = pNode->pNext->pNext; pNode->pNext = pTemp; break; } pNode = pNode->pNext; } } zorder->nNumber--;}// this funciton add the new main window to the main window list.// if new main window is a visible window,// this new main window becomes the active window and this function// return the old main window.// otherwise, return NULL.static PMAINWIN dskAddNewMainWindow (PMAINWIN pWin, PZORDERNODE pNode){ // Handle main window hosting. if (pWin->pHosting) dskAddNewHostedMainWindow (pWin->pHosting, pWin); // Init Global Clip Region info. init_gcrinfo (pWin); // Init Invalid Region info. init_invrgn (pWin); // Update Z Order info. pNode->hWnd = (HWND)pWin; if (pWin->dwExStyle & WS_EX_TOPMOST) add_new_window (&TopMostWinZOrder, pNode); else add_new_window (&MainWinZOrder, pNode); // show and active this main window. if ( pWin->dwStyle & WS_VISIBLE ) { if (pWin->dwExStyle & WS_EX_TOPMOST) dskUpdateGCRInfoOnShowNewMainWinEx (pWin); else dskUpdateGCRInfoOnShowNewMainWin (pWin); SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, 0); SendNotifyMessage ((HWND)pWin, MSG_SHOWWINDOW, SW_SHOWNORMAL, 0); InvalidateRect ((HWND)pWin, NULL, TRUE); return dskChangActiveWindow (pWin); } return NULL;}// This function defined in gui/window.cBOOL wndInvalidateRect (HWND hWnd, const RECT* prc, BOOL bEraseBkgnd);// this function called when a visible main win becomes as a top most window.// this is a normal main window.static BOOL update_on_change_topmost (ZORDERINFO* zorder, PMAINWIN pNew, RECT* rcNew){ PGCRINFO pGCRInfo; PZORDERNODE pNode; RECT rcInter; RECT rcOther; BOOL inved = FALSE; // clip all main windows which will covered by this new top most window pNode = zorder->pTopMost; while (pNode) { if ( pNode->hWnd == (HWND)pNew ) break; if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen ((PMAINWIN)pNode->hWnd, &rcOther); if (IntersectRect(&rcInter, rcNew, &rcOther)) { pGCRInfo = ((PMAINWIN)(pNode->hWnd))->pGCRInfo; pthread_mutex_lock (&pGCRInfo->lock); SubtractClipRect (&pGCRInfo->crgn, rcNew); pGCRInfo->age ++; pthread_mutex_unlock (&pGCRInfo->lock); // update this window's client area. dskScreenToClient (pNew, &rcInter, &rcInter); wndInvalidateRect ((HWND)pNew, &rcInter, TRUE); inved = TRUE; } } pNode = pNode->pNext; } return inved;}static void dskUpdateGCRInfoOnChangeTopMost(PMAINWIN pNew){ RECT rcNew; dskGetWindowRectInScreen (pNew, &rcNew); if (update_on_change_topmost (&MainWinZOrder, pNew, &rcNew)); PostMessage ((HWND)pNew, MSG_PAINT, 0, 0);}// this is a top most windowstatic void dskUpdateGCRInfoOnChangeTopMostEx (PMAINWIN pNew){ RECT rcNew; dskGetWindowRectInScreen (pNew, &rcNew); if (update_on_change_topmost (&TopMostWinZOrder, pNew, &rcNew)) PostMessage ((HWND)pNew, MSG_PAINT, 0, 0);}static void move_to_top (ZORDERINFO* zorder, PMAINWIN pWin){ PZORDERNODE pNode, pTemp; pNode = zorder->pTopMost; if (pNode->hWnd != (HWND)pWin) { while (pNode->pNext) { if (pNode->pNext->hWnd == (HWND)pWin) { pTemp = pNode->pNext; pNode->pNext = pNode->pNext->pNext; pTemp->pNext = zorder->pTopMost; zorder->pTopMost = pTemp; break; } pNode = pNode->pNext; } }}// this function called when a main window becomes a visible top most window.// Functions which lead to call this function:// ShowWindow: show a invisible window with SW_SHOWNORMAL parameters.//// return: old active window.//static PMAINWIN dskMoveToTopMost (PMAINWIN pWin, BOOL bActive){ RECT rcWin; if (!pWin) return pActiveMainWnd; if (dskIsTopMost (pWin) && (pWin->dwStyle & WS_VISIBLE)) return pActiveMainWnd; // update this main window's global clip region info. dskGetWindowRectInScreen (pWin, &rcWin); start_clip_window (pWin); reset_window (pWin, &rcWin); if (!(pWin->dwExStyle & WS_EX_TOPMOST)) clip_by_windows (&TopMostWinZOrder, pWin); end_clip_window (pWin); // activate this main window. if ( !(pWin->dwStyle & WS_VISIBLE) ) { // Update Z Order first. if (pWin->dwExStyle & WS_EX_TOPMOST) move_to_top (&TopMostWinZOrder, pWin); else move_to_top (&MainWinZOrder, pWin); if (pWin->dwExStyle & WS_EX_TOPMOST) dskUpdateGCRInfoOnShowNewMainWinEx (pWin); else dskUpdateGCRInfoOnShowNewMainWin (pWin); pWin->dwStyle |= WS_VISIBLE; SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, 0); InvalidateRect ((HWND)pWin, NULL, TRUE); } else { SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, 0); if (pWin->dwExStyle & WS_EX_TOPMOST) dskUpdateGCRInfoOnChangeTopMostEx (pWin); else dskUpdateGCRInfoOnChangeTopMost (pWin); // then update Z Order. if (pWin->dwExStyle & WS_EX_TOPMOST) move_to_top (&TopMostWinZOrder, pWin); else move_to_top (&MainWinZOrder, pWin); } if (bActive)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -