⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 desktop.c

📁 这是一个介绍 linux 编程知识的文章。
💻 C
📖 第 1 页 / 共 5 页
字号:
            free (pNode);
        }
        else {
            while (pNode->pNext) {
                if (pNode->pNext->hWnd == (HWND)pWin) {
                   pTemp = pNode->pNext->pNext;
                   free (pNode->pNext);
                   pNode->pNext = pTemp;
           
                   break;
                }
                pNode = pNode->pNext;
            }
        }
        MainWinZOrder.nNumber--;
    }

    return pActiveMainWnd;
}

static BOOL dskUpdateWindow (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 void dskUpdateAllGCRInfoOnHideMenu ();
static int dskScrollMainWindow (PMAINWIN pWin, PSCROLLWINDOWINFO pswi)
{
    HDC hdc;
    RECT rcClient, rcInter, rcInvalid, rcScroll;
    PZORDERNODE pNode;
    PMAINWIN pTemp;
    BOOL inved = FALSE;

    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);
        
    hdc = GetClientDC ((HWND)pWin);
    SelectClipRect (hdc, &rcScroll);
    BitBlt (hdc, 0, 0, rcClient.right, rcClient.bottom,
            hdc, pswi->iOffx, pswi->iOffy, 0);
    ReleaseDC (hdc);

    if (!(pWin->dwExStyle & WS_EX_TOPMOST)) {
        WindowToScreen ((HWND)pWin, &rcClient.left, &rcClient.top);
        WindowToScreen ((HWND)pWin, &rcClient.right, &rcClient.bottom);

        pNode = TopMostWinZOrder.pTopMost;
        while (pNode) {

            pTemp = (PMAINWIN)(pNode->hWnd);
            if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE) {

                if (IntersectRect (&rcInter, 
                            &rcClient, (PRECT)(&pTemp->left))) {
                            
                    ScreenToClient ((HWND)pWin, 
                        &rcInter.left, &rcInter.top);
                    ScreenToClient ((HWND)pWin, 
                        &rcInter.right, &rcInter.bottom);
                    
                    if (pswi->iOffx < 0) {
                        rcInter.right = rcInter.left;
                        rcInter.left += pswi->iOffx;
                    }
                    else if (pswi->iOffx > 0) {
                        rcInter.left = rcInter.right;
                        rcInter.right += pswi->iOffx;
                    }

                    if (pswi->iOffy < 0) {
                        rcInter.bottom = rcInter.top;
                        rcInter.top += pswi->iOffy;
                    }
                    else if (pswi->iOffy > 0) {
                        rcInter.top = rcInter.bottom;
                        rcInter.bottom += pswi->iOffy;
                    }

                    rcInter.right += 2;
                    rcInter.bottom += 2;

                    wndInvalidateRect ((HWND)pWin, &rcInter, TRUE);
                    inved = TRUE;
                }
            }

            pNode = pNode->pNext;
        }
    }

    if (pswi->iOffx < 0) {
        rcInvalid.top = 0;
        rcInvalid.bottom = pWin->cb - pWin->ct;
        rcInvalid.right = pWin->cr - pWin->cl;
        rcInvalid.left = rcInvalid.right + pswi->iOffx;

        wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
        inved = TRUE;
    }
    else if (pswi->iOffx > 0) {
        rcInvalid.top = 0;
        rcInvalid.bottom = pWin->cb - pWin->ct;
        rcInvalid.left = 0;
        rcInvalid.right = pswi->iOffx;

        wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
        inved = TRUE;
    }
    
    if (pswi->iOffy < 0) {
        rcInvalid.left = 0;
        rcInvalid.right = pWin->cr - pWin->cl;
        rcInvalid.bottom = pWin->cb - pWin->ct;
        rcInvalid.top = rcInvalid.bottom + pswi->iOffy;

        wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
        inved = TRUE;
    }
    else if (pswi->iOffy > 0) {
        rcInvalid.left = 0;
        rcInvalid.right = pWin->cr - pWin->cl;
        rcInvalid.top = 0;
        rcInvalid.bottom = pswi->iOffy;

        wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
        inved = TRUE;
    }

    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;
    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, &sg_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 (dskUpdateWindow (pWin, rcInv + i, &oldWinRect, &oldClientRect))
            SendAsyncMessage ((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) {
                dskUpdateWindow (pWin, (PRECT)(&pTemp->left), 
                        &oldWinRect, &oldClientRect);
//                if (dskUpdateWindow (pWin, (PRECT)(&pTemp->left), 
//                        &oldWinRect, &oldClientRect))
//                    SendAsyncMessage ((HWND)pWin, MSG_PAINT, 0, 0);
            }

            pNode = pNode->pNext;
        }

    }
   

    // when other windows' rect 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)
                    dskUpdateWindow (pTemp, rc + i, 
                            (PRECT)(&pTemp->left), (PRECT)(&pTemp->cl));
//                    if (dskUpdateWindow (pTemp, rc + i, 
//                            (PRECT)(&pTemp->left), (PRECT)(&pTemp->cl)))
//                        SendAsyncMessage ((HWND)pTemp, MSG_PAINT, 0, 0);

                pNode = pNode->pNext;
            }
        }
        
        pNode = MainWinZOrder.pTopMost;
        while (pNode) {
    
            pTemp = (PMAINWIN)(pNode->hWnd);
            if (pTemp != pWin && pTemp->dwStyle & WS_VISIBLE)
                dskUpdateWindow (pTemp, rc + i, 
                        (PRECT)(&pTemp->left), (PRECT)(&pTemp->cl));

            pNode = pNode->pNext;
        }

        IntersectRect (&rcInter, rc + i, &sg_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))
        { };
    }
}

