最近写了一个桌面菜单系统,可以扩充成网吧菜单系统。
我总结下用到的技术,以及重要的算法:
1.使用MSXML时需要:
加载库文件 #import<msxml4.dll>
然后 在APP里 AfxOleInit();
然后开始读文件:
StrVec LoadXmlByID(const char* filePath,const char* pathID)
{
StrVec ret;
MSXML2::IXMLDOMDocumentPtr pDoc;
HRESULT hr;
hr=pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));
if(FAILED(hr))
{
AfxMessageBox("无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库!");
return ret;
}
CString strFile=filePath;
//加载文件
if(!pDoc->load((LPCTSTR)strFile))
{
AfxMessageBox("没有找到配置文件!面板初始化...");
return ret;
}
MSXML2::IXMLDOMNodeListPtr pNodes;
//在树中查找名为Book的节点,"//"表示在任意一层查找
pNodes=pDoc->selectNodes(pathID);
int nLen=pNodes->length;
CString sztmp,strDomainName;
for(int i=0;i<nLen;++i)
{
MSXML2::IXMLDOMNamedNodeMapPtr pAttrMap=NULL;
MSXML2::IXMLDOMNodePtr pAttrItem;
_variant_t variantValue;
MSXML2::IXMLDOMNode* temp=NULL;
pNodes->get_item(i,&temp);
temp->get_attributes(&pAttrMap);
pAttrMap->get_item(0,&pAttrItem);
//取得节点的值
pAttrItem->get_nodeTypedValue(&variantValue);
sztmp=(char *)(_bstr_t)variantValue;//Name
string str=LPCTSTR(sztmp);
str.insert(str.length(),"/0");
ret.push_back(str);
}
return ret;
}
以下是写文件:
void CDeskTopDlg::SaveXml()
{
if(m_bNeedSave)
{// TODO: Add your control notification handler code here
if(MessageBox("是否保存所作的修改","提示:",MB_YESNO)==IDNO)return;
MSXML2::IXMLDOMDocumentPtr pDoc;
MSXML2::IXMLDOMElementPtr xmlRoot,xmlSubTop,xmlSubNode;
//创建DOMDocument对象
HRESULT hr=pDoc.CreateInstance(_uuidof(MSXML2::DOMDocument40));
if(!SUCCEEDED(hr))
{
MessageBox("无法创建DOMDocument对象,请检查是否安装了MS XML Parser 运行库!");
return;
}
//根节点的名称为Book
//创建元素并添加到文档中
xmlRoot=pDoc->createElement((_bstr_t)"DeskTop-config");
pDoc->appendChild(xmlRoot);
int nTopLen=m_vecBtnName.size();
for(int i=0;i<nTopLen;++i)
{
xmlSubTop=pDoc->createElement((_bstr_t)"top");
xmlSubTop->setAttribute("id",m_vecBtnName[i].c_str());
TagVec vecTag=m_vecTagVec[i];
int nNodeLen=vecTag.size();
for(int j=0;j<nNodeLen;++j)
{
xmlSubNode=pDoc->createElement((_bstr_t)"node");
xmlSubNode->setAttribute("text",vecTag[j].strName.c_str());
xmlSubNode->setAttribute("path",vecTag[j].strPath.c_str());
xmlSubNode->setAttribute("ext",vecTag[j].strExt.c_str());
xmlSubTop->appendChild(xmlSubNode);
}
xmlRoot->appendChild(xmlSubTop);
}
CString strSavePath=m_strCurDir;
strSavePath+="//";
strSavePath+=XmlFileName;
hr=pDoc->save((LPCTSTR)strSavePath);
}
}
2.
根据文件关联打开文件:
首先在app里写:
CoInitialize(NULL);
EnableShellOpen();
然后是
::CoUninitialize();
然后是ShellExec(hWnd,"open","filefullname",NULL...)
打开.lnk文件:
打开.lnk文件
写个ResolveIt(...)
最后使用ResolveIt
HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPSTR lpszPath)
{
HRESULT hres;
IShellLink* psl;
char szGotPath[MAX_PATH];
char szDescription[MAX_PATH];
WIN32_FIND_DATA wfd;
*lpszPath = 0; // assume failure
// Get a pointer to the IShellLink interface.
hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl);
if (SUCCEEDED(hres)) {
IPersistFile* ppf;
// Get a pointer to the IPersistFile interface.
hres = psl->QueryInterface(/*&*/IID_IPersistFile,
(VOID**)&ppf);
if (SUCCEEDED(hres)) {
WCHAR wsz[MAX_PATH];
// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz,
MAX_PATH);
// Load the shortcut.
hres = ppf->Load(wsz, STGM_READ);
if (SUCCEEDED(hres)) {
// Resolve the link.
hres = psl->Resolve(hwnd, 0);
if (SUCCEEDED(hres)) {
// Get the path to the link target.
hres = psl->GetPath(szGotPath,
MAX_PATH, (WIN32_FIND_DATA *)&wfd,
SLGP_SHORTPATH );
// if (FAILED(hres) ;
// HandleErr(hres); // application-defined function
// Get the description of the target.
hres = psl->GetDescription(szDescription, MAX_PATH);
// if (FAILED(hres))
// HandleErr(hres);
lstrcpy(lpszPath, szGotPath);
}
}
// Release the pointer to the IPersistFile interface.
ppf->Release();
}
// Release the pointer to the IShellLink interface.
psl->Release();
}
return hres;
}