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

📄 menu.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (PtInRect (&rc, x, y))
        return pmi;

    rc.top += pmi->h;
    if (pmi->type == TYPE_PPPMENU)
        psubmi = pmi->submenu;
    else
        psubmi = pmi->next;
   
    while (psubmi) {
        
        rc.bottom = rc.top + psubmi->h;

        if (PtInRect (&rc, x, y))
            return psubmi;

        rc.top = rc.bottom;
        psubmi = psubmi->next;
    }

    return NULL;
}

static void mnuHiliteMenuItem (PTRACKMENUINFO ptmi, PMENUITEM pmi, BOOL bHilite)
{
    RECT rc;
    PMENUITEM ptemp = ptmi->pmi;
    int inter;
    int mioffx;
    int marginlx, marginrx;
    int offy;

    PBITMAP bmp;
    
    if (pmi->type == TYPE_PPPMENU) return;

    inter = GetMainWinMetrics (MWM_INTERMENUITEMY);
    mioffx = GetMainWinMetrics (MWM_MENUITEMOFFX);
    marginlx = GetMainWinMetrics (MWM_MENULEFTMARGIN);
    marginrx = GetMainWinMetrics (MWM_MENURIGHTMARGIN);

    rc.left = ptmi->rc.left;
    rc.right = ptmi->rc.right;
    rc.top = ptmi->rc.top + GetMainWinMetrics (MWM_MENUTOPMARGIN);

    if (ptemp == pmi)
        ptemp = pmi;
    else {
        rc.top += ptemp->h;
        if (ptemp->type == TYPE_PPPMENU)
            ptemp = ptemp->submenu;
        else
            ptemp = ptemp->next;

        while (ptemp != pmi) {
            rc.top += ptemp->h;
            ptemp = ptemp->next;
        }
    }

    rc.bottom = rc.top + ptemp->h;

    if (ptemp->mnutype & MFT_SEPARATOR) return;

    if (bHilite)
        ptemp->mnustate |= MFS_HILITE;
    else
        ptemp->mnustate &= ~MFS_HILITE;

    SetBrushColor (HDC_SCREEN, 
        bHilite ? GetWindowElementColor(BKC_MENUITEM_HILITE)
                : GetWindowElementColor(BKC_MENUITEM_NORMAL));

    FillBox (HDC_SCREEN, rc.left + marginlx, rc.top, 
        RECTW (rc) - marginlx - marginrx, RECTH (rc)); 
#if defined(_FLAT_WINDOW_STYLE) && !defined(_GRAY_SCREEN)
    if (bHilite) {
	    SetPenColor(HDC_SCREEN, GetWindowElementColor(FGC_MENUITEM_FRAME));
	    Rectangle (HDC_SCREEN, rc.left + marginlx, rc.top, 
		rc.left + RECTW (rc) - marginrx, rc.top + RECTH (rc)); 
    }
    else {
	    SetPenColor(HDC_SCREEN, GetWindowElementColor(BKC_MENUITEM_NORMAL));
	    Rectangle (HDC_SCREEN, rc.left + marginlx, rc.top, 
		rc.left + RECTW (rc) - marginrx, rc.top + RECTH (rc)); 
    }
#endif
        
    if (ptemp->mnutype & MFT_BITMAP) {
    
        if (ptemp->mnustate & MFS_CHECKED)
            bmp = ptemp->hbmpChecked;
        else
            bmp = ptemp->hbmpUnchecked;
            
        FillBoxWithBitmap (HDC_SCREEN, rc.left + marginlx, rc.top,
                        bmp->bmWidth, 
                        bmp->bmHeight, 
                        bmp);
    }
    else if (ptemp->mnutype & MFT_OWNERDRAW) {
    }
    else {
        int old_mode, bmp_w = mioffx;

        // draw check bitmap
        bmp = mnuGetCheckBitmap (ptemp);
        if (bmp) {
            offy = (ptemp->h - bmp->bmHeight)>>1;
            FillBoxWithBitmap (HDC_SCREEN, rc.left + marginlx, rc.top + offy,
                    bmp->bmWidth, ptemp->h - (offy<<1), bmp);
            bmp_w = MAX (bmp->bmWidth, mioffx);
        }

        SelectFont (HDC_SCREEN, GetSystemFont (SYSLOGFONT_MENU));
        SetBkColor (HDC_SCREEN, 
                bHilite ? GetWindowElementColor(BKC_MENUITEM_HILITE)
                        : GetWindowElementColor(BKC_MENUITEM_NORMAL));
        old_mode = SetBkMode (HDC_SCREEN, BM_TRANSPARENT);
        if (ptemp->mnustate & MFS_DISABLED) {
            SetTextColor (HDC_SCREEN, GetWindowElementColor(FGC_MENUITEM_DISABLED));
        }
        else {
            SetTextColor (HDC_SCREEN, 
                bHilite ? GetWindowElementColor(FGC_MENUITEM_HILITE)
                        : GetWindowElementColor(FGC_MENUITEM_NORMAL));
        }
        TextOut (HDC_SCREEN, rc.left + bmp_w + marginlx, rc.top + inter,
            (char*)ptemp->typedata);
        SetBkMode (HDC_SCREEN, old_mode);
        
        if (ptemp->submenu) {
            bmp = mnuGetSubMenuBitmap (ptemp);
            offy = (ptemp->h - bmp->bmHeight)>>1;
            FillBoxWithBitmap (HDC_SCREEN, 
                rc.right - mioffx - marginrx,
                rc.top + offy,
                bmp->bmWidth, ptemp->h - (offy<<1), bmp);
        }
    }
}

