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

📄 desktop-comm.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                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) {

            start_clip_window (pTemp);
            dskGetWindowRectInScreen (pTemp, &rcTemp);
            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;

    start_clip_window (pWin);
    pWin->dwStyle &= ~WS_VISIBLE;
    dskGetWindowRectInScreen (pWin, &rcWin);
    recalc_windows_under_this (&sg_MainWinZOrder, pWin, &rcWin);
    recalc_desktop (NULL);
    end_clip_window (pWin);

    IntersectRect (&rcTemp, &rcWin, &g_rcDesktop);
    DesktopWinProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcTemp));

#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
    if (mgIsServer)
        scr_del_clip_rect (pWin->scr_idx);
#endif

}

// this is a top most window
static void dskUpdateGCRInfoOnHideMainWinEx(MAINWIN* pWin)
{
    RECT rcWin, rcTemp;
    
    start_clip_window (pWin);
    pWin->dwStyle &= ~WS_VISIBLE;
    dskGetWindowRectInScreen (pWin, &rcWin);
    recalc_windows_under_this (&sg_TopMostWinZOrder, pWin, &rcWin);
    recalc_windows (&sg_MainWinZOrder, &rcWin);
    recalc_desktop (NULL);
    end_clip_window (pWin);

    IntersectRect (&rcTemp, &rcWin, &g_rcDesktop);
    DesktopWinProc (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, (LPARAM)(&rcTemp));

#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
    if (mgIsServer)
        scr_del_clip_rect (pWin->scr_idx);
#endif
}

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)
{
    PZORDERNODE pAffected;
    RECT     rcTemp;
    PMAINWIN pTemp;
    PTRACKMENUINFO ptmi;
    
    pAffected = sg_TopMostWinZOrder.pTopMost;
    while (pAffected){

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

            start_clip_window (pTemp);
            dskGetWindowRectInScreen (pTemp, &rcTemp);
            reset_window (pTemp, &rcTemp);
            clip_by_all_above_this (&sg_TopMostWinZOrder, pTemp);
            end_clip_window (pTemp);

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

        }

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

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

            start_clip_window (pTemp);
            dskGetWindowRectInScreen (pTemp, &rcTemp);
            reset_window (pTemp, &rcTemp);
            clip_by_windows (&sg_TopMostWinZOrder, pTemp);
            clip_by_all_above_this (&sg_MainWinZOrder, pTemp);
            end_clip_window (pTemp);

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

        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)
        ptmi->scr_idx = scr_add_clip_rect (&ptmi->rc);
#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 ();

#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
    if (mgIsServer)
        scr_del_clip_rect (ptmi->scr_idx);
#endif

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

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

⌨️ 快捷键说明

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