MFC关于按钮下拉菜单的功能实现
前言
根据产品工作需求要求,要实现个剖切管理的功能,关于界面ui的实现,有一模块是类似word文档实现按钮下拉菜单功能的实现。这块实现遇到不少坑,特总结一下经验,为后人少掉坑。
参考类似word相应功能实现:
产品工作需求设计:
产品最终实现效果
思路
参考了不少网上文档,没有找到合适的相关实现。但是给我提供了实现的思路:
利用CMFCMenuButton按钮加上CMenu菜单按钮,进行功能的实现。
基于Menu菜单下拉按钮实现
按钮下拉菜单 Demo 源代码:
- 开发工具:vs2019
- UI框架:MFC
- Menu菜单定义
- 控件定义
Resource.h文件
#define ID_MENU_SECTIONACTION_PNTSELS 32799
#define ID_MENU_SECTIONACTION_GCS 32800
#define ID_MENU_SECTIONACTION_GCN 32801
#define ID_MENU_SECTIONACTION_GCE 32802
#define ID_MENU_SECTIONACTION_GCW 32803
#define ID_MENU_SECTIONACTION_GCU 32804
#define ID_MENU_SECTIONACTION_GCUL 32805
#define ID_MENU_SECTIONACTION_CLS 32806
- 头文件
public:
afx_msg void OnBnClickedBtnSectionAction();
//执行添加一个点选剖切面
void BeginOnePointSection(string sActType);
public:
CMFCMenuButton m_BtnMenuSectionAction;
CMenu m_MenuActions;
// 下拉按钮的状态
map<int, StringWide> m_mapId2MenuName;
int m_nCurrentClickId = -1;
int m_nCurrentClickIndex = -1;
- 源文件
void CSectionsObjectManagerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_MFCMENUBUTTON_SECTIONLIST, m_BtnMenuSectionAction);
}
BOOL CSectionsObjectManagerDlg::OnInitDialog()
{
__super::OnInitDialog();
//...
//下拉按钮
m_mapId2MenuName[ID_MENU_SECTIONACTION_PNTSELS] = L"PointSelSection";
m_mapId2MenuName[ID_MENU_SECTIONACTION_GCS] = L"GlobalCuttingS";
m_mapId2MenuName[ID_MENU_SECTIONACTION_GCN] = L"GlobalCuttingN";
m_mapId2MenuName[ID_MENU_SECTIONACTION_GCE] = L"GlobalCuttingE";
m_mapId2MenuName[ID_MENU_SECTIONACTION_GCW] = L"GlobalCuttingW";
m_mapId2MenuName[ID_MENU_SECTIONACTION_GCU] = L"GlobalCuttingEL";
m_mapId2MenuName[ID_MENU_SECTIONACTION_GCUL] = L"GlobalCutting-EL";
m_mapId2MenuName[ID_MENU_SECTIONACTION_CLS] = L"CenterLineSection";
string flag("Sections Manager");
m_MenuActions.LoadMenu(IDR_MENU_SECTIONACTIONS);
for (auto Item : m_mapId2MenuName)
{
m_MenuActions.ModifyMenuW(Item.first, MF_BYCOMMAND | MF_STRING, Item.first, tr(Item.second.c_str(), flag));
}
m_BtnMenuSectionAction.m_hMenu = m_MenuActions.GetSubMenu(0)->GetSafeHmenu(); // 将CMFCMenuButton和Menu IDR_MENU1关联
m_BtnMenuSectionAction.SizeToContent();
m_BtnMenuSectionAction.m_bOSMenu = FALSE;
m_BtnMenuSectionAction.SetWindowTextW(tr(L"PointSelSection", flag));
m_nCurrentClickId = ID_MENU_SECTIONACTION_PNTSELS;
m_BtnMenuSectionAction.m_nMenuResult = m_nCurrentClickId;
m_nCurrentClickIndex = 0;
}
void CSectionsObjectManagerDlg::OnBnClickedBtnSectionAction()
{
int nCurrIndex = -1;
int nCurrId = -1;
if (m_BtnMenuSectionAction.m_nMenuResult == 0)
{
nCurrId = m_nCurrentClickId;
nCurrIndex = m_nCurrentClickIndex;
}
else
{
nCurrId = m_BtnMenuSectionAction.m_nMenuResult;
nCurrIndex = m_BtnMenuSectionAction.m_nMenuResult - ID_MENU_SECTIONACTION_PNTSELS;
}
if (nCurrId <= 0 || m_mapId2MenuName.find(nCurrId) == m_mapId2MenuName.end())
return;
CString sText = m_mapId2MenuName[nCurrId].c_str();
if (sText.GetLength() > 0)
{
m_BtnMenuSectionAction.SetWindowText(tr(sText.GetString(), "Sections Manager"));
m_BtnMenuSectionAction.SetFocus();
m_BtnMenuSectionAction.RedrawWindow();
m_BtnMenuSectionAction.Invalidate();
m_BtnMenuSectionAction.UpdateData(FALSE);
}
m_nCurrentClickIndex = nCurrIndex;
m_nCurrentClickId = nCurrId;
// 执行相应的动作
BeginOnePointSection(StringWideToUtf8(sText.GetString()));
}