static int mnuOpenNewSubMenu (PTRACKMENUINFO ptmi, PMENUITEM pmi, 
                int x, int y)
{
    PTRACKMENUINFO pnewtmi;

    pnewtmi = TrackMenuInfoAlloc ();
    
    pnewtmi->rc.left = x;
    pnewtmi->rc.top  = y;
    pnewtmi->pmi = pmi;
    pnewtmi->pmb = ptmi->pmb;
    pnewtmi->philite = NULL;
    pnewtmi->hwnd = ptmi->hwnd;
    pnewtmi->flags = ptmi->flags;
    pnewtmi->next = NULL;
    pnewtmi->prev = NULL;
   
    return SendMessage (HWND_DESKTOP, MSG_TRACKPOPUPMENU,
                    0, (LPARAM)(pnewtmi));
}

static PMENUITEM mnuGetNextMenuItem (PTRACKMENUINFO ptmi, PMENUITEM pmi)
{
    PMENUITEM head = ptmi->pmi;
    PMENUITEM next;

    if (head->type == TYPE_PPPMENU)
        head = head->submenu;

    if (pmi == NULL)
        next = head;
    else if (pmi->next)
        next = pmi->next;
    else
        next = head;

    while (next && next->mnutype & MFT_SEPARATOR)
        next = next->next;

    if (next == NULL)
        next = head;

    while (next && next->mnutype & MFT_SEPARATOR)
        next = next->next;

    return next;
}

static PMENUITEM mnuGetPrevItem (PMENUITEM head, PMENUITEM pmi)
{
    if (head == pmi)
        return NULL;

    while (head) {
        if (head->next == pmi)
            return head;

        head = head->next;
    }

    return NULL;
}

static PMENUITEM mnuGetPrevMenuItem (PTRACKMENUINFO ptmi, PMENUITEM pmi)
{
    PMENUITEM head = ptmi->pmi, tail;
    PMENUITEM prev;

    if (head->type == TYPE_PPPMENU)
        head = head->submenu;

    prev = pmi;

    do {
        prev = mnuGetPrevItem (head, prev);

        if (prev) {
            if (prev->mnutype & MFT_SEPARATOR)
                continue;
            else
                return prev;
        }
        else
            break;
    }while (TRUE);

    tail = head;
    while (tail && tail->next)
        tail = tail->next;

    prev = tail;
    do {
        if (prev) {
            if (!(prev->mnutype & MFT_SEPARATOR))
                return prev;
        }
        else
            break;
            
        prev = mnuGetPrevItem (head, prev);
    }while (TRUE);

    return NULL;
}

