我想实现一个动态的自定义的菜单,类似于某些Email客户端软件的附件按钮。点击附件按钮,会弹出一个菜单,每一个附件是一个菜单项,点击菜单项将附件保存至本地。
菜单项不固定;响应函数不固定;经过研究在OnCommand函数中可实现。菜单命令是交由OnCommand函数处理的,在这个函数中完成命令消息的路由。
第一步:需要定义菜单项的ID。
这里需要定义菜单项的开始ID。例如;const int MENU_SEQ_LEVEL_START = 10000;
第二步:定义菜单变量,创建弹出式菜单。
CMenu m_menuPopSeqLevel;
在初始化函数中创建弹出式菜单:m_menuPopSeqLevel.CreatePopupMenu();
第三步:初始化菜单项
我使用一个字符串数组,每个字符串作为一个菜单项。
m_arraySeqLevel中存储了菜单项的名称。
m_mapMenuIdName将名称与菜单项对应起来。
for ( UINT i = 0; i < m_arraySeqLevel.GetSize(); i++ )
{
m_menuPopSeqLevel.AppendMenu( MF_STRING,
MENU_SEQ_LEVEL_START + i,
m_arraySeqLevel.GetAt( i ) );
m_mapMenuIdName.insert( MAP_ID_NAME::value_type( MENU_SEQ_LEVEL_START + i, m_arraySeqLevel.GetAt( i ) ) );
}
第四步:弹出菜单
在一个按钮的响应函数中:
DWORD dwPos = GetMessagePos();
CPoint point( LOWORD(dwPos), HIWORD(dwPos) );
m_menuPopSeqLevel.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON,
point.x,
point.y,
this );
第五步:OnCommand函数响应菜单命令
int nMenuID = LOWORD( wParam );
// 判断是否是菜单命令,只要判断命令Id是否是菜单Id即可
if ( nMenuID >= MENU_SEQ_LEVEL_START &&
nMenuID < MENU_SEQ_LEVEL_START + m_mapMenuIdName.size() )
{
CString strMenuName;
// 通过菜单ID找到菜单项名称,初始化时保存在map中
strMenuName = getMenuNameFromId( nMenuID );
if ( !strMenuName.IsEmpty() )
{
// TODO:
}
}