📄 desktop-comm.c
字号:
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 (&sg_TopMostWinZOrder, pNode); else add_new_window (&sg_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; #ifndef _LITE_VERSION pthread_mutex_lock (&pGCRInfo->lock);#endif SubtractClipRect (&pGCRInfo->crgn, rcNew); pGCRInfo->age ++;#ifndef _LITE_VERSION pthread_mutex_unlock (&pGCRInfo->lock);#endif // 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 (&sg_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 (&sg_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; } }}static PMAINWIN dskHideMainWindow (PMAINWIN pWin);static void dskSetPrimitiveChildren (PMAINWIN pWin, BOOL bSet){ PMAINWIN pParent = (PMAINWIN) pWin->hParent; if (bSet) { while (pParent) { pParent->hPrimitive = (HWND)pWin; pWin = pParent; pParent = (PMAINWIN) pWin->hParent; } } else { while (pParent) { pParent->hPrimitive = 0; pWin = pParent; pParent = (PMAINWIN) pWin->hParent; } }}// 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, int reason, LPARAM lParam){ RECT rcWin; PMAINWIN pOldTopMost; if (!pWin) return __mg_active_mainwnd; if (pWin->dwExStyle & WS_EX_TOPMOST) pOldTopMost = (PMAINWIN) sg_TopMostWinZOrder.pTopMost->hWnd; else pOldTopMost = (PMAINWIN) sg_MainWinZOrder.pTopMost->hWnd; if (pOldTopMost && (pOldTopMost->WinType == TYPE_CONTROL) && (pOldTopMost->dwStyle & WS_VISIBLE)) { dskHideMainWindow (pOldTopMost); dskSetPrimitiveChildren (pOldTopMost, FALSE); SendNotifyMessage (pOldTopMost->hParent, MSG_CHILDHIDDEN, reason, lParam); } if (dskIsTopMost (pWin) && (pWin->dwStyle & WS_VISIBLE)) return __mg_active_mainwnd; // 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 (&sg_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 (&sg_TopMostWinZOrder, pWin); else move_to_top (&sg_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 (&sg_TopMostWinZOrder, pWin); else move_to_top (&sg_MainWinZOrder, pWin); } if (reason != RCTM_SHOWCTRL) return dskChangActiveWindow (pWin); else return __mg_active_mainwnd;}static void recalc_windows_under_this (ZORDERINFO* zorder, PMAINWIN pWin, RECT* rcWin){ PZORDERNODE pNode, pAffected; RECT rcTemp, rcInv; PMAINWIN pTemp; // where is the hidding main window? pNode = zorder->pTopMost; while (pNode->hWnd != (HWND)pWin) pNode = pNode->pNext; pAffected = pNode->pNext; while (pAffected){ pTemp = (PMAINWIN)(pAffected->hWnd); if (pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); start_clip_window (pTemp); reset_window (pTemp, &rcTemp); if (zorder != &sg_TopMostWinZOrder) { clip_by_windows (&sg_TopMostWinZOrder, pTemp); clip_by_all_above_this (&sg_MainWinZOrder, pTemp); } else clip_by_all_above_this (&sg_TopMostWinZOrder, pTemp); end_clip_window (pTemp); if (IntersectRect (&rcTemp, rcWin, &rcTemp)) { dskScreenToWindow (pTemp, &rcTemp, &rcInv); SendAsyncMessage ((HWND)pTemp, MSG_NCPAINT, 0, (LPARAM)(&rcInv)); dskScreenToClient (pTemp, &rcTemp, &rcInv); InvalidateRect ((HWND)pTemp, &rcInv, TRUE); } } pAffected = pAffected->pNext; }}static void recalc_windows (ZORDERINFO* zorder, RECT* rcWin){ PZORDERNODE pAffected; RECT rcTemp, rcInv; PMAINWIN pTemp; pAffected = zorder->pTopMost; while (pAffected){ pTemp = (PMAINWIN)(pAffected->hWnd); if (pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); start_clip_window (pTemp); reset_window (pTemp, &rcTemp); clip_by_windows (&sg_TopMostWinZOrder, pTemp); clip_by_all_above_this (&sg_MainWinZOrder, pTemp); end_clip_window (pTemp); if (IntersectRect (&rcTemp, rcWin, &rcTemp)) { dskScreenToWindow (pTemp, &rcTemp, &rcInv); SendAsyncMessage ((HWND)pTemp, MSG_NCPAINT, 0, (LPARAM)(&rcInv)); dskScreenToClient (pTemp, &rcTemp, &rcInv); InvalidateRect ((HWND)pTemp, &rcInv, TRUE); } } pAffected = pAffected->pNext; }}static void recalc_desktop (PTRACKMENUINFO ptmi){ PZORDERNODE pNode; RECT rcTemp; PMAINWIN pTemp; // update desktop's global clip region.#ifndef _LITE_VERSION pthread_mutex_lock (&sg_ScrGCRInfo.lock);#endif SetClipRgn (&sg_ScrGCRInfo.crgn, &g_rcDesktop); pNode = sg_TopMostWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if (pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); SubtractClipRect (&sg_ScrGCRInfo.crgn, &rcTemp); } pNode = pNode->pNext; } pNode = sg_MainWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if (pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); SubtractClipRect (&sg_ScrGCRInfo.crgn, &rcTemp); } pNode = pNode->pNext; } while (ptmi) { SubtractClipRect (&sg_ScrGCRInfo.crgn, &ptmi->rc); ptmi = ptmi->next; }#if defined(_LITE_VERSION) && !defined(_STAND_ALONE) if (mgIsServer && mgTopmostLayer) { MG_Client* client = mgTopmostLayer->cli_head; while (client) { SubtractClipRect (&sg_ScrGCRInfo.crgn, &client->rc); client = client->next; } }#endif sg_ScrGCRInfo.age ++;#ifndef _LITE_VERSION pthread_mutex_unlock (&sg_ScrGCRInfo.lock);#endif}// When hide a main win, all main win which is covered by// this hidding main win will be regenerated.//// Functions which lead to call this function:// ShowWindow: hide a visible window with SW_HIDE parameters.// DestroyWindow: destroy a visible window.//static void dskUpdateGCRInfoOnHideMainWin (MAINWIN* pWin){ RECT rcWin, rcTemp; pWin->dwStyle &= ~WS_VISIBLE; dskGetWindowRectInScreen (pWin, &rcWin); recalc_windows_under_this (&sg_MainWinZOrder, pWin, &rcWin); recalc_desktop (NULL); IntersectRect (&rcTemp, &rcWin, &g_rcDesktop); DesktopWinProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcTemp));}// this is a top most windowstatic void dskUpdateGCRInfoOnHideMainWinEx(MAINWIN* pWin){ RECT rcWin, rcTemp; pWin->dwStyle &= ~WS_VISIBLE; dskGetWindowRectInScreen (pWin, &rcWin); recalc_windows_under_this (&sg_TopMostWinZOrder, pWin, &rcWin); recalc_windows (&sg_MainWinZOrder, &rcWin); recalc_desktop (NULL); IntersectRect (&rcTemp, &rcWin, &g_rcDesktop); DesktopWinProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcTemp));}static PMAINWIN dskGetFirstActivableWindow (void){ PZORDERNODE pNode; PMAINWIN pTemp; pNode = sg_MainWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if ((pTemp->WinType != TYPE_CONTROL) && (pTemp->dwStyle & WS_VISIBLE) && !(pTemp->dwStyle & WS_DISABLED) && !(pTemp->dwExStyle & WS_EX_TOOLWINDOW)) return pTemp; pNode = pNode->pNext; } pNode = sg_TopMostWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if ((pTemp->WinType != TYPE_CONTROL) && (pTemp->dwStyle & WS_VISIBLE) && !(pTemp->dwStyle & WS_DISABLED) && !(pTemp->dwExStyle & WS_EX_TOOLWINDOW)) return pTemp; pNode = pNode->pNext; } return NULL;}static PMAINWIN dskGetNextVisibleMainWindow (PMAINWIN pWin){ PZORDERNODE pNode; PMAINWIN pTemp; if (pWin) pNode = pWin->pZOrderNode->pNext; else pNode = sg_MainWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if ((pTemp->WinType != TYPE_CONTROL) && (pTemp->dwStyle & WS_VISIBLE) && !(pTemp->dwStyle & WS_DISABLED)) return pTemp; pNode = pNode->pNext; } return NULL;}static PMAINWIN dskHideMainWindow (PMAINWIN pWin){ if (!(pWin->dwStyle & WS_VISIBLE)) return NULL; // Update all affected windows' GCR info. if (pWin->dwExStyle & WS_EX_TOPMOST) dskUpdateGCRInfoOnHideMainWinEx (pWin); else dskUpdateGCRInfoOnHideMainWin (pWin); // if this is the avtive window, // must choose another window as the active one. if (__mg_active_mainwnd == pWin) dskChangActiveWindow (dskGetFirstActivableWindow ()); return __mg_active_mainwnd;}// When destroy a main win, all main win which is covered by// this destroying main win will be redraw.//// Functions which lead to call this function:// DestroyWindow: destroy a visible window.//// return: the new active window.static PMAINWIN dskRemoveMainWindow (PMAINWIN pWin){ // Handle main window hosting. if (pWin->pHosting) dskRemoveHostedMainWindow (pWin->pHosting, pWin); // Update all affected windows' GCR info. if (pWin->dwStyle & WS_VISIBLE) { if (pWin->dwExStyle & WS_EX_TOPMOST) dskUpdateGCRInfoOnHideMainWinEx (pWin); else dskUpdateGCRInfoOnHideMainWin (pWin); if (__mg_active_mainwnd == pWin) dskChangActiveWindow (dskGetFirstActivableWindow ()); if (__mg_active_mainwnd == pWin) __mg_active_mainwnd = NULL; } // Update window Z order list. if (pWin->dwExStyle & WS_EX_TOPMOST) remove_window (&sg_TopMostWinZOrder, pWin); else remove_window (&sg_MainWinZOrder, pWin); return __mg_active_mainwnd;}static void dskUpdateAllGCRInfoOnShowMenu (RECT* prc){ clip_windows (&sg_TopMostWinZOrder, prc); clip_windows (&sg_MainWinZOrder, prc); clip_desktop (prc);}static void dskUpdateAllGCRInfoOnHideMenu (void){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -