跳转至

菜单栏控件 (SMenuBar)

基本信息

  • 类名SMenuBar
  • 控件标签menubar
  • 基类SWindow
  • 功能描述:应用程序顶部的菜单栏,可在其中挂载多个 SMenuSMenuEx 弹出菜单,是构建传统桌面应用菜单系统(文件/编辑/视图…)的容器控件。

重要纠正:旧文档列出的 itemWidth / itemHeight / textOffset / iconBarWidth / separatorHeight / colorText* / colorBkgnd / itemSkin / iconSkin 等“属性”在 SMenuBar 源码(SOUI/include/control/SMenuBar.h)中均不存在SMenuBar 自身只有一个 SOUI_ATTRS 属性 useMenuEx,其余外观(文本颜色、背景、皮肤、项高宽等)完全由 SWindow 通用属性与 <style> 决定。下为对照源码后的正确属性表。

自身属性

SMenuBar::SOUI_ATTRS_BEGIN 中声明的属性:

属性名 类型 默认值 是否重绘 说明
useMenuEx bool false true 时,通过 Insert(标题, 资源名) 挂载的弹出菜单使用 SMenuEx 渲染;为 false(默认)时使用原生 SMenu

说明:SOUI_ATTRS_BEGIN 的第三个参数 allredraw 表示“属性变更后是否重绘”,不是默认值。上表默认值来自 SMenuBar 构造函数成员初始化(m_bUseMenuEx(FALSE))。

继承的通用属性

除上述自有属性外,SMenuBar 作为 SWindow 派生控件,支持全部通用控件属性,常用包括:

  • 布局:possizewidthheightlayoutgravity
  • 外观:colorTextcolorTextDisableskinclassvisibleenablealpha
  • 文本:fontalignvaligntext

菜单项的外观(文本色、背景、图标、项高宽)应在 <style> 或皮肤中统一设置,而非通过 SMenuBar 的 XML 属性。

使用示例

基本菜单栏

<menubar name="mainMenu" pos="0,0,-0,28"
         colorBkgnd="#F0F0F0" colorText="#333333"
         useMenuEx="1">
    <item text="文件">
        <item text="新建" hotkey="Ctrl+N"/>
        <item text="打开" hotkey="Ctrl+O"/>
        <sep/>
        <item text="退出"/>
    </item>
    <item text="编辑">
        <item text="剪切" hotkey="Ctrl+X"/>
        <item text="复制" hotkey="Ctrl+C"/>
        <item text="粘贴" hotkey="Ctrl+V"/>
    </item>
</menubar>

带图标的菜单栏

<menubar name="menuIcon" pos="0,0,-0,28" iconSkin="menu_icons">
    <item text="文件" icon="0">
        <item text="新建文件" icon="1"/>
        <item text="新建文件夹" icon="2"/>
        <sep/>
        <item text="打开" icon="3"/>
    </item>
    <item text="编辑" icon="4">
        <item text="撤销" icon="5"/>
        <item text="重做" icon="6"/>
    </item>
</menubar>

代码挂载菜单

#include <control/SMenuBar.h>

void InitMenuBar(SMenuBar* pMenuBar)
{
    // 通过标题 + 菜单资源名挂载(资源名指向 menu / menuex 布局)
    pMenuBar->Insert(L"文件", L"layout:menu_file");
    pMenuBar->Insert(L"编辑", L"layout:menu_edit");

    // 运行时判断当前使用的菜单类型
    if (pMenuBar->IsUseMenuEx())
    {
        SMenuEx* pEx = pMenuBar->GetMenuEx(0);
        // ...
    }
    else
    {
        SMenu* pMenu = pMenuBar->GetMenu(0);
        // ...
    }
}

事件处理

菜单项被选中时触发 EventCmd,可在宿主窗口的事件映射中处理:

EVENT_MAP_BEGIN()
    EVENT_NAME_COMMAND(L"mainMenu", OnMenuCommand)
EVENT_MAP_END()

void CMainDlg::OnMenuCommand(UINT uNotifyCode, int nID, HWND wndCtl)
{
    switch (nID)
    {
    case ID_FILE_NEW:  OnFileNew();  break;
    case ID_FILE_OPEN: OnFileOpen(); break;
    }
}

常见问题

  1. 项高/间距无法设置SMenuBar 没有 itemHeight 等属性,项尺寸由项皮肤或 <style> 控制。
  2. useMenuEx 不生效:该属性决定 Insert 挂载的弹出菜单类型,需与所加载资源(原生 menumenuex 布局)匹配。
  3. 弹出菜单无皮肤:原生 SMenu 必须在资源 <menu> 根节点设置 itemSkinSMenuEx 则依赖其布局中的 menuItem 皮肤。

相关主题