📄 desktop-comm.c
字号:
PZORDERNODE pAffected; RECT rcTemp; PMAINWIN pTemp; PTRACKMENUINFO ptmi; pAffected = sg_TopMostWinZOrder.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_all_above_this (&sg_TopMostWinZOrder, pTemp); ptmi = __mg_ptmi; while (ptmi) { SubtractClipRect (&pTemp->pGCRInfo->crgn, &ptmi->rc); ptmi = ptmi->next; } end_clip_window (pTemp); } pAffected = pAffected->pNext; } pAffected = sg_MainWinZOrder.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); ptmi = __mg_ptmi; while (ptmi) { SubtractClipRect (&pTemp->pGCRInfo->crgn, &ptmi->rc); ptmi = ptmi->next; } end_clip_window (pTemp); } pAffected = pAffected->pNext; } recalc_desktop (__mg_ptmi);}// call back proc of tracking menu.// defined in Menu module.int PopupMenuTrackProc (PTRACKMENUINFO ptmi, int message, WPARAM wParam, LPARAM lParam);static int dskTrackPopupMenu(PTRACKMENUINFO ptmi){ PTRACKMENUINFO plast; if (__mg_ptmi) { plast = __mg_ptmi; while (plast->next) { plast = plast->next; } plast->next = ptmi; ptmi->prev = plast; ptmi->next = NULL; } else { __mg_ptmi = ptmi; ptmi->next = NULL; ptmi->prev = NULL;#if defined(_LITE_VERSION) && !defined(_STAND_ALONE) if (mgIsServer) { OnlyMeCanDraw (); }#endif } PopupMenuTrackProc (ptmi, MSG_INITMENU, 0, 0); // Update all main windows' GCR info. dskUpdateAllGCRInfoOnShowMenu (&ptmi->rc); PopupMenuTrackProc (ptmi, MSG_SHOWMENU, 0, 0); return 0;}static int dskEndTrackMenu (PTRACKMENUINFO ptmi){ PZORDERNODE pNode; PMAINWIN pTemp; PTRACKMENUINFO plast; RECT rcInvalid, rcTemp; if (__mg_ptmi == ptmi) { __mg_ptmi = NULL; } else { plast = __mg_ptmi; while (plast->next) { plast = plast->next; } plast->prev->next = NULL; } // Update all main windows' GCR info. dskUpdateAllGCRInfoOnHideMenu (); PopupMenuTrackProc (ptmi, MSG_HIDEMENU, 0, 0); // Invalidate rect of affected main window. pNode = sg_TopMostWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if (pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); if (IntersectRect (&rcInvalid, &ptmi->rc, &rcTemp)) { dskScreenToClient (pTemp, &rcInvalid, &rcInvalid); InvalidateRect ((HWND)pTemp, &rcInvalid, FALSE); } } pNode = pNode->pNext; } pNode = sg_MainWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); pTemp = (PMAINWIN)(pNode->hWnd); if (pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); if (IntersectRect (&rcInvalid, &ptmi->rc, &rcTemp)) { dskScreenToClient (pTemp, &rcInvalid, &rcInvalid); InvalidateRect ((HWND)pTemp, &rcInvalid, FALSE); } } pNode = pNode->pNext; } PopupMenuTrackProc (ptmi, MSG_ENDTRACKMENU, 0, 0);#if defined(_LITE_VERSION) && !defined(_STAND_ALONE) if (__mg_ptmi == NULL && mgIsServer) { ClientCanDrawNowEx (FALSE, NULL); }#endif return __mg_ptmi == ptmi;}static BOOL dskForceCloseMenu (void){ if (__mg_ptmi == NULL) return FALSE; SendNotifyMessage (__mg_ptmi->hwnd, MSG_DEACTIVEMENU, (WPARAM)__mg_ptmi->pmb, (LPARAM)__mg_ptmi->pmi); PopupMenuTrackProc (__mg_ptmi, MSG_CLOSEMENU, 0, 0); __mg_ptmi = NULL; // Update all main windows' GCR info. dskUpdateAllGCRInfoOnHideMenu (); return TRUE;}static BOOL dskUpdateOldMainWindow (PMAINWIN pWin, const RECT* prcInv, const RECT* prcWin, const RECT* prcClient){ RECT rcInter; if (IntersectRect (&rcInter, prcInv, prcWin)) { rcInter.left -= prcWin->left; rcInter.top -= prcWin->top; rcInter.right -= prcWin->left; rcInter.bottom -= prcWin->top; SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, (LPARAM)(&rcInter)); if (IntersectRect (&rcInter, prcInv, prcClient)) { rcInter.left -= prcClient->left; rcInter.top -= prcClient->top; rcInter.right -= prcClient->left; rcInter.bottom -= prcClient->top; InvalidateRect ((HWND)pWin, &rcInter, TRUE); return TRUE; } } return FALSE;}static BOOL dskUpdateWindow (PMAINWIN pWin, const RECT* prcInv, const RECT* prcWin, const RECT* prcClient){ RECT rcInter, rcInv; if (IntersectRect (&rcInter, prcInv, prcWin)) { dskScreenToWindow (pWin, &rcInter, &rcInv); SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, (LPARAM)(&rcInv)); if (IntersectRect (&rcInter, prcInv, prcClient)) { dskScreenToClient (pWin, &rcInter, &rcInv); InvalidateRect ((HWND)pWin, &rcInv, TRUE); return TRUE; } } return FALSE;}static int dskScrollMainWindow (PMAINWIN pWin, PSCROLLWINDOWINFO pswi){ HDC hdc; RECT rcClient, rcScreen, rcInvalid, rcScroll; BOOL inved = FALSE; PCLIPRECT pcrc; rcClient.left = 0; rcClient.top = 0; rcClient.right = pWin->cr - pWin->cl; rcClient.bottom = pWin->cb - pWin->ct; if (pswi->rc1) IntersectRect (&rcScroll, pswi->rc1, &rcClient); else rcScroll = rcClient; if (pswi->rc2) IntersectRect (&rcScroll, pswi->rc2, &rcScroll); dskClientToScreen (pWin, &rcScroll, &rcScreen); hdc = GetClientDC ((HWND)pWin); pcrc = GetGCRgnInfo ((HWND)pWin)->crgn.head; while (pcrc) { RECT rcMove; if (!IntersectRect (&rcMove, &pcrc->rc, &rcScreen)) { pcrc = pcrc->next; continue; } dskScreenToClient (pWin, &rcMove, &rcMove); if (!IntersectRect (&rcMove, &rcMove, &rcScroll)) { pcrc = pcrc->next; continue; } SelectClipRect (hdc, &rcMove); BitBlt (hdc, rcMove.left, rcMove.top, rcMove.right - rcMove.left, rcMove.bottom - rcMove.top, hdc, pswi->iOffx + rcMove.left, pswi->iOffy + rcMove.top, 0); pcrc = pcrc->next; } ReleaseDC (hdc); pcrc = GetGCRgnInfo ((HWND)pWin)->crgn.head; while (pcrc) { RECT rcMove;#if defined(_LITE_VERSION) && !defined(_STAND_ALONE) RECT rcTemp; IntersectRect (&rcTemp, &g_rcDesktop, (const RECT*)&SHAREDRES_CLI_SCR_LX); if (IntersectRect (&rcTemp, &pcrc->rc, &rcTemp)) { if (!IntersectRect (&rcMove, &rcTemp, &rcScreen)) { pcrc = pcrc->next; continue; } } else continue;#else if (!IntersectRect (&rcMove, &pcrc->rc, &rcScreen)) { pcrc = pcrc->next; continue; }#endif dskScreenToClient (pWin, &rcMove, &rcMove); rcInvalid = rcMove; if (pswi->iOffx < 0) { rcInvalid.left = rcInvalid.right + pswi->iOffx; wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE); inved = TRUE; } else if (pswi->iOffx > 0) { rcInvalid.right = rcInvalid.left + pswi->iOffx; wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE); inved = TRUE; } rcInvalid = rcMove; if (pswi->iOffy < 0) { rcInvalid.top = rcInvalid.bottom + pswi->iOffy; wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE); inved = TRUE; } else if (pswi->iOffy > 0) { rcInvalid.bottom = rcInvalid.top + pswi->iOffy; wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE); inved = TRUE; } pcrc = pcrc->next; } if (inved) PostMessage ((HWND)pWin, MSG_PAINT, 0, 0); return 0;}static void dskMoveMainWindow (PMAINWIN pWin, const RECT* prcExpect){ RECT oldWinRect, oldClientRect, src; // old window rect. RECT rc[4], rcInv[4]; // invalid rects. RECT rcInter, rcTemp, rcTempClient; int nCount, nInvCount; // number of invalid rects. int i; PZORDERNODE pNode; PMAINWIN pTemp; HDC hdc; memcpy (&src, &pWin->left, sizeof (RECT)); memcpy (&oldClientRect, &pWin->cl, sizeof (RECT)); oldWinRect = src; // calculate invalid rect of other windows nCount = SubtractRect (rc, &src, prcExpect); // calculate invalid rect of moving window#if defined(_LITE_VERSION) && !defined(_STAND_ALONE) IntersectRect (&rcInter, &g_rcDesktop, (const RECT*)&SHAREDRES_CLI_SCR_LX); nInvCount = SubtractRect (rcInv, &src, &rcInter);#else nInvCount = SubtractRect (rcInv, &src, &g_rcScr);#endif // Update all affected windows' GCR info. SendAsyncMessage ((HWND)pWin, MSG_CHANGESIZE, (WPARAM)(prcExpect), 0); dskUpdateAllGCRInfoOnHideMenu (); // Move window content. hdc = GetDC ((HWND)pWin); BitBlt (HDC_SCREEN, oldWinRect.left, oldWinRect.top, RECTW (oldWinRect), RECTH (oldWinRect), hdc, 0, 0, 0); ReleaseDC (hdc); // when old window rect out of date. for (i=0; i<nInvCount; i++) dskUpdateOldMainWindow (pWin, rcInv + i, &oldWinRect, &oldClientRect); if (!(pWin->dwExStyle & WS_EX_TOPMOST)) { pNode = sg_TopMostWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); dskUpdateOldMainWindow (pWin, &rcTemp, &oldWinRect, &oldClientRect); } pNode = pNode->pNext; } } // when other windows run out of date. for (i=0; i<nCount; i++) { if (pWin->dwExStyle & WS_EX_TOPMOST) { pNode = sg_TopMostWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); dskGetClientRectInScreen (pTemp, &rcTempClient); dskUpdateWindow (pTemp, rc + i, &rcTemp, &rcTempClient); } pNode = pNode->pNext; } } pNode = sg_MainWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)(pNode->hWnd); if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE) { dskGetWindowRectInScreen (pTemp, &rcTemp); dskGetClientRectInScreen (pTemp, &rcTempClient); dskUpdateWindow (pTemp, rc + i, &rcTemp, &rcTempClient); } pNode = pNode->pNext; } IntersectRect (&rcInter, rc + i, &g_rcDesktop); DesktopWinProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcInter)); } { MSG msg; // remove any mouse moving messages in mesasge queue. while (PeekPostMessage (&msg, (HWND)pWin, MSG_MOUSEMOVE, MSG_MOUSEMOVE, PM_REMOVE)) { }; }}/*********************** Hook support ****************************************/static HOOKINFO keyhook;static HOOKINFO mousehook;static MSGHOOK dskRegisterKeyHook (void* context, MSGHOOK hook){ MSGHOOK old_hook = keyhook.hook; keyhook.context = context; keyhook.hook = hook; return old_hook;}static MSGHOOK dskRegisterMouseHook (void* context, MSGHOOK hook){ MSGHOOK old_hook = mousehook.hook; mousehook.context = context; mousehook.hook = hook; return old_hook;}static int dskHandleKeyHooks (HWND dst_wnd, int message, WPARAM wParam, LPARAM lParam){ int ret = HOOK_GOON; if (keyhook.hook) { ret = keyhook.hook (keyhook.context, dst_wnd, message, wParam, lParam); } return ret;}static int dskHandleMouseHooks (HWND dst_wnd, int message, WPARAM wParam, LPARAM lParam){ int ret = HOOK_GOON; if (mousehook.hook) { ret = mousehook.hook (mousehook.context, dst_wnd, message, wParam, lParam); } return ret;}/*********************** Desktop window support ******************************/PMAINWIN GetMainWindowPtrUnderPoint (int x, int y){ PZORDERNODE pNode; PMAINWIN pTemp; RECT rcTemp; pNode = sg_TopMostWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)pNode->hWnd; dskGetWindowRectInScreen (pTemp, &rcTemp); if (PtInRect (&rcTemp, x, y) && (pTemp->dwStyle & WS_VISIBLE)) { return pTemp; } pNode = pNode->pNext; } pNode = sg_MainWinZOrder.pTopMost; while (pNode) { pTemp = (PMAINWIN)pNode->hWnd; dskGetWindowRectInScreen (pTemp, &rcTemp); if (PtInRect (&rcTemp, x, y) && (pTemp->dwStyle & WS_VISIBLE)) { return pTemp; } pNode = pNode->pNext; } return NULL;}static int HandleSpecialKey (int scancode){ switch (scancode) { case SCANCODE_BACKSPACE: TerminateGUI (-1); exit (2); break; } return 0;}void GUIAPI ExitGUISafely (int exitcode){ TerminateGUI ((exitcode > 0) ? -exitcode : exitcode); exit (2);}static int KeyMessageHandler (int message, int scancode, DWORD status){ PMAINWIN pNextWin; static int mg_altdown = 0; static int mg_modal = 0; if ((message == MSG_KEYDOWN) && (status & KS_ALT) && (status & KS_CTRL)) return HandleSpecialKey (scancode); if (scancode == SCANCODE_LEFTALT || scancode == SCANCODE_RIGHTALT) { if (message == MSG_KEYDOWN) { mg_altdown = 1; return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -