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

📄 desktop-comm.c

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

    pNode = zorder->pTopMost;
    if (pNode->hWnd == (HWND)pWin) {
        zorder->pTopMost = pNode->pNext;
    }
    else {
        while (pNode->pNext) {
            if (pNode->pNext->hWnd == (HWND)pWin) {
               pTemp = pNode->pNext->pNext;
               pNode->pNext = pTemp;
       
               break;
            }
            pNode = pNode->pNext;
        }
    }
    zorder->nNumber--;
}

// this funciton add the new main window to the main window list.
// if new main window is a visible window,
// this new main window becomes the active window and this function
// return the old main window.
// otherwise, return NULL.
static PMAINWIN dskAddNewMainWindow (PMAINWIN pWin, PZORDERNODE pNode)
{
    // Handle main window hosting.
    if (pWin->pHosting)
        dskAddNewHostedMainWindow (pWin->pHosting, pWin);
    
    // Init Global Clip Region info.
    init_gcrinfo (pWin);

    // Init Invalid Region info.
    init_invrgn (pWin);

    // Update Z Order info.
    pNode->hWnd = (HWND)pWin;
    if (pWin->dwExStyle & WS_EX_TOPMOST)
        add_new_window (&sg_TopMostWinZOrder, pNode);
    else
        add_new_window (&sg_MainWinZOrder, pNode);

    // show and active this main window.
    if ( pWin->dwStyle & WS_VISIBLE ) {

        if (pWin->dwExStyle & WS_EX_TOPMOST)
            dskUpdateGCRInfoOnShowNewMainWinEx (pWin);
        else
            dskUpdateGCRInfoOnShowNewMainWin (pWin);
        
        SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, 0);

        SendNotifyMessage ((HWND)pWin, MSG_SHOWWINDOW, SW_SHOWNORMAL, 0);

        InvalidateRect ((HWND)pWin, NULL, TRUE);

        return dskChangActiveWindow (pWin);
    }

    return NULL;
}

// This function defined in gui/window.c
BOOL wndInvalidateRect (HWND hWnd, const RECT* prc, BOOL bEraseBkgnd);

// this function called when a visible main win becomes as a top most window.
// this is a normal main window.
static BOOL update_on_change_topmost (ZORDERINFO* zorder, PMAINWIN pNew, RECT* rcNew)
{
    PGCRINFO pGCRInfo;
    PZORDERNODE pNode;
    RECT rcInter;
    RECT rcOther;
    BOOL inved = FALSE;

    // clip all main windows which will covered by this new top most window
    pNode = zorder->pTopMost;
    while (pNode)
    {
        if ( pNode->hWnd == (HWND)pNew )
            break;

        if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {
        
            dskGetWindowRectInScreen ((PMAINWIN)pNode->hWnd, &rcOther);
            if (IntersectRect(&rcInter, rcNew, &rcOther)) {
                pGCRInfo = ((PMAINWIN)(pNode->hWnd))->pGCRInfo;
        
#ifndef _LITE_VERSION
                pthread_mutex_lock (&pGCRInfo->lock);
#endif
                SubtractClipRect (&pGCRInfo->crgn, rcNew);
                pGCRInfo->age ++;
#ifndef _LITE_VERSION
                pthread_mutex_unlock (&pGCRInfo->lock);
#endif

                // update this window's client area.
                dskScreenToClient (pNew, &rcInter, &rcInter);
                wndInvalidateRect ((HWND)pNew, &rcInter, TRUE);
                inved = TRUE;
            }
        }

        pNode = pNode->pNext;
    }

    return inved;
}

static void dskUpdateGCRInfoOnChangeTopMost(PMAINWIN pNew)
{
    RECT rcNew;

    dskGetWindowRectInScreen (pNew, &rcNew);

    if (update_on_change_topmost (&sg_MainWinZOrder, pNew, &rcNew));
        PostMessage ((HWND)pNew, MSG_PAINT, 0, 0);
}

// this is a top most window
static void dskUpdateGCRInfoOnChangeTopMostEx (PMAINWIN pNew)
{
    RECT rcNew;

    dskGetWindowRectInScreen (pNew, &rcNew);

    if (update_on_change_topmost (&sg_TopMostWinZOrder, pNew, &rcNew))
        PostMessage ((HWND)pNew, MSG_PAINT, 0, 0);
}

static void move_to_top (ZORDERINFO* zorder, PMAINWIN pWin)
{
    PZORDERNODE pNode, pTemp;

    pNode = zorder->pTopMost;
    if (pNode->hWnd != (HWND)pWin) {
        while (pNode->pNext) {
            if (pNode->pNext->hWnd == (HWND)pWin) {
               pTemp = pNode->pNext;
               pNode->pNext = pNode->pNext->pNext;

               pTemp->pNext = zorder->pTopMost;
               zorder->pTopMost = pTemp;

               break;
            }
            pNode = pNode->pNext;
        }
    }
}

