完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
转stemwin教程
本期教程讲解STemWin支持的菜单控件。 48. 1 菜单控件介绍 48. 2 官方WIDGET_Menu实例 48. 3使用官方GUIBulder建立MENU控件 48. 4 总结 48.1 列表框控件介绍 MENU控件可用于创建若干种菜单。每个菜单项代表一个应用程序命令或子菜单。MENU可水平显示和/或垂直显示。菜单项可使用分隔符进行分组。水平菜单和垂直菜单均支持分隔符。选择一个菜单项会发送WM_MENU消息给菜单的所有者,或打开一个子菜单。如果已启用鼠标支持,则MENU小工具会对菜单项上方的鼠标移动作出反应。 下表显示水平MENU控件带垂直菜单的外观: 上表显示菜单控件使用其默认效果WIDGET_Effect_3D1L和使用WIDGET_Effect_Simple时的相应外观。菜单控件还可以与所有其他效果配合使用。 |
|
相关推荐
|
|
48.1.1 菜单消息
为了通知其所有者有关选择一个项或打开一个子菜单的信息,菜单控件将发送WM_MENU类型的消息给其所有者。 WM_MENU:发送此消息的目的是通知菜单的所有者有关选择一个项或打开一个子菜单的信息。已禁用的菜单项将不发送此消息。 WM_MENU中的MENU_MSG_DATA数据结构介绍如下:
|
||
|
||
|
||
下面是一个WM_MENU的简单示例:
复制代码 void Callback(WM_MESSAGE * pMsg) { MENU_MSG_DATA * pData; WM_HWIN hWin = pMsg->hWin; switch (pMsg->MsgId) { case WM_MENU: pData = (MENU_MSG_DATA *)pMsg->Data.p; switch (pData->MsgType) { case MENU_ON_ITEMACTIVATE: _UpdateStatu***ar(pData->ItemId); break; case MENU_ON_INITMENU: _OnInitMenu(); break; case MENU_ON_ITEMSELECT: switch (pData->ItemId) { case ID_MENU_ITEM0: ... /* React on selection of menu item 0 */ break; case ID_MENU_ITEM1: ... /* React on selection of menu item 1 */ break; case ... ... } break; } break; default: MENU_Callback(pMsg); } } |
|
|
|
|
|
48.1.2 数据结构
MENU_ITEM_DATA:此结构充当一个容器,用于设置或检索有关菜单项的信息,MENU_ITEM_DATA的元素介绍如下:
|
||
|
||
|
||
48.1.3 菜单支持键盘反应
如果控件具有输入焦点,则它将对下列各键做出反应:
|
|
|
|
|
|
源码如下(程序中进行了详细的注释):
复制代码 ---------------------------------------------------------------------- File : WIDGET_Menu.c Purpose : Shows how to work with menu widget Requirements: WindowManager - (x) MemoryDevices - (x) AntiAliasing - ( ) VNC-Server - ( ) PNG-Library - ( ) TrueTypeFonts - ( ) ---------------------------------------------------------------------- */ #include #include "GUI.h" #include "DIALOG.h" #include "MENU.h" #include "MESSAGEBOX.h" /********************************************************************* * * Defines * ********************************************************************** */ #define ID_MENU (GUI_ID_USER + 0) #define ID_MENU_FILE_NEW (GUI_ID_USER + 1) #define ID_MENU_FILE_OPEN (GUI_ID_USER + 2) #define ID_MENU_FILE_CLOSE (GUI_ID_USER + 3) #define ID_MENU_FILE_EXIT (GUI_ID_USER + 4) #define ID_MENU_FILE_RECENT (GUI_ID_USER + 5) #define ID_MENU_RECENT_0 (GUI_ID_USER + 6) #define ID_MENU_RECENT_1 (GUI_ID_USER + 7) #define ID_MENU_RECENT_2 (GUI_ID_USER + 8) #define ID_MENU_RECENT_3 (GUI_ID_USER + 9) #define ID_MENU_EDIT_UNDO (GUI_ID_USER + 10) #define ID_MENU_EDIT_REDO (GUI_ID_USER + 11) #define ID_MENU_EDIT_COPY (GUI_ID_USER + 12) #define ID_MENU_EDIT_PASTE (GUI_ID_USER + 13) #define ID_MENU_EDIT_DELETE (GUI_ID_USER + 14) #define ID_MENU_HELP_ABOUT (GUI_ID_USER + 15) /********************************************************************* * * Static data * ********************************************************************** */ static WM_HWIN _hMenu; static WM_HWIN _hText; static WM_HWIN _hFrame; static char * _paDescription[] = { "Creates a new file", "Opens an existing file", "Closes the file", "Quits the application", "", "Opens file 1", "Opens file 2", "Opens file 3", "Opens file 4", "Undoes the last action", "Redoes the previously undone action", "Copies to clipboard", "Inserts contents of clipboard", "Deletes the selection", "Displays program information" }; /********************************************************************* * * Static code * ********************************************************************** */ /********************************************************************* * * _AddMenuItem */ static void _AddMenuItem(MENU_Handle hMenu, MENU_Handle hSubmenu, const char* pText, U16 Id, U16 Flags) { MENU_ITEM_DATA Item; Item.pText = pText; Item.hSubmenu = hSubmenu; Item.Flags = Flags; Item.Id = Id; MENU_AddItem(hMenu, &Item); } /********************************************************************* * * _CreateMenu * 创建菜单控件 */ static WM_HWIN _CreateMenu(WM_HWIN hParent) { MENU_Handle hMenu; MENU_Handle hMenuFile; MENU_Handle hMenuEdit; MENU_Handle hMenuHelp; MENU_Handle hMenuRecent; // // Create main menu // hMenu = MENU_CreateEx(0, 0, 0, 0, WM_UNATTACHED, 0, MENU_CF_HORIZONTAL, ID_MENU); // // Create sub menus // hMenuFile = MENU_CreateEx(0, 0, 0, 0, WM_UNATTACHED, 0, MENU_CF_VERTICAL, 0); hMenuEdit = MENU_CreateEx(0, 0, 0, 0, WM_UNATTACHED, 0, MENU_CF_VERTICAL, 0); hMenuHelp = MENU_CreateEx(0, 0, 0, 0, WM_UNATTACHED, 0, MENU_CF_VERTICAL, 0); hMenuRecent = MENU_CreateEx(0, 0, 0, 0, WM_UNATTACHED, 0, MENU_CF_VERTICAL, 0); // // Add menu items to menu 'Recent' // _AddMenuItem(hMenuRecent, 0, "File 1", ID_MENU_RECENT_0, 0); _AddMenuItem(hMenuRecent, 0, "File 2", ID_MENU_RECENT_1, 0); _AddMenuItem(hMenuRecent, 0, "File 3", ID_MENU_RECENT_2, 0); _AddMenuItem(hMenuRecent, 0, "File 4", ID_MENU_RECENT_3, 0); // // Add menu items to menu 'File' // _AddMenuItem(hMenuFile, 0, "New", ID_MENU_FILE_NEW, 0); _AddMenuItem(hMenuFile, 0, "Open", ID_MENU_FILE_OPEN, 0); _AddMenuItem(hMenuFile, 0, "Close", ID_MENU_FILE_CLOSE, MENU_IF_DISABLED); _AddMenuItem(hMenuFile, 0, 0, 0, MENU_IF_SEPARATOR); _AddMenuItem(hMenuFile, hMenuRecent, "Files...", ID_MENU_FILE_RECENT, 0); _AddMenuItem(hMenuFile, 0, 0, 0, MENU_IF_SEPARATOR); _AddMenuItem(hMenuFile, 0, "Exit", ID_MENU_FILE_EXIT, 0); // // Add menu items to menu 'Edit' // _AddMenuItem(hMenuEdit, 0, "Undo", ID_MENU_EDIT_UNDO, 0); _AddMenuItem(hMenuEdit, 0, "Redo", ID_MENU_EDIT_REDO, 0); _AddMenuItem(hMenuEdit, 0, 0, 0, MENU_IF_SEPARATOR); _AddMenuItem(hMenuEdit, 0, "Copy", ID_MENU_EDIT_COPY, 0); _AddMenuItem(hMenuEdit, 0, "Paste", ID_MENU_EDIT_PASTE, 0); _AddMenuItem(hMenuEdit, 0, "Delete", ID_MENU_EDIT_DELETE, 0); // // Add menu items to menu 'Help' // _AddMenuItem(hMenuHelp, 0, "About", ID_MENU_HELP_ABOUT, 0); // // Add menu items to main menu // _AddMenuItem(hMenu, hMenuFile, "File", 0, 0); _AddMenuItem(hMenu, hMenuEdit, "Edit", 0, 0); _AddMenuItem(hMenu, hMenuHelp, "Help", 0, 0); // // Attach menu to parent window // FRAMEWIN_AddMenu(hParent, hMenu); return hMenu; } /********************************************************************* * * _DrawGradientV * 实现垂直的颜色梯度 */ static void _DrawGradientV(int x0, int y0, int x1, int y1, GUI_COLOR Color0, GUI_COLOR Color1) { int r0; int g0; int b0; int r1; int g1; int b1; int y; int ySize; int r; int g; I32 b; int Diff; ySize = y1 - y0 + 1; r0 = (Color0 >> 0) & 0x000000ff; g0 = (Color0 >> 8) & 0x000000ff; b0 = (Color0 >> 16) & 0x000000ff; r1 = (Color1 >> 0) & 0x000000ff; g1 = (Color1 >> 8) & 0x000000ff; b1 = (Color1 >> 16) & 0x000000ff; for (y = y0; y <= y1; y++) { GUI_COLOR Color; Diff = y - y0; r = r0 + (r1 - r0) * Diff / ySize; g = g0 + (g1 - g0) * Diff / ySize; b = b0 + (b1 - b0) * Diff / ySize; Color = r | (g << 8) | (b << 16); GUI_SetColor(Color); GUI_DrawHLine(y, x0, x1); } } /********************************************************************* * * _MessageBox * 创建并执行模态的消息框 */ static void _MessageBox(const char * pText, const char * pCaption) { WM_HWIN hBox; hBox = MESSAGEBOX_Create(pText, pCaption, GUI_MESSAGEBOX_CF_MODAL | GUI_MESSAGEBOX_CF_MOVEABLE); WM_SetStayOnTop(hBox, 1); WM_BringToTop(hBox); GUI_ExecCreatedDialog(hBox); WM_SetFocus(_hMenu); MENU_SetSel(_hMenu, -1); } /********************************************************************* * * _cbClient * 框架窗口的回调函数 */ static void _cbClient(WM_MESSAGE * pMsg) { char acBuffer[50]; int Index; int xSize; int ySize; int xPos; int yPos; WM_HWIN hWin; WM_HWIN hClient; MENU_MSG_DATA * pData; MENU_ITEM_DATA Data; hWin = pMsg->hWin; hClient = WM_GetClientWindow(hWin); xSize = WM_GetWindowSizeX(hClient); ySize = WM_GetWindowSizeY(hClient); switch (pMsg->MsgId) { case WM_SIZE: // // 如果改变窗口控件大小的话,这里是重新设置文本控件的位置。 // xPos = WM_GetWindowOrgX(hClient); yPos = WM_GetWindowOrgY(hClient); WM_SetWindowPos(_hText, xPos + 4, yPos + ySize - 10, xSize, 10); WM_SetWindowPos(_hMenu, xPos , yPos , xSize, WM_GetWindowSizeY(_hMenu)); TEXT_SetText(_hText, "Ready"); break; case WM_PAINT: // // 绘制框架窗口中用户区部分的背景 // _DrawGradientV(0, 0, xSize - 1, ySize - 12 - 1, GUI_WHITE, GUI_LIGHTBLUE); GUI_SetColor(GUI_LIGHTGRAY); GUI_FillRect(0, ySize - 12, xSize - 1, ySize - 1); GUI_SetTextMode(GUI_TM_TRANS); GUI_SetColor(GUI_BLACK); GUI_SetFont(&GUI_Font24B_ASCII); GUI_DispStringHCenterAt( "MENU widget sample" , xSize / 2, 40); GUI_SetFont(&GUI_Font16B_ASCII); GUI_DispStringHCenterAt( "The sample shows how to use the MENUn" "widget. Use the keyboard or the pointern" "input device for playing with the widget.n" "On highlighting a menu item the statusn" "bar shows a small description. On selectingn" "a menu item a message box will be shown." , xSize / 2, 70); break; case WM_MENU: pData = (MENU_MSG_DATA*)pMsg->Data.p; switch (pData->MsgType) { case MENU_ON_ITEMPRESSED: //按下菜单项之后,将发送此消息给小工具的所有者窗口。对于 //已禁用的菜单项,也将发送此消息 MENU_GetItem(pMsg->hWinSrc, pData->ItemId, &Data); if (Data.Flags & MENU_IF_DISABLED) { _MessageBox("The pressed item was disabled", "Message"); } break; case MENU_ON_ITEMACTIVATE: // // 菜单项被高亮显示之后,菜单的所有者窗口将收到此消息。将 // 子菜单高亮显示之后,则不会发送此消息 // Index = pData->ItemId - ID_MENU_FILE_NEW; if (Index >= 0) { TEXT_SetText(_hText, _paDescription[pData->ItemId - ID_MENU_FILE_NEW]); } else { TEXT_SetText(_hText, "Ready"); } break; case MENU_ON_ITEMSELECT: // // 选择菜单项之后将立即发送此消息给菜单的所有者。ItemId // 元素包含已按下的菜单项的Id。 sprintf(acBuffer, "ID of the selectednitem is 0x%X", pData->ItemId); _MessageBox(acBuffer, "Message"); break; } } WM_DefaultProc(pMsg); } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * MainTask */ void MainTask(void) { int xSize; int ySize; WM_HWIN hClient; GUI_Init(); // // 通过下面两个函数使能所有窗口使用内存设备 // #if GUI_SUPPORT_MEMDEV WM_SetCreateFlags(WM_CF_MEMDEV); WM_EnableMemdev(WM_HBKWIN); #endif WM_SetDesktopColor(GUI_BLACK); MENU_SetDefaultEffect(&WIDGET_Effect_3D1L); // // 创建框架窗口 // _hFrame = FRAMEWIN_CreateEx(10, 10, 300, 220, WM_HBKWIN, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, "Application with menu", _cbClient); FRAMEWIN_SetFont(_hFrame, &GUI_Font13_ASCII); FRAMEWIN_AddMaxButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 0); /* 添加框架窗口最大化按钮 */ FRAMEWIN_AddMinButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 2); /* 添加框架窗口最小化按钮 */ // // 创建菜单控件 // _hMenu = _CreateMenu(_hFrame); // // 创建文本控件 // hClient = WM_GetClientWindow(_hFrame); xSize = WM_GetWindowSizeX(hClient); ySize = WM_GetWindowSizeY(hClient); _hText = TEXT_CreateEx(4, ySize - 10, xSize, 10, hClient, WM_CF_SHOW, 0, GUI_ID_TEXT0, "Ready"); TEXT_SetFont(_hText, &GUI_Font8_ASCII); // // 创建菜单控件 // WM_SetFocus(_hMenu); MENU_SetSel(_hMenu, -1); while (1) { GUI_Delay(100); } } |
|
|
|
|
|
48.3 使用官方GUIBulder建立MENU控件
官方GUIBulder5.22对MENU控件的支持还不够完善,只能建立简单的菜单,菜单里面具体的子项需要用户自己添加。这里用GUIBulder5.22建立一个如下的界面(分辨率480*272): |
|
|
|
|
|
添加后具体每个MENU选项的名字左下角这里进行设置:
设置好以后,将生成的代码复制到模拟器或者开发板上面并稍作修改(生成的代码在本期教程配套的例子中),显示效果如下: |
|
|
|
|
|
48.4 总结
本期教程主要是跟大家讲解了菜单控件的使用,希望大家可以把本期教程中讲的这两个例子跑跑,然后自己设计一个相关的例子进行试验学习。教程中只是使用了部分的菜单控件API,其它的API大家都可以试试。 |
|
|
|
|
|
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-使用AHT20进行环境监测之AHT20传感器介绍
510 浏览 0 评论
792 浏览 0 评论
833 浏览 1 评论
基于瑞萨FPB-RA4E2智能床头灯项目——1编译环境搭建与点亮驱动ws2812全彩LED
797 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
1244 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11816 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 20:19 , Processed in 0.679506 second(s), Total 55, Slave 47 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号