📄 desktop-comm.c
字号:
void TerminateDesktop (void){ TerminateSysRes (); DestroyFreeClipRectList (&sg_FreeClipRectList); DestroyFreeClipRectList (&sg_FreeInvRectList);}PGCRINFO GetGCRgnInfo(HWND hWnd){ if (hWnd == HWND_DESKTOP) return &sg_ScrGCRInfo; return ((PMAINWIN)hWnd)->pGCRInfo;}inline void DesktopSetActiveWindow (PMAINWIN pWin){#ifndef _LITE_VERSION if (__mg_ime_wnd) SendNotifyMessage (__mg_ime_wnd, MSG_IME_SETTARGET, (WPARAM)pWin, 0);#endif __mg_active_mainwnd = pWin;}static HWND DesktopSetCapture(HWND hwnd){ HWND hTemp; hTemp = __mg_capture_wnd; __mg_capture_wnd = hwnd; return hTemp;}static void dskScreenToClient (PMAINWIN pWin, const RECT* rcScreen, RECT* rcClient){ PCONTROL pParent; rcClient->top = rcScreen->top - pWin->ct; rcClient->left = rcScreen->left - pWin->cl; rcClient->right = rcScreen->right - pWin->cl; rcClient->bottom = rcScreen->bottom - pWin->ct; pParent = (PCONTROL) pWin; while ((pParent = pParent->pParent)) { rcClient->top -= pParent->ct; rcClient->left -= pParent->cl; rcClient->right -= pParent->cl; rcClient->bottom -= pParent->ct; }}static void dskScreenToWindow (PMAINWIN pWin, const RECT* rcScreen, RECT* rcWindow){ PCONTROL pParent; rcWindow->top = rcScreen->top - pWin->top; rcWindow->left = rcScreen->left - pWin->left; rcWindow->right = rcScreen->right - pWin->left; rcWindow->bottom = rcScreen->bottom - pWin->top; pParent = (PCONTROL) pWin; while ((pParent = pParent->pParent)) { rcWindow->top -= pParent->ct; rcWindow->left -= pParent->cl; rcWindow->right -= pParent->cl; rcWindow->bottom -= pParent->ct; }}static void dskClientToScreen (PMAINWIN pWin, const RECT* rcClient, RECT* rcScreen){ PCONTROL pParent; rcScreen->top = rcClient->top + pWin->ct; rcScreen->left = rcClient->left + pWin->cl; rcScreen->right = rcClient->right + pWin->cl; rcScreen->bottom = rcClient->bottom + pWin->ct; pParent = (PCONTROL) pWin; while ((pParent = pParent->pParent)) { rcScreen->top += pParent->ct; rcScreen->left += pParent->cl; rcScreen->right += pParent->cl; rcScreen->bottom += pParent->ct; }}#if 0static void dskWindowToScreen (PMAINWIN pWin, const RECT* rcWindow, RECT* rcScreen){ PCONTROL pParent; rcScreen->top = rcWindow->top + pWin->top; rcScreen->left = rcWindow->left + pWin->left; rcScreen->right = rcWindow->right + pWin->left; rcScreen->bottom = rcWindow->bottom + pWin->top; pParent = (PCONTROL) pWin; while ((pParent = pParent->pParent)) { rcScreen->top += pParent->ct; rcScreen->left += pParent->cl; rcScreen->right += pParent->cl; rcScreen->bottom += pParent->ct; }}#endifstatic void dskGetWindowRectInScreen (PMAINWIN pWin, RECT* prc){ PCONTROL pParent; PCONTROL pCtrl; pParent = pCtrl = (PCONTROL)pWin; prc->left = pCtrl->left; prc->top = pCtrl->top; prc->right = pCtrl->right; prc->bottom = pCtrl->bottom; while ((pParent = pParent->pParent)) { prc->left += pParent->cl; prc->top += pParent->ct; prc->right += pParent->cl; prc->bottom += pParent->ct; }}static void dskGetClientRectInScreen (PMAINWIN pWin, RECT* prc){ PCONTROL pCtrl; PCONTROL pParent; pParent = pCtrl = (PCONTROL) pWin; prc->left = pCtrl->cl; prc->top = pCtrl->ct; prc->right = pCtrl->cr; prc->bottom = pCtrl->cb; while ((pParent = pParent->pParent)) { prc->left += pParent->cl; prc->top += pParent->ct; prc->right += pParent->cl; prc->bottom += pParent->ct; }}/************************* ZOrder operation **********************************/static void InitZOrderInfo(PZORDERINFO pZOrderInfo, HWND hHost){ pZOrderInfo->nNumber = 0; pZOrderInfo->hWnd = hHost; pZOrderInfo->pTopMost = NULL;}// reset clip info of windowstatic void reset_window (PMAINWIN pWin, RECT* rcWin){ PGCRINFO pGCRInfo; RECT rcTemp; pGCRInfo = pWin->pGCRInfo; IntersectRect (&rcTemp, rcWin, &g_rcDesktop); SetClipRgn (&pGCRInfo->crgn, &rcTemp);}inline void start_clip_window (PMAINWIN pWin){#ifndef _LITE_VERSION pthread_mutex_lock (&pWin->pGCRInfo->lock);#endif}inline static void end_clip_window (PMAINWIN pWin){ pWin->pGCRInfo->age ++;#ifndef _LITE_VERSION pthread_mutex_unlock (&pWin->pGCRInfo->lock);#endif}// clip by all windows in specified zorder// call start_clip_window and end_clip_window.static void clip_by_windows (ZORDERINFO* zorder, PMAINWIN pWin){ PZORDERNODE pNode; PMAINWIN pTemp; RECT rcTemp; pNode = zorder->pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if (pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); SubtractClipRect (&pWin->pGCRInfo->crgn, &rcTemp); } pNode = pNode->pNext; }}// clip all windows in specified zorderstatic void clip_windows (ZORDERINFO* zorder, RECT* rcWin){ PZORDERNODE pNode; PGCRINFO pGCRInfo; pNode = zorder->pTopMost; while (pNode) { if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) { pGCRInfo = ((PMAINWIN)(pNode->hWnd))->pGCRInfo; #ifndef _LITE_VERSION pthread_mutex_lock (&pGCRInfo->lock);#endif SubtractClipRect (&pGCRInfo->crgn, rcWin); pGCRInfo->age ++;#ifndef _LITE_VERSION pthread_mutex_unlock (&pGCRInfo->lock);#endif } pNode = pNode->pNext; }}// clip desktopstatic void clip_desktop (RECT* rcWin){#ifndef _LITE_VERSION pthread_mutex_lock (&sg_ScrGCRInfo.lock);#endif SubtractClipRect (&sg_ScrGCRInfo.crgn, rcWin); sg_ScrGCRInfo.age ++;#ifndef _LITE_VERSION pthread_mutex_unlock (&sg_ScrGCRInfo.lock);#endif}// clip all windows under this window.static void clip_windows_under_this (ZORDERINFO* zorder, PMAINWIN pWin, RECT* rcWin){ PZORDERNODE pNode; PGCRINFO pGCRInfo; pNode = zorder->pTopMost; while (pNode->hWnd != (HWND)pWin) pNode = pNode->pNext; pNode = pNode->pNext; while (pNode) { if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) { pGCRInfo = ((PMAINWIN)(pNode->hWnd))->pGCRInfo; #ifndef _LITE_VERSION pthread_mutex_lock (&pGCRInfo->lock);#endif SubtractClipRect (&pGCRInfo->crgn, rcWin); pGCRInfo->age ++;#ifndef _LITE_VERSION pthread_mutex_unlock (&pGCRInfo->lock);#endif } pNode = pNode->pNext; }}static void clip_by_all_above_this (ZORDERINFO* zorder, PMAINWIN pWin){ PZORDERNODE pNode; PGCRINFO pGCRInfo = pWin->pGCRInfo; PMAINWIN pTemp; 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 (&sg_TopMostWinZOrder, pWin); end_clip_window (pWin); clip_windows_under_this (&sg_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 (&sg_TopMostWinZOrder, pWin, &rcWin); clip_windows (&sg_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 (&sg_TopMostWinZOrder, pWin); clip_by_all_above_this (&sg_MainWinZOrder, pWin); end_clip_window (pWin); clip_windows_under_this (&sg_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 (&sg_TopMostWinZOrder, pWin); end_clip_window (pWin); clip_windows_under_this (&sg_TopMostWinZOrder, pWin, &rcWin); clip_windows (&sg_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 = sg_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 == sg_TopMostWinZOrder.pTopMost->hWnd); else return ((HWND)pWin == sg_MainWinZOrder.pTopMost->hWnd);}static PMAINWIN dskChangActiveWindow (PMAINWIN pWin){ PMAINWIN pOldActive; if (__mg_ime_wnd && (__mg_ime_wnd == (HWND)pWin)) return __mg_active_mainwnd; if ((pWin == __mg_active_mainwnd) || (pWin && (pWin->dwExStyle & WS_EX_TOOLWINDOW))) return __mg_active_mainwnd; pOldActive = __mg_active_mainwnd; DesktopSetActiveWindow (pWin); if (pOldActive && (pOldActive->dwStyle & WS_VISIBLE)) { SendAsyncMessage ((HWND)pOldActive, MSG_NCACTIVATE, FALSE, 0); SendNotifyMessage ((HWND)pOldActive, MSG_ACTIVE, FALSE, 0); SendNotifyMessage ((HWND)pOldActive, MSG_KILLFOCUS, (HWND)pWin, 0); } if (pWin) { SendAsyncMessage ((HWND)pWin, MSG_NCACTIVATE, TRUE, 0); SendNotifyMessage ((HWND)pWin, MSG_ACTIVE, TRUE, 0); SendNotifyMessage ((HWND)pWin, MSG_SETFOCUS, (HWND)pOldActive, 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, __mg_active_mainwnd)) 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);#ifndef _LITE_VERSION pthread_mutex_init (&pWin->pGCRInfo->lock, NULL);#endif pWin->pGCRInfo->age = 0; InitClipRgn (&pWin->pGCRInfo->crgn, &sg_FreeClipRectList); IntersectRect (&rcTemp, &rcWin, &g_rcDesktop); SetClipRgn (&pWin->pGCRInfo->crgn, &rcTemp);}static void init_invrgn (PMAINWIN pWin){#ifndef _LITE_VERSION pthread_mutex_init (&pWin->InvRgn.lock, NULL);#endif pWin->InvRgn.frozen = 0; 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){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -