根据表中数据动态生成菜单
(
三
)
本文讲述,如何通过数据库中的数据来动态生成菜单,如下:
1.
创建对话框工程:
DynamicMenuBornFromDatabase
2.
本文使用
ADO
技术,因此需要导入一个
ADO
动态链接库
msado15.dll
,此库位于
”
Program Files/Common Files/System/ado/”
。
StdAfx.h
中代码如下:
#import
"c:/Program Files/Common Files/System/ado/msado15.dll"
rename_namespace (
"ADODB"
)/
rename (
"EOF"
,
"ADOEOF"
)
using
namespace
ADODB
;
如果你的系统盘是其它盘,只需要修改以上路径即可。
3.
为
InitInstance()
函数添加初始化连接数据库操作如下:
//
添加数据库连接
AfxOleInit();
m_pCon.CreateInstance(
__uuidof
(Connection));
m_pRecord.CreateInstance(
__uuidof
(Recordset));
m_pCon->ConnectionString =
"Provider=Microsoft.Jet.OLEDB.4.0; /
Data Source=./Menu.mdb;Persist Security Info=False"
;
try
{
m_pCon->Open(
""
,
""
,
""
,-1);
}
catch
(...)
{
AfxMessageBox(
"
数据库连接错误
"
,0,0);
exit;
}
4.
在
CDynamicMenuBornFromDatabaseDlg
类中添加如下成员变量:
CMenu menu;
HMENU h_menu ;
HMENU h_submenu;
CDynamicMenuBornFromDatabaseDlg
实现中添加如下两个变量:
extern
_ConnectionPtr m_pCon;
extern
_RecordsetPtr m_pRecord;
添加两个全局变量如下:
_ConnectionPtr m_pCon;
_RecordsetPtr m_pRecord;
在
OnInitDialog()
中添加如下代码:
menu.CreateMenu();
LoadMenuFromDatabase();
5.
在
CDynamicMenuBornFromDatabaseDlg
中添加如下三个成员函数如下:
//
判断指定的菜单是否有子菜单项
BOOL CDynamicMenuBornFromDatabaseDlg::IsHaveSubMenu(CString str)
{
_ConnectionPtr m_con;
_RecordsetPtr m_record;
m_con.CreateInstance(
"ADODB.Connection"
);
m_record.CreateInstance(
"ADODB.Recordset"
);
m_con->ConnectionString = m_pCon->ConnectionString;
m_con->Open(
""
,
""
,
""
,-1);
CString sql;
sql.Format(
"select * from tb_menuinfo where
上级菜单
= '%s'"
,str);
m_record = m_con->Execute((_bstr_t)sql,NULL,adCmdText);
if
((!m_record->BOF) &&(! m_record->ADOEOF))
{
return
TRUE;
}
return
FALSE;
}
//
从数据库中加载菜单
void
CDynamicMenuBornFromDatabaseDlg::LoadMenuFromDatabase()
{
CString sql;
sql.Format(
"select * from tb_menuinfo where
上级菜单
is NULL"
);
m_pRecord = m_pCon->Execute((_bstr_t)sql,NULL,adCmdText);
CMenu m_menu;
CString c_menustr;
while
(! m_pRecord->ADOEOF)
{
c_menustr = m_pRecord->GetCollect(
"
菜单名称
"
).bstrVal;
//menu.AppendMenu(MF_STRING,-1,c_menustr);
LoadSubMenu(&menu,c_menustr);
m_pRecord->MoveNext();
}
SetMenu(&menu);
}
//
利用递归的方式加载子菜单
void
CDynamicMenuBornFromDatabaseDlg::LoadSubMenu(CMenu *m_menu, CString str)
{
_ConnectionPtr m_con;
_RecordsetPtr m_record;
m_con.CreateInstance(
"ADODB.Connection"
);
m_record.CreateInstance(
"ADODB.Recordset"
);
m_con->ConnectionString = m_pCon->ConnectionString;
m_con->Open(
""
,
""
,
""
,-1);
CString sql;
sql.Format(
"select * from tb_menuinfo where
上级菜单
= '%s'"
,str);
m_record = m_con->Execute((_bstr_t)sql,NULL,adCmdText);
CMenu m_tempmenu;
m_tempmenu.CreatePopupMenu();
while
(!m_record->ADOEOF)
{
CString c_menustr = m_record->GetCollect(
"
菜单名称
"
).bstrVal;
m_tempmenu.AppendMenu(MF_STRING,-1,c_menustr);
if
(IsHaveSubMenu(c_menustr))
LoadSubMenu(&m_tempmenu,c_menustr);
m_record->MoveNext();
}
m_menu->AppendMenu(MF_POPUP,(UINT)m_tempmenu.m_hMenu,str);
m_tempmenu.Detach();
if
(m_record != NULL)
m_record.Release();
if
(m_con!= NULL)
m_con.Release();
}
编译运行,就可以看到效果了,可以根据数据库中的数据来生成菜单项。