实验环境:VC++6.0 ,windows XP
需要安装MSXML 4.0 SP2
实现的功能是初始化XML文档,读取特定节点,和创建新节点删除节点等操作。XML文件如下所示:
首先我们要实现的功能是:创建一个如图所示的XML文档
在VC中创建基于对话框的MFC工程。主对话框实现下面的摆放。
主要功能为:初始化XML文档,是初始化如第一幅图所示的XML,登陆即按照XML中的用户账号信息进行登陆,分为管理员身份和普通用户身份。
程序刚运行时,已经有初始化的XML文档在程序文件夹下。此时只有登陆按钮可用。 管理员登陆以后:登陆按钮变为不可用,其他按钮均变为可用;(只有管理员有权初始化,创建和删除用户)。
普通用户登陆以后:只有注销按钮可用,其余全为不可用。
对话框各控件ID和关联变量如下图:
在实现功能之前,需要做下面几步: 1.
在StdAfx.h中引入动态链接库 MSXML.DLL(C:\windows\system32\msxml.dll)
#import <msxml4.dll>
2. 在APP类的InitInstance函数里面加入如下代码:
AfxOleInit(); //Com口初始化 3.在我们要操作XML的cpp文件开始部分加入:
using namespace MSXML2; 4. 为了实现用户的权限控制,在Dlg类的OnInitDialog()函数中添加:
//初始化只有登陆按钮可用
GetDlgItem(IDC_CREATE)->EnableWindow(false);
GetDlgItem(IDC_DELETE)->EnableWindow(false);
GetDlgItem(IDC_LOGOUT)->EnableWindow(false);
GetDlgItem(IDC_INITIAL)->EnableWindow(false);
功能实现部分:
一
初始化XML: 在按钮“初始化XML”的响应函数OnInitial_XML()里面加入下面的代码:
void CXML_DatabaseDlg::OnInitial_XML()
{
// TODO: Add your control notification handler code here
//创建XML文件
UpdateData(TRUE);
MSXML2::IXMLDOMDocumentPtr pDoc;
MSXML2::IXMLDOMElementPtr xmlRoot; //创建DOMDocument对象
HRESULT hr = pDoc.CreateInstance(_uuidof(MSXML2::DOMDocument40));
if (FAILED(hr))
{
MessageBox("无法创建DOM文件对象,检查是否安装MS XML Parser运行库!");
return;
}
//根节点名称为Account
//创建元素并添加到文档中
xmlRoot = pDoc->createElement_x((_bstr_t)"Account");
pDoc->appendChild(xmlRoot);
//创建一个节点
MSXML2::IXMLDOMElementPtr pNode;
//添加用户
pNode = pDoc->createElement_x((_bstr_t)"USER");
pNode->setAttribute("id","admin");
pNode->setAttribute("password","admin");
pNode->setAttribute("persimmon","admin");
xmlRoot->appendChild(pNode);
//添加用户
pNode = pDoc->createElement_x((_bstr_t)"USER");
pNode->setAttribute("id","monitor1");
pNode->setAttribute("password","monitor1");
pNode->setAttribute("persimmon","user");
xmlRoot->appendChild(pNode);
//添加用户
pNode = pDoc->createElement_x((_bstr_t)"USER");
pNode->setAttribute("id","monitor2");
pNode->setAttribute("password","monitor2");
pNode->setAttribute("persimmon","user");
xmlRoot->appendChild(pNode);
//保存文件,不存在就建立,存在就覆盖
pDoc->save("account.xml");
m_List.InsertString(-1,"XML初始化成功........"); }
二
登陆(读取XML) 首先要做一个登陆对话框,如下图所示:
然后登陆对话框的控件ID和关联变量如下图所示:
在CXML_DatabaseDlg 中添加public变量: CLoginDlg logdlg;
给“登陆”按钮添加响应函数OnLogin()。添加如下代码:
void CXML_DatabaseDlg::OnLogin()
{
// TODO: Add your control notification handler code here
if(logdlg.DoModal()==IDOK)
{
CString username="",username_in=""; //用户名,密码
CString password="",password_in="";
CString permission="";
//得到输入的用户名和密码
username_in = logdlg.m_name;
password_in = logdlg.m_password;
if (username_in==""||password_in=="")
{
MessageBox("用户名或者密码不能为空!");
return;
}
MSXML2::IXMLDOMDocumentPtr pDoc;
HRESULT hr;
hr = pDoc.CreateInstance(_uuidof(MSXML2::DOMDocument40));
if (FAILED(hr))
{
MessageBox("无法创建DOM对象,检查是否安装了MS XML Parser运行库!");
return;
}
//加载xml文档
pDoc->load("account.xml"); //得到根节点
MSXML2::IXMLDOMElementPtr pRoot = pDoc->GetdocumentElement();
MSXML2::IXMLDOMNodeListPtr pNodeList = pRoot->GetchildNodes(); //得到所有的节点列表
MSXML2::IXMLDOMNamedNodeMapPtr pNodeAttributes;
//某个节点所有的属性
MSXML2::IXMLDOMNodePtr pNode,pid,ppassword,ppermission;
//遍历所有USER节点
long nodecount=0;
pNodeList->get_length(&nodecount);
_variant_t id_value,password_value,permission_value; //存储节点属性值
for (long i=0;i<nodecount;i++)
{
pNode = pNodeList->Getitem(i);
pNodeAttributes = pNode->Getattributes();
//得到每一个节点的所有属性
//遍历一个节点的所有属性id,password,permission
pid = pNodeAttributes->Getitem(0);
id_value = pid->GetnodeValue(); //得到这个节点的id属性值
username = (char *)(_bstr_t)id_value;
if (username==username_in)
{
ppassword = pNodeAttributes->Getitem(1);
//如果id匹配,接着比较password
password_value = ppassword->GetnodeValue();
password = (char *)(_bstr_t)password_value;
if (password==password_in)
{
//id ,password都正确,得到用户权限
ppermission = pNodeAttributes->Getitem(2);
permission_value = ppermission->GetnodeValue();
permission = (char *)(_bstr_t)permission_value;
if (permission=="admin")
{
m_List.InsertString(-1,"管理员"+logdlg.m_name+"登陆成功......"); GetDlgItem(IDC_CREATE)->EnableWindow(true)
GetDlgItem(IDC_DELETE)->EnableWindow(true);
GetDlgItem(IDC_LOGIN)->EnableWindow(false); GetDlgItem(IDC_LOGOUT)->EnableWindow(true);
return;
}
else
{
m_List.InsertString(-1,"普通用户"+logdlg.m_name+"登陆成功......"); GetDlgItem(IDC_LOGOUT)->EnableWindow(true);
return;
}
}
else
{
MessageBox("密码错误!");
return;
}
}
else if(i==nodecount-1)
{
MessageBox("用户不存在");
return;
}
}
} }
三
注销 注销主要做的就是使一些按钮不可用,如下所示:
给“注销”按钮添加响应函数 OnLogOut(),并添加如下代码:
void CXML_DatabaseDlg::OnLogout()
{
// TODO: Add your control notification handler code here
GetDlgItem(IDC_CREATE)->EnableWindow(false);
GetDlgItem(IDC_DELETE)->EnableWindow(false);
GetDlgItem(IDC_LOGIN)->EnableWindow(true);
GetDlgItem(IDC_LOGOUT)->EnableWindow(false);
GetDlgItem(IDC_INITIAL)->EnableWindow(false); m_List.InsertString("用户"+logdlg.m_name+"成功注销!");
logdlg.m_name="";
logdlg.m_password=""; }