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

📄 menu.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
** $Id: menu.c,v 1.52 2004/10/25 04:04:17 snig Exp $
**
** menu.c: The Menu module.
**
** Copyright (C) 2003 Feynman Software.
** Copyright (C) 1999 ~ 2002 Wei Yongming.
**
** Create date: 1999.04.09
**
** Current maintainer: Wei Yongming.
**
** Used abbreviations in this file:
**      Menu: mnu
**      Popup: ppp
**      Identifier: id
**      Mnemonic: mnic
**      Normal: nml
**      Item: itm
**      Modify records:
*/

/*
** 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 "gal.h"
#include "internals.h"
#include "blockheap.h"
#include "menu.h"

/************************* MENUBAR allocation ********************************/
static BLOCKHEAP MBHeap;
inline static void InitFreeMBList (void)
{
    InitBlockDataHeap (&MBHeap, sizeof (MENUBAR), SIZE_MB_HEAP);
}

inline static PMENUBAR MenuBarAlloc (void)
{
    return (PMENUBAR) BlockDataAlloc (&MBHeap);
}

inline static void FreeMenuBar (PMENUBAR pmb)
{
    BlockDataFree (&MBHeap, pmb);
}

inline static void DestroyFreeMBList (void)
{
    DestroyBlockDataHeap (&MBHeap);
}

/************************* MENUITEM allocation *******************************/
static BLOCKHEAP MIHeap;
inline static void InitFreeMIList (void)
{
    InitBlockDataHeap (&MIHeap, sizeof (MENUITEM), SIZE_MI_HEAP);
}

inline static PMENUITEM MenuItemAlloc (void)
{
    return (PMENUITEM) BlockDataAlloc (&MIHeap);
}

inline static void FreeMenuItem (MENUITEM* pmi)
{
    BlockDataFree (&MIHeap, pmi);
}

inline static void DestroyFreeMIList (void)
{
    DestroyBlockDataHeap (&MIHeap);
}

/************************* TRACKMENUITEM heap *******************************/
static BLOCKHEAP TMIHeap;
inline static void InitFreeTMIList (void)
{
    InitBlockDataHeap (&TMIHeap, sizeof (TRACKMENUINFO), SIZE_TMI_HEAP);
}

inline static PTRACKMENUINFO TrackMenuInfoAlloc (void)
{
    return (PTRACKMENUINFO) BlockDataAlloc (&TMIHeap);
}

inline static void FreeTrackMenuInfo (TRACKMENUINFO* ptmi)
{
    BlockDataFree (&TMIHeap, ptmi);
}

inline static void DestroyFreeTMIList(void)
{
    DestroyBlockDataHeap (&TMIHeap);
}

/************************* Module initialization *****************************/

static BITMAP bmp_menuitem;

BOOL InitMenu (void)
{
    InitFreeMBList ();
    InitFreeMIList ();
    InitFreeTMIList ();

    return InitBitmap (HDC_SCREEN, 16, 12, 0, NULL, &bmp_menuitem);
}

/************************* Module termination *******************************/
void TerminateMenu (void)
{
    DestroyFreeTMIList ();
    DestroyFreeMBList ();
    DestroyFreeMIList ();

    UnloadBitmap (&bmp_menuitem);
}

/***************************** Menu creation *******************************/
HMENU GUIAPI LoadMenuFromFile (const char* filename, int id)
{
    return 0;
}

HMENU GUIAPI CreateMenu (void)
{
    PMENUBAR pmb;

    if (!(pmb = MenuBarAlloc ()))
        return 0;
    
    pmb->category = TYPE_HMENU;
    pmb->type = TYPE_MENUBAR;
    pmb->head = NULL;

    return (HMENU)pmb;
}

HMENU GUIAPI CreatePopupMenu (PMENUITEMINFO pmii)
{
    PMENUITEM pmi;
    
    if (!(pmi = MenuItemAlloc ()))
        return 0;
   
    pmi->category = TYPE_HMENU;
    pmi->type = TYPE_PPPMENU;
    pmi->next = NULL;
    pmi->submenu = NULL;

    pmi->mnutype         = pmii->type;
    pmi->mnustate        = pmii->state;
    pmi->id              = pmii->id;
    pmi->hbmpChecked     = pmii->hbmpChecked;
    pmi->hbmpUnchecked   = pmii->hbmpUnchecked;
    pmi->itemdata        = pmii->itemdata;

    // copy string.
    if (pmii->type == MFT_STRING || pmii->type == MFT_BMPSTRING) {
        int len = strlen ((char*)pmii->typedata);
        pmi->typedata = (DWORD)FixStrAlloc (len);
        if (len > 0)
            strcpy ((char*)pmi->typedata, (char*)pmii->typedata);
    }
    else
        pmi->typedata = pmii->typedata;

    return (HMENU)pmi;
}

HMENU GUIAPI CreateSystemMenu (HWND hwnd, DWORD dwStyle)
{
    HMENU hmnu;
    MENUITEMINFO mii;

    memset (&mii, 0, sizeof(MENUITEMINFO));
    mii.type        = MFT_STRING;
    mii.id          = 0;
    mii.typedata    = (DWORD)GetSysText(SysText[5]);

    hmnu = CreatePopupMenu (&mii);

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

    if (dwStyle & WS_MINIMIZEBOX) {
        mii.type        = MFT_STRING;
        mii.state       = 0;
        mii.id          = SC_MINIMIZE;
        mii.typedata    = (DWORD)GetSysText(SysText[6]);
        InsertMenuItem(hmnu, 0, TRUE, &mii);
    }

    if (dwStyle & WS_MAXIMIZEBOX) {
        mii.type        = MFT_STRING;
        if (dwStyle & WS_MAXIMIZE)
            mii.state   = MFS_DISABLED;
        else
            mii.state   = 0;
        mii.id          = SC_MAXIMIZE;
        mii.typedata    = (DWORD)GetSysText(SysText[7]);
        InsertMenuItem(hmnu, 1, TRUE, &mii);

        mii.type        = MFT_STRING;
        if (dwStyle & WS_MAXIMIZE)
            mii.state   = 0;
        else
            mii.state   = MFS_DISABLED;
        mii.id          = SC_RESTORE;
        mii.typedata    = (DWORD)GetSysText(SysText[8]);
        InsertMenuItem(hmnu, 2, TRUE, &mii);
    }

    mii.type        = MFT_SEPARATOR;
    mii.state       = 0;
    mii.id          = 0;
    mii.typedata    = 0;
    InsertMenuItem(hmnu, 3, TRUE, &mii);

    mii.type        = MFT_STRING;
    mii.state       = 0;
    mii.id          = SC_CLOSE;
    mii.typedata    = (DWORD)GetSysText(SysText[9]);
    InsertMenuItem(hmnu, 4, TRUE, &mii);

    return hmnu;
}

static BOOL mnuInsertMenuItem (PMENUITEM pmi, PMENUITEM pnewmi,
                int item, BOOL flag)
{
    PMENUITEM ptmpmi;
    int index;
    
    if (flag) {
        // Insert this new menu item at the start.
        if (item == 0) {
            pnewmi->next = pmi;
            return TRUE;
        }
        
        index = 1;
        while (pmi->next) {

            if (index == item) {
                ptmpmi = pmi->next;
                pmi->next = pnewmi;
                pnewmi->next = ptmpmi;
                return FALSE;
            }
            
            index ++;
            pmi = pmi->next;
        }
    }
    else {
        if (item == pmi->id) {
            pnewmi->next = pmi;
            return TRUE;
        }
        
        while (pmi->next) {

            if (pmi->next->id == item) {
                ptmpmi = pmi->next;
                pmi->next = pnewmi;
                pnewmi->next = ptmpmi;
                return FALSE;
            }
            
            pmi = pmi->next;
        }
    }

    // append this new menu item at the end.
    pmi->next = pnewmi;

    return FALSE;
}

int GUIAPI InsertMenuItem (HMENU hmnu, int item, 
                            BOOL flag, PMENUITEMINFO pmii)
{
    PMENUBAR pmb;
    PMENUITEM pnewmi, pmi;

    pmb = (PMENUBAR) hmnu;

    if (pmb->category != TYPE_HMENU)
        return ERR_INVALID_HANDLE; 
    
    if (!(pnewmi = MenuItemAlloc ())) 
        return ERR_RES_ALLOCATION;

    pnewmi->category        = TYPE_HMENU;
    pnewmi->type            = TYPE_NMLMENU;
    pnewmi->mnutype         = pmii->type;
    pnewmi->mnustate        = pmii->state;
    pnewmi->id              = pmii->id;
    pnewmi->hbmpChecked     = pmii->hbmpChecked;
    pnewmi->hbmpUnchecked   = pmii->hbmpUnchecked;
    pnewmi->itemdata        = pmii->itemdata;
    pnewmi->next            = NULL;
    pnewmi->submenu         = (PMENUITEM)(pmii->hsubmenu);

    // copy string.
    if (pmii->type == MFT_STRING || pmii->type == MFT_BMPSTRING) {
        int len = strlen ((char*)pmii->typedata);
        pnewmi->typedata = (DWORD)FixStrAlloc (len);
        if (len > 0)
            strcpy ((char*)pnewmi->typedata, (char*)pmii->typedata);
    }
    else
        pnewmi->typedata = pmii->typedata;
    
    if (pmb->type == TYPE_MENUBAR) {
        pmi = pmb->head;
        
        if (!pmi)
            pmb->head = pnewmi;
        else {
            if (mnuInsertMenuItem (pmb->head, pnewmi, item, flag))
                pmb->head = pnewmi;
        }
    }
    else if (pmb->type == TYPE_PPPMENU) {
        pmi = (PMENUITEM)hmnu;

        if (!pmi->submenu)
            pmi->submenu = pnewmi;
        else {
            if (mnuInsertMenuItem (pmi->submenu, pnewmi, item, flag))
                pmi->submenu = pnewmi;
        }
    }
    else
        return ERR_INVALID_HMENU;

   return 0;
}

static void mnuDeleteMenuItem (PMENUITEM pmi)
{
    PMENUITEM ptmpmi;
    PMENUITEM psubmi;

    if (pmi->submenu) {
        psubmi = pmi->submenu;
        while (psubmi) {
            ptmpmi = psubmi->next;
            mnuDeleteMenuItem (psubmi);
            psubmi = ptmpmi;
        }
    }

    if (pmi->mnutype == MFT_STRING || pmi->mnutype == MFT_BMPSTRING)
        FreeFixStr ((void*)pmi->typedata);
        
    FreeMenuItem (pmi);
}

static PMENUITEM mnuRemoveMenuItem (PMENUITEM phead, int item, BOOL flag)
{
    int index;
    PMENUITEM pmi, ptmpmi;
    
    if (!phead) return NULL;
    
    if (flag) {
    
        if (item == 0) {
            pmi = phead->next;
            if (!phead->submenu) 
                mnuDeleteMenuItem (phead);
            return pmi;
        }
        
        pmi = phead;
        index = 1;
        while (pmi->next) {

            if (index == item) {
                ptmpmi = pmi->next;
                pmi->next = pmi->next->next;
                
                if (!ptmpmi->submenu)
                    mnuDeleteMenuItem (ptmpmi);

                return phead;
            }

            index ++;
            pmi = pmi->next;
        }
    }
    else {
        if (phead->id == item) {
            pmi = phead->next;
            if (!phead->submenu) 
                mnuDeleteMenuItem (phead);
            return pmi;
        }
        
        pmi = phead;
        while (pmi->next) {

            if (pmi->next->id == item) {
                ptmpmi = pmi->next;
                pmi->next = pmi->next->next;
                
                if (!ptmpmi->submenu)
                    mnuDeleteMenuItem (ptmpmi);

                return phead;
            }

            pmi = pmi->next;
        }
    }

    return phead;
}

int GUIAPI RemoveMenu (HMENU hmnu, int item, UINT flags)
{
    PMENUBAR pmb;
    PMENUITEM pmi;

    pmb = (PMENUBAR) hmnu;

    if (pmb->category != TYPE_HMENU)
        return ERR_INVALID_HANDLE;
    
    if (pmb->type == TYPE_MENUBAR)
        pmb->head = mnuRemoveMenuItem (pmb->head, item, 
            flags & MF_BYPOSITION);
    else if (pmb->type == TYPE_PPPMENU) {
        pmi = (PMENUITEM) hmnu;
        pmi->submenu = mnuRemoveMenuItem (pmi->submenu, item, 
            flags & MF_BYPOSITION);
    }
    else
        return ERR_INVALID_HMENU;   // this is a normal menu item. 

    return 0;
}

static PMENUITEM mnuDeleteMenu (PMENUITEM phead, int item, BOOL flag)
{
    int index;
    PMENUITEM pmi, ptmpmi;
    
    if (!phead) return NULL;
    
    if (flag) {
    
        if (item == 0) {
            pmi = phead->next;
            mnuDeleteMenuItem (phead);
            return pmi;
        }
        
        pmi = phead;
        index = 1;
        while (pmi->next) {

            if (index == item) {
                ptmpmi = pmi->next;

⌨️ 快捷键说明

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