📄 desktop.c
字号:
}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; dskClientToScreen (pWin, &rcClient, &rcScreen); if (pswi->rc1) IntersectRect (&rcScroll, pswi->rc1, &rcClient); else rcScroll = rcClient; if (pswi->rc2) IntersectRect (&rcScroll, pswi->rc2, &rcScroll); 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 (!IntersectRect (&rcMove, &pcrc->rc, &rcScreen)) { pcrc = pcrc->next; continue; } 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, hMemDC; 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 nInvCount = SubtractRect (rcInv, &src, &g_rcScr); // save window rect. hdc = GetDC ((HWND)pWin); hMemDC = CreateCompatibleDC (hdc); BitBlt (hdc, 0, 0, RECTW(oldWinRect), RECTH(oldWinRect), hMemDC, 0, 0, 0); ReleaseDC (hdc); // Update all affected windows' GCR info. SendAsyncMessage ((HWND)pWin, MSG_CHANGESIZE, (WPARAM)(prcExpect), 0); dskUpdateAllGCRInfoOnHideMenu (); // put window rect. hdc = GetDC ((HWND)pWin);// ScreenCopy (oldWinRect.left, oldWinRect.top, hdc, 0, 0); BitBlt (hMemDC, 0, 0, RECTW (oldWinRect), RECTH (oldWinRect), hdc, 0, 0, 0); DeleteCompatibleDC (hMemDC); ReleaseDC (hdc); // when old window rect out of date. for (i=0; i<nInvCount; i++) if (dskUpdateOldMainWindow (pWin, rcInv + i, &oldWinRect, &oldClientRect)) PostMessage ((HWND)pWin, MSG_PAINT, 0, 0); if (!(pWin->dwExStyle & WS_EX_TOPMOST)) { pNode = 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 = 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 = 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_rcScr); DesktopProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcInter)); } { MSG msg; // remove any mouse moving messages in mesasge queue. while (PeekPostMessage (&msg, HWND_DESKTOP, MSG_MOUSEMOVE, MSG_MOUSEMOVE, PM_REMOVE)) { }; }}/*********************** Hook support ****************************************/#define NR_KEYHOOK 5#define NR_MOUSEHOOK 5#define MIN_MHHOOK NR_KEYHOOK#define MAX_MHHOOK (NR_KEYHOOK + NR_MOUSEHOOK - 1)static KEYHOOK keyhook [NR_KEYHOOK];static MOUSEHOOK mousehook[NR_MOUSEHOOK];static HHOOK dskRegisterKeyHook (HWND hWnd, KEYMSGHOOK hook){ int i; for (i = 0; i<NR_KEYHOOK; i++) { if (keyhook [i].hWnd == HWND_DESKTOP) { keyhook [i].hWnd = hWnd; keyhook [i].hook = hook; return (HHOOK)i; } } return HHOOK_INVALID;}static HHOOK dskRegisterMouseHook (HWND hWnd, MOUSEMSGHOOK hook){ int i; for (i = 0; i<NR_MOUSEHOOK; i++) { if (mousehook [i].hWnd == HWND_DESKTOP) { mousehook [i].hWnd = hWnd; mousehook [i].hook = hook; return (HHOOK)(i + MIN_MHHOOK); } } return HHOOK_INVALID;}static int dskUnregisterHook (HHOOK hHook){ int i; if (hHook < 0 || hHook > MAX_MHHOOK) return HHOOK_INVALID; if (hHook >= MIN_MHHOOK) { i = hHook - MIN_MHHOOK; if (mousehook [i].hWnd == HWND_DESKTOP) return HHOOK_INVALID; mousehook [i].hWnd = HWND_DESKTOP; mousehook [i].hook = NULL; } else { i = hHook; if (keyhook [i].hWnd == HWND_DESKTOP) return HHOOK_INVALID; keyhook [i].hWnd = HWND_DESKTOP; keyhook [i].hook = NULL; } return HOOK_OK;}static void dskHandleKeyHooks (HWND hWnd, int message, WPARAM wParam, LPARAM lParam){ int i; for (i = 0; i < NR_KEYHOOK; i++) { if (keyhook [i].hWnd != HWND_DESKTOP) { (*(keyhook [i].hook)) (keyhook [i].hWnd, message, wParam, lParam); } }}static void dskHandleMouseHooks (HWND hWnd, int message, WPARAM wParam, LPARAM lParam){ int i; for (i = 0; i < NR_MOUSEHOOK; i++) { if (mousehook [i].hWnd != HWND_DESKTOP) { (*(mousehook [i].hook)) (mousehook [i].hWnd, message, wParam, lParam); } }}/*********************** Desktop window support ******************************/static PMAINWIN GetWinUnderPointer (int x, int y){ PZORDERNODE pNode; PMAINWIN pTemp; RECT rcTemp; pNode = 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 = 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 (-1); break; } return 0;}void GUIAPI ExitGUISafely (int exitcode){ TerminateGUI ((exitcode > 0) ? -exitcode : exitcode); exit (exitcode);}static int KeyMessageHandler (int message, int scancode, DWORD status){ static int altdown = 0; static int modal = 0; PMAINWIN pNextWin; if ((message == MSG_KEYDOWN) && (status & KS_ALT) && (status & KS_CTRL)) return HandleSpecialKey (scancode); if (scancode == SCANCODE_LEFTALT || scancode == SCANCODE_RIGHTALT) { if (message == MSG_KEYDOWN) { altdown = 1; return 0; } else { altdown = 0; if (modal == 1) { modal = 0; return 0; } } } if (altdown) { if (message == MSG_KEYDOWN) { if( scancode == SCANCODE_TAB) { modal = 1; if (sg_ptmi) dskForceCloseMenu (); pNextWin = dskGetNextVisibleMainWindow (pActiveMainWnd); dskMoveToTopMost (pNextWin, TRUE); return 0; } else if (scancode == SCANCODE_ESCAPE) { modal = 1; if (pActiveMainWnd) {#ifdef _DEBUG fprintf (stderr, "Will be Closed: %p.\n", pActiveMainWnd);#endif PostMessage ((HWND)pActiveMainWnd, MSG_CLOSE, 0, 0); return 0; } } } else if (modal == 1) return 0; } if (scancode == SCANCODE_F10 || scancode == SCANCODE_LEFTALT || scancode == SCANCODE_RIGHTALT || altdown) { if (message == MSG_KEYDOWN) message = MSG_SYSKEYDOWN; else { message = MSG_SYSKEYUP; altdown = 0; } } else if (sg_hIMEWnd != HWND_DESKTOP) { if (pActiveMainWnd && (pActiveMainWnd->dwExStyle & WS_EX_IMECOMPOSE)) { dskHandleKeyHooks (sg_hIMEWnd, message, (WPARAM)scancode, (LPARAM)status); PostMessage (sg_hIMEWnd, message, (WPARAM)scancode, (LPARAM)status); return 0; } } if (pActiveMainWnd) { dskHandleKeyHooks ((HWND)pActiveMainWnd, message, (WPARAM)scancode, (LPARAM)status); PostMessage ((HWND)pActiveMainWnd, message, (WPARAM)scancode, (LPARAM)status); } else { dskHandleKeyHooks (HWND_DESKTOP, message, (WPARAM)scancode, (LPARAM)status); SendMessage (HWND_DESKTOP, MSG_DT_KEYOFF + message, (WPARAM)scancode, (LPARAM)status); } return 0;}static int MouseMessageHandler (int message, WPARAM flags, int x, int y){ static PMAINWIN pOldUnderPointer = NULL; static PMAINWIN pCaptured = (void*)HWND_INVALID; PMAINWIN pUnderPointer; PMAINWIN pCtrlPtrIn; int CapHitCode = HT_UNKNOWN; int UndHitCode = HT_UNKNOWN; int cx = 0, cy = 0; if (message == MSG_WINDOWCHANGED) { pCaptured = (void*) HWND_INVALID; CapHitCode = HT_UNKNOWN; pOldUnderPointer = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -