📄 menu.c
字号:
/*** $Id: menu.c,v 1.47 2003/09/04 03:15:07 weiym 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; pmi->next = pmi->next->next; mnuDeleteMenuItem (ptmpmi); return phead; } index ++; pmi = pmi->next; } } else { if (phead->id == item) { pmi = phead->next; mnuDeleteMenuItem (phead); return pmi; } pmi = phead; while (pmi->next) { if (pmi->next->id == item) { ptmpmi = pmi->next; pmi->next = pmi->next->next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -