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

📄 menubutton.c

📁 MiniGUI for uCOS 移植实验全部源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    mii.type        = MFT_STRING;
    mii.id          = 0;
    mii.typedata    = (DWORD)GetWindowCaption (hWnd);
    if (!(hmnu = CreatePopupMenu (&mii)))
        return 0;

    pmbi = mb_data->first_item;
    while (pmbi) {

        memset (&mii, 0, sizeof(MENUITEMINFO));
        mii.state       = 0;
        mii.id          = index + _OFF_CMDID;
        if (pmbi->text && pmbi->bmp) {
            mii.type        = MFT_BMPSTRING;
            mii.hbmpChecked = pmbi->bmp;
            mii.hbmpUnchecked = pmbi->bmp;
            mii.typedata    = (DWORD)pmbi->text;
        }
        else if (pmbi->text) {
            mii.type        = MFT_STRING;
            mii.typedata    = (DWORD)pmbi->text;
        }
        else if (pmbi->bmp) {
            mii.type        = MFT_BITMAP;
            mii.hbmpChecked = pmbi->bmp;
            mii.hbmpUnchecked = pmbi->bmp;
        }
        else
            goto error;

        if (InsertMenuItem (hmnu, index, TRUE, &mii))
            goto error;

        index ++;
        pmbi = pmbi->next;
    }

    if (index == 0) goto error;

    GetClientRect (hWnd, &rc);
    ClientToScreen (hWnd, &rc.left, &rc.top);
    TrackPopupMenu (GetPopupSubMenu (hmnu), TPM_LEFTALIGN,
                                    rc.left, rc.top, hWnd);

    return hmnu;

error:
    DestroyMenu (hmnu);
    return 0;
}

