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

📄 menubutton.c

📁 MiniGUI for uCOS 移植实验全部源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
** $Id: menubutton.c,v 1.28 2004/06/26 07:49:31 weiym Exp $
**
** button.c: the Menu Button Control module.
**
** Copyright (C) 2003 Feynman Software.
** Copyright (C) 2000 ~ 2002 Wei Yongming.
**
** Current maintainer: Wei Yongming.
**
** Create date: 2000/11/16
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
** TODO:
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common.h"
#include "minigui.h"
#include "gdi.h"
#include "window.h"
#include "control.h"
#include "cliprect.h"
#include "internals.h"
#include "ctrlclass.h"
#include "ctrlmisc.h"

#ifdef _CTRL_MENUBUTTON

#define _USE_FIXSTR  1

#include "menubutton.h"

#ifdef _FLAT_WINDOW_STYLE
#   define _WIDTH_BORDER       1
#define myDrawButton(hdc, hwnd, x0, y0, x1, y1, flags, fillc) \
                 DrawFlatControlFrameEx(hdc, hwnd, x0, y0, x1, y1, 3, flags, fillc)
#else
#   define _WIDTH_BORDER       4
#define myDrawButton Draw3DControlFrameEx
#endif

#ifdef _PHONE_WINDOW_STYLE

const BITMAP* bmp_downarrow;

#   define _WIDTH_MENUBAR   (bmp_downarrow->bmWidth)
#   define _HEIGHT_MENUBAR  (bmp_downarrow->bmHeight)

#else

#   define _WIDTH_MENUBAR   12
#   define _HEIGHT_MENUBAR  8

#endif

#define _INTER_BARTEXT   4

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

BOOL RegisterMenuButtonControl (void)
{
    WNDCLASS WndClass;

#ifdef _PHONE_WINDOW_STYLE
    if ((bmp_downarrow = GetStockBitmap (STOCKBMP_DOWNARROW, 0, 0)) == NULL)
        return FALSE;
#endif

    WndClass.spClassName = CTRL_MENUBUTTON;
    WndClass.dwStyle     = WS_NONE;
    WndClass.dwExStyle   = WS_EX_NONE;
    WndClass.hCursor     = GetSystemCursor (IDC_ARROW);
    WndClass.iBkColor    = GetWindowElementColor (BKC_BUTTON_DEF);
    WndClass.WinProc     = MenuButtonCtrlProc;

    return AddNewControlClass (&WndClass) == ERR_OK;
}

#if 0
void MenuButtonControlCleanup (void)
{
    return;
}
#endif

static BOOL mbInitMenuButtonData (MENUBTNDATA* mb_data, int len)
{
    int i;
    PMBITEM pmbi;
    
    mb_data->str_cmp = strncmp;

    mb_data->cur_sel = MB_INV_ITEM;

    // init item buffer.
    if (!(mb_data->buff_head = malloc (len * sizeof (MBITEM))))
        return FALSE;

    mb_data->buff_len = len;
    mb_data->buff_tail = mb_data->buff_head + len;
    mb_data->free_list = mb_data->buff_head;

    pmbi = mb_data->free_list;
    for (i = 0; i < len - 1; i++) {
        pmbi->next = pmbi + 1;
        pmbi ++;
    }
    pmbi->next = NULL;

    return TRUE;
}

static void mbMenuButtonCleanUp (MENUBTNDATA* mb_data)
{
    PMBITEM pmbi;
    PMBITEM next;

    pmbi = mb_data->first_item;
    while (pmbi) {
#if _USE_FIXSTR
        FreeFixStr (pmbi->text);
#else
        free (pmbi->text);
#endif
        next = pmbi->next;
        if (pmbi < mb_data->buff_head || pmbi > mb_data->buff_tail)
            free (pmbi);

        pmbi = next;
    }
    
    free (mb_data->buff_head);
}

static void mbResetMenuButtonContent (PMENUBTNDATA mb_data)
{
    int i;
    PMBITEM pmbi, next;

    mb_data->item_count = 0;
    mb_data->cur_sel    = MB_INV_ITEM;

    pmbi = mb_data->first_item;
    while (pmbi) {
#if _USE_FIXSTR
        FreeFixStr (pmbi->text);
#else
        free (pmbi->text);
#endif
        next = pmbi->next;
        if (pmbi < mb_data->buff_head || pmbi > mb_data->buff_tail)
            free (pmbi);

        pmbi = next;
    }

    mb_data->first_item = NULL;
    mb_data->free_list = mb_data->buff_head;

    pmbi = mb_data->free_list;
    for (i = 0; i < mb_data->buff_len - 1; i++) {
        pmbi->next = pmbi + 1;
        pmbi ++;
    }
    pmbi->next = NULL;
}

static PMBITEM mbAllocItem (PMENUBTNDATA mb_data)
{
    PMBITEM pmbi;

    if (mb_data->free_list) {
        pmbi = mb_data->free_list;
        mb_data->free_list = pmbi->next;
    }
    else
        pmbi = (PMBITEM) malloc (sizeof (MBITEM));
    
    return pmbi;
}

static void mbFreeItem (PMENUBTNDATA mb_data, PMBITEM pmbi)
{
    if (pmbi < mb_data->buff_head || pmbi > mb_data->buff_tail)
        free (pmbi);
    else {
        pmbi->next = mb_data->free_list;
        mb_data->free_list = pmbi;
    }
}

