VC 动态生成菜单
2012-07-31 16:25
281 查看
动态生成菜单
这是一段根据字符串动态生成菜单的程序,字符串的格式是这样的:一个数字+一个字符串组成一个菜单项,一项一项的排开,用逗号,分隔,组成一个大字符串。数字表示菜单的层次,0是主菜单,1是1级子菜单...n+1是离它最近的左边的n级菜单的子菜单。最多可以表示9级子菜单,这已经足够了。字符串是菜单显示的内容。举个例子,比如0a,1b,1c,0d表示主菜单是a和d,a有2个子菜单b和c。
再比如 0a,1a1,2a11,2a12,1a2,2a21,3e,2a22,0b,0c,0d,1d1,2d11 表示出的菜单是这样的:
具体做起来很简单。
在头文件里:
由于要用到vector和map,所以先include他俩:
#include
定一个结构体,存储菜单项相关信息。
struct node_t
{
int level;//菜单项的层次
CString name;//菜单项显示的字符串
int nID;//该菜单项的id,用于处理选某个菜单项
};
typedef std::vector
别忘了还得有个成员变量:
CMenu* m_pMenu;
在cpp文件:
//这是个功能函数,把输入字符串解析成结构体数组,以便后面生成菜单用。
bool CQuickmenuDlg::ParseStringToVector( CString csparse, arNode& arlist )
{
arlist.clear();
node_t node;
for (;;){
int npos = csparse.Find( _T(','));
if ( -1 == npos ){
csparse.TrimLeft();
csparse.TrimRight();
if(csparse.IsEmpty()){
return false;
}
CString cst=csparse.Left(1);
LPCTSTR tmp=LPCTSTR(cst);
node.level = _ttoi(tmp);
node.name = csparse.Mid(1);
arlist.push_back( node );
break;
}
CString csadd = csparse.Left( npos );
csadd.TrimLeft();
csadd.TrimRight();
if(csadd.IsEmpty()){
return false;
}
CString cst=csadd.Left(1);
LPCTSTR tmp=LPCTSTR(cst);
node.level = _ttoi(tmp);
node.name = csadd.Mid(1);
arlist.push_back( node );
csparse = csparse.Mid( npos + 1 );
}
return true;
}
//在对话框初始化函数里,开始生成菜单了。
BOOL CQuickmenuDlg::OnInitDialog()
{
...
//前面的省略
// TODO: Add extra initialization here
//这是生成菜单所用的字符串。他的来源可以是消息,可以是文件,这只是个例子,写个固定值。
CString cs=_T("0a,1a1,2a11,2a12,1a2,2a21,2a22,0b,0c,0d,1d1");
//分解成结构体数组
arNode menulist;
if(!ParseStringToVector(cs,menulist)){
return TRUE;
}
//创建菜单
m_pMenu=new CMenu;
if(!m_pMenu->CreatePopupMenu()){
return TRUE;
}
//这是核心代码了,根据结构体数组创建菜单项。
std::map<int,CMenu*> menumap;
std::map<int,int> levelcountmap;
levelcountmap[0]=0;
menumap[0]=m_pMenu;
int n=menulist.size();
for (int i=0;i<n-1;i++){
node_t node=menulist[i];
levelcountmap[node.level]++;
node_t nodenext=menulist[i+1];
if (nodenext.level>node.level){
HMENU hmenu=CreatePopupMenu();
menumap[node.level]->AppendMenu(MF_STRING|MF_POPUP,(long)hmenu,node.name);
menumap[nodenext.level]=menumap[node.level]->GetSubMenu(levelcountmap[node.level]-1);
}else{
if (nodenext.level<node.level){
for (int j=node.level;j>nodenext.level;j--){
levelcountmap[j]=0;
}
}
//这里的i是该菜单项的id,可以根据node.name设定,以便后面弹出菜单后选某一项时处理。
menumap[node.level]->AppendMenu(MF_STRING,i,node.name);
}
}
//最后一项,这个i也是它的id。
menumap[menulist[n-1].level]->AppendMenu(MF_STRING,i,menulist[n-1].name);
return TRUE; // return TRUE unless you set the focus to a control
}
//最后在右键响应函数里加上TrackPopupMenu弹出菜单。
void CQuickmenuDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
ClientToScreen(&point);
int nID=m_pMenu->TrackPopupMenu(TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTALIGN
| TPM_LEFTBUTTON | TPM_RIGHTBUTTON,point.x,point.y,this);
//process selection nID...
//这个nID就是创建时设的,用个switch case结构分别处理。
switch(nID)
{
case 1:
break;
//...
}
CDialog::OnRButtonUp(nFlags, point);
}
这是一段根据字符串动态生成菜单的程序,字符串的格式是这样的:一个数字+一个字符串组成一个菜单项,一项一项的排开,用逗号,分隔,组成一个大字符串。数字表示菜单的层次,0是主菜单,1是1级子菜单...n+1是离它最近的左边的n级菜单的子菜单。最多可以表示9级子菜单,这已经足够了。字符串是菜单显示的内容。举个例子,比如0a,1b,1c,0d表示主菜单是a和d,a有2个子菜单b和c。
再比如 0a,1a1,2a11,2a12,1a2,2a21,3e,2a22,0b,0c,0d,1d1,2d11 表示出的菜单是这样的:
具体做起来很简单。
在头文件里:
由于要用到vector和map,所以先include他俩:
#include
定一个结构体,存储菜单项相关信息。
struct node_t
{
int level;//菜单项的层次
CString name;//菜单项显示的字符串
int nID;//该菜单项的id,用于处理选某个菜单项
};
typedef std::vector
别忘了还得有个成员变量:
CMenu* m_pMenu;
在cpp文件:
//这是个功能函数,把输入字符串解析成结构体数组,以便后面生成菜单用。
bool CQuickmenuDlg::ParseStringToVector( CString csparse, arNode& arlist )
{
arlist.clear();
node_t node;
for (;;){
int npos = csparse.Find( _T(','));
if ( -1 == npos ){
csparse.TrimLeft();
csparse.TrimRight();
if(csparse.IsEmpty()){
return false;
}
CString cst=csparse.Left(1);
LPCTSTR tmp=LPCTSTR(cst);
node.level = _ttoi(tmp);
node.name = csparse.Mid(1);
arlist.push_back( node );
break;
}
CString csadd = csparse.Left( npos );
csadd.TrimLeft();
csadd.TrimRight();
if(csadd.IsEmpty()){
return false;
}
CString cst=csadd.Left(1);
LPCTSTR tmp=LPCTSTR(cst);
node.level = _ttoi(tmp);
node.name = csadd.Mid(1);
arlist.push_back( node );
csparse = csparse.Mid( npos + 1 );
}
return true;
}
//在对话框初始化函数里,开始生成菜单了。
BOOL CQuickmenuDlg::OnInitDialog()
{
...
//前面的省略
// TODO: Add extra initialization here
//这是生成菜单所用的字符串。他的来源可以是消息,可以是文件,这只是个例子,写个固定值。
CString cs=_T("0a,1a1,2a11,2a12,1a2,2a21,2a22,0b,0c,0d,1d1");
//分解成结构体数组
arNode menulist;
if(!ParseStringToVector(cs,menulist)){
return TRUE;
}
//创建菜单
m_pMenu=new CMenu;
if(!m_pMenu->CreatePopupMenu()){
return TRUE;
}
//这是核心代码了,根据结构体数组创建菜单项。
std::map<int,CMenu*> menumap;
std::map<int,int> levelcountmap;
levelcountmap[0]=0;
menumap[0]=m_pMenu;
int n=menulist.size();
for (int i=0;i<n-1;i++){
node_t node=menulist[i];
levelcountmap[node.level]++;
node_t nodenext=menulist[i+1];
if (nodenext.level>node.level){
HMENU hmenu=CreatePopupMenu();
menumap[node.level]->AppendMenu(MF_STRING|MF_POPUP,(long)hmenu,node.name);
menumap[nodenext.level]=menumap[node.level]->GetSubMenu(levelcountmap[node.level]-1);
}else{
if (nodenext.level<node.level){
for (int j=node.level;j>nodenext.level;j--){
levelcountmap[j]=0;
}
}
//这里的i是该菜单项的id,可以根据node.name设定,以便后面弹出菜单后选某一项时处理。
menumap[node.level]->AppendMenu(MF_STRING,i,node.name);
}
}
//最后一项,这个i也是它的id。
menumap[menulist[n-1].level]->AppendMenu(MF_STRING,i,menulist[n-1].name);
return TRUE; // return TRUE unless you set the focus to a control
}
//最后在右键响应函数里加上TrackPopupMenu弹出菜单。
void CQuickmenuDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
ClientToScreen(&point);
int nID=m_pMenu->TrackPopupMenu(TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTALIGN
| TPM_LEFTBUTTON | TPM_RIGHTBUTTON,point.x,point.y,this);
//process selection nID...
//这个nID就是创建时设的,用个switch case结构分别处理。
switch(nID)
{
case 1:
break;
//...
}
CDialog::OnRButtonUp(nFlags, point);
}
相关文章推荐
- VC++中动态生成菜单技巧
- VC++中动态生成菜单技巧
- 谈在VC中动态改变菜单
- easyUI动态生成多级菜单树
- WinForm winform动态生成菜单
- 动态生成树状菜单
- 【VC控件】动态修改控件和弹出菜单上的文字内容及大小
- vc动态生成按钮并响应 .
- Ext tree 动态生成、拖动排序、右键菜单
- Android 实现动态生成菜单
- VC下动态改变菜单显示的标题和Checked状态(Change title of CMenu and Checked)
- 关于VC++下动态添加菜单的心得
- win32动态生成窗体菜单
- 使用dtree生成的树结构,ajax动态加载子节点后,如何绑定右键菜单续
- 在VC程序中实现控件的动态生成与响应
- Vs2005的win form动态生成菜单
- MVC5+EF6 入门完整教程13 -- 动态生成多级菜单
- vc++ 使用菜单类动态创建菜单
- DotnetBar MapX中动态生成可以查询地图数据的弹出菜单问题
- VC++工具栏与状态栏的动态生成