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

📄 desktop-comm.c

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

#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
    // update region covered by the server clipping rects.
    if (!mgIsServer) {
        int i;
        RECT* crcs = SHAREDRES_SCRINFO.clip_rects;

        for (i = 0; i < MAX_SRV_CLIP_RECTS; i++) {
            if (!IsRectEmpty (crcs + i)) {
                if (IntersectRect (&rcInvalid, crcs + i, &rcScreen)) {
                    dskScreenToClient (pWin, &rcInvalid, &rcInvalid);
                    OffsetRect (&rcInvalid, pswi->iOffx, pswi->iOffy);
                    wndInvalidateRect ((HWND)pWin, &rcInvalid, TRUE);
                    inved = TRUE;
                }
            }
        }
    }
#endif

    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;

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

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

#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
    if (mgIsServer) {
        scr_del_clip_rect (pWin->scr_idx);
        dskGetWindowRectInScreen (pWin, &rcTemp);
        pWin->scr_idx = scr_add_clip_rect (&rcTemp);
    }
#endif

    // when old window rect out of date.
    for (i=0; i<nInvCount; i++)
        dskUpdateOldMainWindow (pWin, rcInv + i, &oldWinRect, &oldClientRect);
    
#if defined(_LITE_VERSION) && !defined(_STAND_ALONE)
    // update region covered by the server clipping rects.
    if (!mgIsServer) {
        int i;
        RECT* crcs = SHAREDRES_SCRINFO.clip_rects;

        for (i = 0; i < MAX_SRV_CLIP_RECTS; i++) {
            if (!IsRectEmpty (crcs + i))
                dskUpdateOldMainWindow (pWin, crcs + i, &oldWinRect, &oldClientRect);
        }
    }
#endif

    // update region covered by the topmost windows.
    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);
#ifndef __UCOSII__
        exit (2);
#endif
        break;
    }

    return 0;
}

void GUIAPI ExitGUISafely (int exitcode)
{
    TerminateGUI ((exitcode > 0) ? -exitcode : exitcode);
#ifndef __UCOSII__
    exit (2);
#endif
}

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;
        }
        else {
            mg_altdown = 0;
            if (mg_modal == 1) {
                mg_modal = 0;
                return 0;
            }
        }
    }

    if (mg_altdown) {
        if (message == MSG_KEYDOWN) {
            if( scancode == SCANCODE_TAB) {
            
                mg_modal = 1;
                
                if (__mg_ptmi)
                    dskForceCloseMenu ();

                pNextWin = dskGetNextVisibleMainWindow (__mg_active_mainwnd);
                dskMoveToTopMost (pNextWin, RCTM_KEY, 0);
                dskChangActiveWindow (pNextWin);
                return 0;
            }
            else if (scancode == SCANCODE_ESCAPE) {

                mg_modal = 1;

                if (__mg_active_mainwnd) {
#ifdef  _DEBUG
                    fprintf (stderr, "Will be Closed: %p.\n", __mg_active_mainwnd);
#endif
                    PostMessage ((HWND)__mg_active_mainwnd, MSG_CLOSE, 0, 0);
                    return 0;
                }
            }
        }
        else if (mg_modal == 1)
            return 0;
    }
    
    if (scancode == SCANCODE_LEFTALT
             || scancode == SCANCODE_RIGHTALT || mg_altdown) {
        if (message == MSG_KEYDOWN)
            message = MSG_SYSKEYDOWN;
        else {
            message = MSG_SYSKEYUP;
            mg_altdown = 0;
        }
    }
#ifdef _LITE_VERSION
    if (__mg_ime_wnd) {
        if (dskHandleKeyHooks (__mg_ime_wnd, 

⌨️ 快捷键说明

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