static int mbAddNewItem (DWORD dwStyle, 
        PMENUBTNDATA mb_data, PMBITEM newItem, int pos)
{
    PMBITEM pmbi;
    PMBITEM insPosItem = NULL;
    int insPos = 0;

    newItem->next = NULL;
    if (!mb_data->first_item)
        insPosItem = NULL;
    else if (dwStyle & MBS_SORT) {
        pmbi = mb_data->first_item;

        if (mb_data->str_cmp (newItem->text, pmbi->text, (size_t)-1) < 0) {
            insPosItem = NULL;
            insPos = 0;
        }
        else {
            while (pmbi->next) {
                if (mb_data->str_cmp (newItem->text, pmbi->next->text, (size_t)-1) <= 0)
                    break;
            
                pmbi = pmbi->next;
                insPos ++;
            }
            insPosItem = pmbi;
        }
    }
    else {
        pmbi = mb_data->first_item;

        if (pos < 0) {
            while (pmbi->next) {
                pmbi = pmbi->next;
                insPos ++;
            }
            insPosItem = pmbi;
        }
        else if (pos > 0) {
            int index = 0;

            while (pmbi->next) {
                if (pos == index)
                    break;
                pmbi = pmbi->next;
                index ++;
                insPos ++;
            }
            insPosItem = pmbi;
        }
    }

    if (insPosItem) {
        pmbi = insPosItem->next;
        insPosItem->next = newItem;
        newItem->next = pmbi;

        insPos ++;
    }
    else {
        pmbi = mb_data->first_item;
        mb_data->first_item = newItem;
        newItem->next = pmbi;
    }

    mb_data->item_count ++;

    return insPos;
}

static PMBITEM mbRemoveItem (PMENUBTNDATA mb_data, int* pos)
{
    int index = 0;
    PMBITEM pmbi, prev;

    if (!mb_data->first_item)
        return NULL;

    if (*pos < 0) {
        prev = mb_data->first_item;
        pmbi = mb_data->first_item;
        while (pmbi->next) {
            prev = pmbi;
            pmbi = pmbi->next;
            index ++;
        }

        if (pmbi == mb_data->first_item) {
            mb_data->first_item = mb_data->first_item->next;
            *pos = 0;
            return pmbi;
        }
        else {
            prev->next = pmbi->next;
            *pos = index;
            return pmbi;
        }
    }
    else if (*pos == 0) {
        pmbi = mb_data->first_item;
        mb_data->first_item = pmbi->next;
        return pmbi;
    }
    else {
        index = 0;
        prev = mb_data->first_item;
        pmbi = mb_data->first_item;
        while (pmbi->next) {
            if (*pos == index)
                break;

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

        if (pmbi == mb_data->first_item) {
            mb_data->first_item = mb_data->first_item->next;
            *pos = 0;
            return pmbi;
        }
        else {
            prev->next = pmbi->next;
            *pos = index;
            return pmbi;
        }
    }

    return NULL;
}

static PMBITEM mbGetItem (PMENUBTNDATA mb_data, int pos)
{
    int index = 0;
    PMBITEM pmbi;

    pmbi = mb_data->first_item;

    while (pmbi) {
        if (index == pos)
            break;

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

    return pmbi;
}

static void mbGetRects (HWND hWnd, DWORD dwStyle,
                                    RECT* prcClient,
                                    RECT* prcText,
                                    RECT* prcMenuBar)
{
    GetClientRect (hWnd, prcClient);
    prcClient->right --;
    prcClient->bottom --;

    if (dwStyle & MBS_LEFTARROW) {
        SetRect (prcMenuBar, prcClient->left + _WIDTH_BORDER,
                      (prcClient->top + prcClient->bottom - _HEIGHT_MENUBAR) >> 1,
                      prcClient->left + _WIDTH_BORDER + _WIDTH_MENUBAR,
                      (prcClient->top + prcClient->bottom + _HEIGHT_MENUBAR) >> 1);

        SetRect (prcText, prcMenuBar->right + _INTER_BARTEXT,
                      prcClient->top + _WIDTH_BORDER,
                      prcClient->right - _INTER_BARTEXT,
                      prcClient->bottom - _WIDTH_BORDER);

    }
    else {
        SetRect (prcText, prcClient->left + _WIDTH_BORDER,
                      prcClient->top + _WIDTH_BORDER,
                      prcClient->right - _WIDTH_MENUBAR - (_INTER_BARTEXT << 1),
                      prcClient->bottom - _WIDTH_BORDER);

        SetRect (prcMenuBar, prcText->right + _INTER_BARTEXT,
                      (prcClient->top + prcClient->bottom - _HEIGHT_MENUBAR) >> 1,
                      prcClient->right - _INTER_BARTEXT,
                      (prcClient->top + prcClient->bottom + _HEIGHT_MENUBAR) >> 1);
    }
}

#define _OFF_CMDID      100

static HMENU mbPopupMenu (HWND hWnd)
{
    HMENU hmnu;
    MENUITEMINFO mii;
    PMENUBTNDATA mb_data;
    int index = 0;
    PMBITEM pmbi;
    RECT rc;

    mb_data = (PMENUBTNDATA)GetWindowAdditionalData2 (hWnd);

    memset (&mii, 0, sizeof(MENUITEMINFO));

⌨️ 快捷键说明

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