static int MenuButtonCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
    PMENUBTNDATA mb_data;

    switch (message) {
    case MSG_CREATE:
        if ((mb_data = (MENUBTNDATA *) calloc (1, sizeof(MENUBTNDATA))) == NULL)
            return -1;

        SetWindowAdditionalData2 (hWnd, (DWORD) mb_data);
        if (!mbInitMenuButtonData (mb_data, DEF_MB_BUFFER_LEN)) {
            free (mb_data);
            return -1;
        }
        break;
       
    case MSG_DESTROY:
        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        mbMenuButtonCleanUp (mb_data);
        free (mb_data);
        break;
        
    case MBM_SETSTRCMPFUNC:
        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        if (mb_data->item_count == 0 && lParam) {
            mb_data->str_cmp = (STRCMP)lParam;
            return MB_OKAY;
        }
        return MB_ERR;

    case MBM_ADDITEM:
    {
        PMBITEM newItem;
        int pos;
        PMENUBUTTONITEM want = (PMENUBUTTONITEM)lParam;
        DWORD style = GetWindowStyle (hWnd);
#if _USE_FIXSTR
        int len;
#endif
        
        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        newItem = mbAllocItem (mb_data);
        if (!newItem) {
            NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_ERRSPACE);
            return MB_ERR_SPACE;
        }

#if _USE_FIXSTR
        len = strlen (want->text);
        newItem->text = FixStrAlloc (len);
        if (!newItem->text) {
            mbFreeItem (mb_data, newItem);
            return MB_ERR_SPACE;
        }
        if (len > 0)
            strcpy (newItem->text, want->text);
#else
        newItem->text = strdup (want->text);
        if (!newItem->text) {
            mbFreeItem (mb_data, newItem);
            return MB_ERR_SPACE;
        }
#endif
        
        newItem->bmp  = want->bmp;
        newItem->data = want->data;
        pos = mbAddNewItem (style, mb_data, newItem, (int)wParam);
        return pos;
    }
        
    case MBM_DELITEM:
    {
        PMBITEM removed;
        int delete = (int)wParam;

        mb_data = (PMENUBTNDATA) GetWindowAdditionalData2 (hWnd);
        removed = mbRemoveItem (mb_data, &delete);
        if (removed) {
#if _USE_FIXSTR
            FreeFixStr (removed->text);
#else
            free (removed->text);
#endif
            mbFreeItem (mb_data, removed);

            mb_data->item_count --;
            if (mb_data->cur_sel == delete) {
                mb_data->cur_sel = MB_INV_ITEM;
                InvalidateRect (hWnd, NULL, TRUE);
            }

            return MB_OKAY;
        }
        return MB_INV_ITEM;
    }

    case MBM_RESETCTRL:
        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        mbResetMenuButtonContent (mb_data);
        InvalidateRect (hWnd, NULL, TRUE);
        return MB_OKAY;
        
    case MBM_GETCURITEM:
        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        return mb_data->cur_sel;
        
    case MBM_SETCURITEM:
    {
        int old, new;

        new = (int)wParam;
        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        old = mb_data->cur_sel;
        if (new >= 0 && new < mb_data->item_count) {
            mb_data->cur_sel = new;
            InvalidateRect (hWnd, NULL, TRUE);
        }

        return old;
    } 

    case MBM_SETITEMDATA:
    {
        PMBITEM pmbi;
        PMENUBUTTONITEM want = (PMENUBUTTONITEM)lParam;

        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        pmbi = mbGetItem (mb_data, (int)wParam);
        if (pmbi == NULL)
            return MB_INV_ITEM;

        if (want->which & MB_WHICH_TEXT) {
#if _USE_FIXSTR
            int len;

            FreeFixStr (pmbi->text);
            len = strlen (want->text);
            pmbi->text = FixStrAlloc (len);
            if (!pmbi->text) {
                pmbi->text = "";
                return MB_ERR_SPACE;
            }
            if (len > 0)
                strcpy (pmbi->text, want->text);
#else
            free (pmbi->text);
            pmbi->text = strdup (want->text);
            if (!pmbi->text) {
                pmbi->text = "";
                return MB_ERR_SPACE;
            }
#endif
        }
        if (want->which & MB_WHICH_BMP) {
            pmbi->bmp = want->bmp;
        }
        if (want->which & MB_WHICH_ATTDATA) {
            pmbi->data = want->data;
        }

        if ((int)wParam == mb_data->cur_sel)
            InvalidateRect (hWnd, NULL, TRUE);
        return MB_OKAY;
    }

    case MBM_GETITEMDATA:
    {
        PMBITEM pmbi;
        PMENUBUTTONITEM want = (PMENUBUTTONITEM)lParam;

        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        pmbi = mbGetItem (mb_data, (int)wParam);
        if (pmbi == NULL)
            return MB_INV_ITEM;

        if (want->which & MB_WHICH_TEXT) {
            want->text = pmbi->text;
        }
        if (want->which & MB_WHICH_BMP) {
            want->bmp = pmbi->bmp;
        }
        if (want->which & MB_WHICH_ATTDATA) {
            want->data = pmbi->data;
        }
        return MB_OKAY;
    }

    case MSG_CHAR:
        if (wParam == ' ') {
            mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
            mb_data->hmnu = mbPopupMenu (hWnd);
            if (mb_data->hmnu)
                NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_STARTMENU);
        }
        break;
        
    case MSG_LBUTTONDOWN:
        SetCapture (hWnd);
        break;
            
    case MSG_LBUTTONUP:
    {
        int x, y;
        RECT rcClient, rcText, rcMenuBar;

        if (GetCapture() != hWnd)
            break;
        ReleaseCapture ();

        x = LOSWORD(lParam);
        y = HISWORD(lParam);
        ScreenToClient (hWnd, &x, &y);
        mbGetRects (hWnd, GetWindowStyle (hWnd),
                        &rcClient, &rcText, &rcMenuBar);
        if (PtInRect (&rcMenuBar, x, y)) {
            mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
            mb_data->hmnu = mbPopupMenu (hWnd);
            if (mb_data->hmnu)
                NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_STARTMENU);
        }
        else if (PtInRect (&rcClient, x, y)) {
            NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_CLICKED);
        }
        break;
    }

    case MSG_ENDTRACKMENU:
    {
        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        if (mb_data->hmnu) {
            DestroyMenu (mb_data->hmnu);
            NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_ENDMENU);
            mb_data->hmnu = 0;
        }
        break;
    }

    case MSG_COMMAND:
    {
        int index = wParam - _OFF_CMDID;

        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        if (index < mb_data->item_count && index >= 0) {
            NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_SELECTED);
            if (index != mb_data->cur_sel) {
                mb_data->cur_sel = index;
                NotifyParent (hWnd, GetDlgCtrlID (hWnd), MBN_CHANGED);
                InvalidateRect (hWnd, NULL, TRUE);
            }
        }

        break;
    }

    case MSG_PAINT:
    {
        HDC hdc;
        RECT rcClient, rcText, rcMenuBar;
        UINT uFormat;
        DWORD dwStyle = GetWindowStyle (hWnd);
        int bk_color = GetWindowBkColor (hWnd);
        const char* text;
        BITMAP* bmp;

        mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);
        mbGetRects (hWnd, dwStyle,
                        &rcClient, &rcText, &rcMenuBar);

        if (mb_data->cur_sel < 0) {
            text = GetWindowCaption (hWnd);
            bmp = NULL;
        }
        else {
            PMBITEM pmbi = mbGetItem (mb_data, mb_data->cur_sel);
            text = pmbi->text;
            bmp = pmbi->bmp;
        }

        hdc = BeginPaint (hWnd);
        if (!(dwStyle & MBS_NOBUTTON))
            myDrawButton (hdc, hWnd, rcClient.left, rcClient.top,
                        rcClient.right, rcClient.bottom, 
                        DF_3DBOX_NORMAL | DF_3DBOX_FILL, 
                        GetWindowBkColor (hWnd));

        if (bmp) {
            if (dwStyle & MBS_LEFTARROW) {
                FillBoxWithBitmap (hdc, 
                            rcMenuBar.right + _INTER_BARTEXT, 
                            (rcText.top + rcText.bottom - bmp->bmHeight) >> 1, 
                            0, 0, bmp);
                rcText.left += bmp->bmWidth + _INTER_BARTEXT;
            }
            else {
                FillBoxWithBitmap (hdc, 
                            rcMenuBar.left - _INTER_BARTEXT -  bmp->bmWidth, 
                            (rcText.top + rcText.bottom - bmp->bmHeight) >> 1, 
                            0, 0, bmp);
                rcText.right -= bmp->bmWidth + _INTER_BARTEXT;
            }
        }

        rcText.left +=  (_INTER_BARTEXT >> 1);

        if (text) {
            uFormat = DT_SINGLELINE | DT_VCENTER;
            switch (dwStyle & MBS_ALIGNMASK) {
                case MBS_ALIGNRIGHT:
                    uFormat |= DT_RIGHT;
                    break;
                case MBS_ALIGNCENTER:
                    uFormat |= DT_CENTER;
                    break;
                default:
                    uFormat |= DT_LEFT;
                    break;
            }
            SetBkColor (hdc, bk_color);
            SetBkMode (hdc, BM_TRANSPARENT);
            if (dwStyle & WS_DISABLED) {
                RECT rc = rcText;

                SetTextColor (hdc, PIXEL_lightwhite);
                OffsetRect (&rc, 1, 1);
                DrawText (hdc, text, -1, &rc, uFormat);

                SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_CONTROL_DISABLED));
                DrawText (hdc, text, -1, &rcText, uFormat);
            }
            else {
                SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_CONTROL_NORMAL));
                DrawText (hdc, text, -1, &rcText, uFormat);
            }
        }

#ifdef _FLAT_WINDOW_STYLE
        DrawFlatControlFrameEx (hdc, hWnd, rcMenuBar.left, rcMenuBar.top, 
                    rcMenuBar.right, rcMenuBar.bottom, 0, DF_3DBOX_NORMAL | DF_3DBOX_FILL, bk_color);
#elif defined (_PHONE_WINDOW_STYLE)
        FillBoxWithBitmap (hdc, rcMenuBar.left, rcMenuBar.top, 0, 0, bmp_downarrow);
#else
        Draw3DThinFrameEx (hdc, hWnd, rcMenuBar.left, rcMenuBar.top, 
                    rcMenuBar.right, rcMenuBar.bottom, DF_3DBOX_NORMAL | DF_3DBOX_FILL, bk_color);
#endif
        EndPaint (hWnd, hdc);
        return 0;
    }

    default:
        break;
    }
    
    return DefaultControlProc (hWnd, message, wParam, lParam);
}

#endif /* _CTRL_MENUBUTTON */

⌨️ 快捷键说明

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