static PMAINWIN dskHideMainWindow (PMAINWIN pWin);

static void dskSetPrimitiveChildren (PMAINWIN pWin, BOOL bSet)
{
    PMAINWIN pParent = (PMAINWIN) pWin->hParent;

    if (bSet) {
        while (pParent) {
            pParent->hPrimitive = (HWND)pWin;

            pWin = pParent;
            pParent = (PMAINWIN) pWin->hParent;
        }
    }
    else {
        while (pParent) {
            pParent->hPrimitive = 0;

            pWin = pParent;
            pParent = (PMAINWIN) pWin->hParent;
        }
    }
}

// this function called when a main window becomes a visible top most window.
// Functions which lead to call this function:
//      ShowWindow: show a invisible window with SW_SHOWNORMAL parameters.
//
// return: old active window.
//
static PMAINWIN dskMoveToTopMost (PMAINWIN pWin, int reason, LPARAM lParam)
{
    RECT rcWin;
    PMAINWIN pOldTopMost;

    if (!pWin) return __mg_active_mainwnd;

    if (pWin->dwExStyle & WS_EX_TOPMOST)
        pOldTopMost = (PMAINWIN) sg_TopMostWinZOrder.pTopMost->hWnd;
    else 
        pOldTopMost = (PMAINWIN) sg_MainWinZOrder.pTopMost->hWnd;

    if (pOldTopMost && (pOldTopMost->WinType == TYPE_CONTROL)
                    && (pOldTopMost->dwStyle & WS_VISIBLE)) {
        dskHideMainWindow (pOldTopMost);
        dskSetPrimitiveChildren (pOldTopMost, FALSE);
        SendNotifyMessage (pOldTopMost->hParent, 
                        MSG_CHILDHIDDEN, reason, lParam);
    }

    if (dskIsTopMost (pWin) && (pWin->dwStyle & WS_VISIBLE))
        return __mg_active_mainwnd;

    // update this main window's global clip region info.
    dskGetWindowRectInScreen (pWin, &rcWin);
    start_clip_window (pWin);
    reset_window (pWin, &rcWin);
    if (!(pWin->dwExStyle & WS_EX_TOPMOST))
        clip_by_windows (&sg_TopMostWinZOrder, pWin);
    end_clip_window (pWin);

    // activate this main window.
    if ( !(pWin->dwStyle & WS_VISIBLE) ) {
        // Update Z Order first.
        if (pWin->dwExStyle & WS_EX_TOPMOST)
            move_to_top (&sg_TopMostWinZOrder, pWin);
        else
            move_to_top (&sg_MainWinZOrder, pWin);

        if (pWin->dwExStyle & WS_EX_TOPMOST)
            dskUpdateGCRInfoOnShowNewMainWinEx (pWin);
        else
            dskUpdateGCRInfoOnShowNewMainWin (pWin);
        
        pWin->dwStyle |= WS_VISIBLE;

        SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, 0);
    
        InvalidateRect ((HWND)pWin, NULL, TRUE);
    }
    else {
        SendAsyncMessage ((HWND)pWin, MSG_NCPAINT, 0, 0);

        if (pWin->dwExStyle & WS_EX_TOPMOST)
            dskUpdateGCRInfoOnChangeTopMostEx (pWin);
        else
            dskUpdateGCRInfoOnChangeTopMost (pWin);

        // then update Z Order.
        if (pWin->dwExStyle & WS_EX_TOPMOST)
            move_to_top (&sg_TopMostWinZOrder, pWin);
        else
            move_to_top (&sg_MainWinZOrder, pWin);
    }

    if (reason != RCTM_SHOWCTRL)
        return dskChangActiveWindow (pWin);
    else
        return __mg_active_mainwnd;
}

static void recalc_windows_under_this (ZORDERINFO* zorder, PMAINWIN pWin, RECT* rcWin)
{
    PZORDERNODE pNode, pAffected;
    RECT rcTemp, rcInv;
    PMAINWIN pTemp;

    // where is the hidding main window?
    pNode = zorder->pTopMost;
    while (pNode->hWnd != (HWND)pWin)
        pNode = pNode->pNext;
    pAffected = pNode->pNext;

    while (pAffected){
        pTemp = (PMAINWIN)(pAffected->hWnd);

        if (pTemp->dwStyle & WS_VISIBLE) {

            start_clip_window (pTemp);
            dskGetWindowRectInScreen (pTemp, &rcTemp);
            reset_window (pTemp, &rcTemp);
            if (zorder != &sg_TopMostWinZOrder) {

⌨️ 快捷键说明

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