static int mnuGetMenuItemY (PTRACKMENUINFO ptmi, PMENUITEM pmi)
{
    PMENUITEM head = ptmi->pmi;
    int y = ptmi->rc.top + GetMainWinMetrics (MWM_MENUTOPMARGIN);

    if (pmi == head) return y;
    
    y += head->h;
    
    if (head->type == TYPE_PPPMENU)
        head = head->submenu;
    else
        head = head->next;

    while (head) {
        if (head == pmi)
            return y;

        y += head->h;

        head = head->next;
    }

    return 0;
}

static void mnuTrackMenuWithKey (PTRACKMENUINFO ptmi, 
                                int message, int scan, DWORD status)
{
    PTRACKMENUINFO phead, pcurtmi, pprevtmi;
    PMENUITEM pcurmi, pnewmi;
    HWND hwnd;
    HMENU hmnu;
    UINT flags;
    int barItem;
    int id;
    
    flags = ptmi->flags;
    hmnu = (HMENU)ptmi->pmi;
    
    phead = ptmi;
    while (phead->prev) {
        phead = phead->prev;
    }
    
    // get last tracking menu, the last menu is the current menu.
    pcurtmi = ptmi;
    while (pcurtmi->next) {
        pcurtmi = pcurtmi->next;
    }

    pprevtmi = pcurtmi->prev;

    pcurmi = pcurtmi->philite;

    if (message == MSG_KEYDOWN) {
        switch (scan) {
            case SCANCODE_CURSORBLOCKDOWN:
            case SCANCODE_CURSORBLOCKUP:
                if (scan == SCANCODE_CURSORBLOCKDOWN)
                    pnewmi = mnuGetNextMenuItem (pcurtmi, pcurmi);
                else
                    pnewmi = mnuGetPrevMenuItem (pcurtmi, pcurmi);

                if (pnewmi != pcurmi) {
                    if (pcurmi) 
                        mnuHiliteMenuItem (pcurtmi, pcurmi, FALSE);
                    if (pnewmi) {
                        mnuHiliteMenuItem (pcurtmi, pnewmi, TRUE);
                        pcurtmi->philite = pnewmi;
                    }
                }
                break;
                
                break;
                
            case SCANCODE_CURSORBLOCKRIGHT:
                if (pcurmi && pcurmi->submenu)
                    mnuOpenNewSubMenu (pcurtmi, 
                                pcurmi->submenu, 
                                pcurtmi->rc.right,
                                mnuGetMenuItemY (pcurtmi, pcurmi));
                else {
                    if (phead->pmb) {
                        barItem  = mnuGetNextMenuBarItem (phead->pmb, 
                                                          phead->barPos);
                        if (barItem != phead->barPos) {
                            hwnd = phead->hwnd;

                            // close current popup menu.
                            SendMessage (HWND_DESKTOP, MSG_CLOSEMENU, 0, 0);

                            // open new popup menu.
                            TrackMenuBar (hwnd, barItem);
                        }
                    }
                }
                break;
                
            case SCANCODE_ESCAPE:
                if (pprevtmi)
                    SendMessage (HWND_DESKTOP, 
                        MSG_ENDTRACKMENU, 0, (LPARAM)pcurtmi);
                break;

            case SCANCODE_CURSORBLOCKLEFT:
                if (pprevtmi)
                    SendMessage (HWND_DESKTOP, 
                        MSG_ENDTRACKMENU, 0, (LPARAM)pcurtmi);
                else {
                    if (phead->pmb) {
                        barItem  = mnuGetPrevMenuBarItem (phead->pmb, 
                                                          phead->barPos);
                        if (barItem != phead->barPos) {
                            hwnd = phead->hwnd;

                            // close current popup menu.
                            SendMessage (HWND_DESKTOP, MSG_CLOSEMENU, 0, 0);

                            // open new popup menu.
                            TrackMenuBar (hwnd, barItem);
                        }
                    }
                }
                break;
                
            case SCANCODE_ENTER:
                if (pcurmi == NULL) return;
                if (pcurmi->mnutype & MFT_SEPARATOR) return;
                if (pcurmi->mnustate & MFS_DISABLED) return;
                
                if (pcurmi->submenu) {
                    mnuOpenNewSubMenu (pcurtmi, 
                                pcurmi->submenu, 
                                pcurtmi->rc.right,
                                mnuGetMenuItemY (pcurtmi, pcurmi));
                    return;
                }

                if (pcurmi && pcurmi->type != TYPE_PPPMENU &&
                    pcurmi->submenu == NULL) {

                    hwnd = ptmi->hwnd;
                    id = pcurmi->id;
        
                    SendMessage (HWND_DESKTOP, MSG_CLOSEMENU, 0, 1);
       
                    if (flags & TPM_SYSCMD)
                        SendNotifyMessage (hwnd, MSG_SYSCOMMAND, id, 0);
                    else
                        SendNotifyMessage (hwnd, MSG_COMMAND, id, 0);

                    if (flags & TPM_DESTROY)
                        DestroyMenu (hmnu);
                }
                break;
        }
    }
    else if (message == MSG_KEYUP) {
        switch (scan) {
            case SCANCODE_LEFTALT:
            case SCANCODE_RIGHTALT:
                SendMessage (HWND_DESKTOP, MSG_CLOSEMENU, 0, 1);

                if (flags & TPM_DESTROY)
                    DestroyMenu (hmnu);
                break;
        }
    }
}

static void mnuTrackMenu (PTRACKMENUINFO ptmi, int x, int y)
{
    PTRACKMENUINFO phead, plast;
    PTRACKMENUINFO pcurtmi, pclose, ptemp;
    PMENUITEM pcurmi;
    PMENUITEM philite;
    int barItem;
    HWND hwnd;
    
    // get first tracking menu.
    phead = ptmi;
    while (phead->prev) {
        phead = phead->prev;
    }
        
    // get last tracking menu.
    plast = ptmi;
    while (plast->next) {
        plast = plast->next;
    }

    pcurtmi = mnuHitTestMenu (plast, x, y);

    if (pcurtmi == NULL) {
        if (plast->philite)
            mnuHiliteMenuItem (plast, plast->philite, FALSE);

        // check to see if move to the other sub menu of menu bar.
        if (phead->pmb) {
            barItem = MenuBarHitTest (phead->hwnd, x, y);
            if (barItem >= 0 && barItem != phead->barPos) {
                    
                hwnd = phead->hwnd;

                // close current popup menu.
                SendMessage (HWND_DESKTOP, MSG_CLOSEMENU, 0, 0);

                // open new popup menu.
                TrackMenuBar (hwnd, barItem);
            }
        }
            
        return;
    }

    pcurmi = mnuHitTestMenuItem (pcurtmi, x, y);

    if (pcurtmi != plast) {
        pclose = pcurtmi->next->next;
       
        if (pclose != NULL) {
            while (pclose != plast) {
                ptemp = plast->prev;
                SendMessage (HWND_DESKTOP, MSG_ENDTRACKMENU, 0, (LPARAM)plast);
                plast = ptemp;
            }
            SendMessage (HWND_DESKTOP, MSG_ENDTRACKMENU, 0, (LPARAM)plast);
            plast = pcurtmi->next;
        }
            
        if (plast->philite) {
            mnuHiliteMenuItem (plast, plast->philite, FALSE);
            plast->philite = NULL;
        }
    }

    philite = pcurtmi->philite;
    if (pcurmi == philite) return;

    // current hilite menu item is a bottom most item.
    if (philite) {
        if (pcurtmi != plast)
            SendMessage (HWND_DESKTOP, MSG_ENDTRACKMENU, 0, (LPARAM)plast);
        mnuHiliteMenuItem (pcurtmi, philite, FALSE);
    }

    pcurtmi->philite = pcurmi;
    if (pcurmi == N

⌨️ 快捷键说明

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