static void dskUpdateAllGCRInfoOnShowMenu (RECT* prc)
{
    PZORDERNODE pNode;
    PGCRINFO pGCRInfo;
    
    // update all main windows' global clip region
    
    pNode = TopMostWinZOrder.pTopMost;
    while (pNode)
    {
        if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {
            pGCRInfo = &((PMAINWIN)(pNode->hWnd))->GCRInfo;
        
            pthread_mutex_lock (&pGCRInfo->lock);
            SubtractClipRect (&pGCRInfo->crgn, prc);
            pGCRInfo->age ++;
            pthread_mutex_unlock (&pGCRInfo->lock);
        }

        pNode = pNode->pNext;
    }

    pNode = MainWinZOrder.pTopMost;
    while (pNode)
    {
        if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {
            pGCRInfo = &((PMAINWIN)(pNode->hWnd))->GCRInfo;
        
            pthread_mutex_lock (&pGCRInfo->lock);
            SubtractClipRect (&pGCRInfo->crgn, prc);
            pGCRInfo->age ++;
            pthread_mutex_unlock (&pGCRInfo->lock);
        }

        pNode = pNode->pNext;
    }
    
    // update desktop's global clip region.
    pthread_mutex_lock (&sg_ScrGCRInfo.lock);
    SubtractClipRect (&sg_ScrGCRInfo.crgn, prc);
    sg_ScrGCRInfo.age ++;
    pthread_mutex_unlock (&sg_ScrGCRInfo.lock);
}

static void dskUpdateAllGCRInfoOnHideMenu ()
{
    PZORDERNODE pNode, pAffected;
    PGCRINFO pGCRInfo;
    RECT     rcTemp;
    PMAINWIN pTemp;
    PTRACKMENUINFO ptmi;
    
    pAffected = TopMostWinZOrder.pTopMost;
    while (pAffected){

        pTemp = (PMAINWIN)(pAffected->hWnd);
        if (pTemp->dwStyle & WS_VISIBLE) {

            pGCRInfo = &pTemp->GCRInfo;
            pthread_mutex_lock (&pGCRInfo->lock);
            IntersectRect (&rcTemp, (PRECT)(&pTemp->left), &sg_rcScr);
            SetClipRgn (&pGCRInfo->crgn, &rcTemp);

            pNode = TopMostWinZOrder.pTopMost;
            while (pNode != pAffected) {

                pTemp = (PMAINWIN)(pNode->hWnd);
                if (pTemp->dwStyle & WS_VISIBLE)
                    SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pTemp->left));

                pNode = pNode->pNext;
            }

            ptmi = sg_ptmi;
            while (ptmi) {
                SubtractClipRect (&pGCRInfo->crgn, &ptmi->rc);
                ptmi = ptmi->next;
            }

            pGCRInfo->age ++;
            pthread_mutex_unlock (&pGCRInfo->lock);
        }

           pAffected = pAffected->pNext;
    }
    
    pAffected = MainWinZOrder.pTopMost;
    while (pAffected){

        pTemp = (PMAINWIN)(pAffected->hWnd);
        if (pTemp->dwStyle & WS_VISIBLE) {

            pGCRInfo = &pTemp->GCRInfo;
            pthread_mutex_lock (&pGCRInfo->lock);
            IntersectRect (&rcTemp, (PRECT)(&pTemp->left), &sg_rcScr);
            SetClipRgn (&pGCRInfo->crgn, &rcTemp);

            pNode = TopMostWinZOrder.pTopMost;
            while (pNode) {

                pTemp = (PMAINWIN)(pNode->hWnd);
                if (pTemp->dwStyle & WS_VISIBLE)
                    SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pTemp->left));

                pNode = pNode->pNext;
            }
            
            pNode = MainWinZOrder.pTopMost;
            while (pNode != pAffected) {

                pTemp = (PMAINWIN)(pNode->hWnd);
                if (pTemp->dwStyle & WS_VISIBLE)
                    SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pTemp->left));

                pNode = pNode->pNext;
            }

            ptmi = sg_ptmi;
            while (ptmi) {
                SubtractClipRect (&pGCRInfo->crgn, &ptmi->rc);
                ptmi = ptmi->next;
            }

            pGCRInfo->age ++;
            pthread_mutex_unlock (&pGCRInfo->lock);
        }

           pAffected = pAffected->pNext;
    }

    // update desktop's global clip region.
    pthread_mutex_lock (&sg_ScrGCRInfo.lock);
    SetClipRgn (&sg_ScrGCRInfo.crgn, &sg_rcScr);
    pNode = TopMostWinZOrder.pTopMost;
    while (pNode) {

        pTemp = (PMAINWIN)(pNode->hWnd);
        if (pTemp->dwStyle & WS_VISIBLE)
            SubtractClipRect (&sg_ScrGCRInfo.crgn, (PRECT)(&pTemp->left));

        pNode = pNode->pNext;
    }
    pNode = MainWinZOrder.pTopMost;
    while (pNode) {
    
        pTemp = (PMAINWIN)(pNode->hWnd);

        if (pTemp->dwStyle & WS_VISIBLE)
            SubtractClipRect (&sg_ScrGCRInfo.crgn, (PRECT)(&pTemp->left));

        pNode = pNode->pNext;
    }
    ptmi = sg_ptmi;
    while (ptmi) {
        SubtractClipRect (&sg_ScrGCRInfo.crgn, &ptmi->rc);
        ptmi = ptmi->next;
    }
    sg_ScrGCRInfo.age ++;
    pthread_mutex_unlock (&sg_ScrGCRInfo.lock);
}

// 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;
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -