Windows Mobile和Wince下使用TinyXML进行Native C++的开发

简介:

背景

继续讲述Mobile Radio项目的开发,上回讲到如何把自于 www.1radio.com.au 网站的电台数据从JSON转换成XML。这回讲述使用tinyXML在windows mobile下进行XML的开发。

 

Mobile Radio项目可以参考:

Windows Mobile和Wince下的WTL(Windows Template Library)开发

Windows Mobile 和 Wince 下的 WTL(Windows Template Library) 界面开发

Windows Mobile和Wince下使用WTL进行Windows Media Player开发

转换Json到XML的JavaScript实现

 

简介

XML已经成为流行的数据保存和交换的格式,本文讲述如何使用TinyXML在Windows Mobile下进行XML的开发。TinyXML是简单,轻装,跨平台的原生C++ xml解释器,可以十分简便的整合到其他系统中。同时TinyXML提供完整的在线文档,方便开发和使用。目前,由于其简便性和稳定性,使用ZLib license(可以用于开源和商业)等原因,TinyXML已经广泛被用于开源社区和商业系统中。

关于更多TinyXML的介绍请看下面链接:

http://sourceforge.net/projects/tinyxml/

http://www.grinninglizard.com/tinyxml/index.html

http://www.grinninglizard.com/tinyxmldocs/index.html

 

环境搭建

下载

请到http://sourceforge.net/projects/tinyxml/ 下载最新的release。

新建项目

tinyxml1

新建Smart Device项目tinyXML。

 tinyxml2

点击Next

tinyxml3

选择平台,这里选择Windows Mobile 6 Professional SDK。

tinyxml4

选择生成静态库,不需要MFC支持和不需要生成预编译文件,点击完成。

tinyxml7

tinyxml5

把下载的TinyXML源代码文件(包括CPP和H文件)拷贝到项目目录下。

tinyxml9

把源代码文件(包括CPP和H文件)添加到项目中。

设置依赖性

tinyxml6 

在Project –> Project Dependencies设置项目依赖性,Mobile Radio依赖于TinyXML。

如果使用在Windows Mobile环境下,需要更改下面的代码。

// Microsoft compiler security
FILE* TiXmlFOpen( const char* filename, const char* mode )
{
//#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
// FILE* fp = 0;
// errno_t err = fopen_s( &fp, filename, mode );
// if ( !err && fp )
// return fp;
// return 0;
//#else
// return fopen( filename, mode );
//#endif
return fopen( filename, mode );
}

tinyxml.cpp文件

//#define TIXML_SAFE
#define TIXML_SSCANF sscanf

tinyxml.h文件

环境搭建完毕。

使用

使用TinyXML是一个愉悦的过程,所有使用的例子都可以在源代码的xmltest.cpp文件里面找到。所以强烈建议学习和使用TinyXML前先认真阅读xmltest.cpp的代码。

简单讲一下XML文件的结构,XML的结构就是层次性(Hierarchy)文件,包含Element(节点)和Attribute(属性),下面我保留英文,因为TinyXML的接口就也是使用同样的术语。Element就是节点,可以包含Attribute和子Element(Child Elements),Attribute就是Element的属性。

下面是Mobile Radio使用TinyXML的代码。

#include "include/tinyXML/tinyXML.h"

使用TinyXML只需要引用一个头文件就可以了。

const char* CONFIGPATH = "Config\\Stations.xml";
void CMobileRadioView::LoadConfig()
{
std::string p = GetCurrentPath() + std::string(CONFIGPATH);
TiXmlDocument document = TiXmlDocument(p.c_str());
if(!document.LoadFile())
{
MessageBox(L"Can not open the config file.");
return;
}

TiXmlHandle docHandle(&document);
TiXmlElement* cityElement = docHandle.FirstChild("stations").FirstChild("city").Element();
Station* station;
std::string city;
while (cityElement)
{
city = cityElement->Attribute("name");
TiXmlElement* stationElement = cityElement->FirstChildElement("station");
while (stationElement)
{
station = new Station();
station->City = city;
station->Id = atoi(stationElement->Attribute("sid"));
station->Name = stationElement->Attribute("name");
station->Image = stationElement->Attribute("image");
station->Stream = stationElement->Attribute("stream");
station->Website = stationElement->Attribute("website");

stationMap[station->Id] = station;
cityStationMap.insert(CityStationMap::value_type(station->City, station));
stationElement = stationElement->NextSiblingElement();
}
cityElement = cityElement->NextSiblingElement();
}
}

这是读取XML配置的代码,XML配置文件的结构可以参考 转换Json到XML的JavaScript实现 。大体的文件结构是分两层,第一层是城市,第二层是具体的电台信息。

TiXmlDocument document = TiXmlDocument(p.c_str());
if(!document.LoadFile())
{
MessageBox(L"Can not open the config file.");
return;
}

把XML配置文件加载到TiXmlDocument里。

TiXmlHandle docHandle(&document);

根据TiXmlDocument生成TiXmlHandle。

TiXmlElement* cityElement = docHandle.FirstChild("stations").FirstChild("city").Element();

TinyXML不直接支持XPath,所以只能一层层读,从根节点逐层查找。如果需要XPath支持,可以参考TinyXPath (http://tinyxpath.sourceforge.net)。

while (cityElement)
{
city = cityElement->Attribute("name");
TiXmlElement* stationElement = cityElement->FirstChildElement("station");
while (stationElement)
{
station = new Station();
station->City = city;
station->Id = atoi(stationElement->Attribute("sid"));
station->Name = stationElement->Attribute("name");
station->Image = stationElement->Attribute("image");
station->Stream = stationElement->Attribute("stream");
station->Website = stationElement->Attribute("website");

stationMap[station->Id] = station;
cityStationMap.insert(CityStationMap::value_type(station->City, station));
stationElement = stationElement->NextSiblingElement();
}
cityElement = cityElement->NextSiblingElement();
}

循环取出城市(City)和电台(Station)信息,FirstChildElement()查找第一个子Element。NextSiblingElement()用于读取同一层的兄弟Element,Attribute可以取出Element的Attribute。关于更多的读取例子,请看xmltest.cpp的代码。

上述例子把XML配置信息读取到C++的map和multimap里面。这两个容器的定义如下:

//Id -> Station
typedef std::map<int, Station*> StationMap;

//City -> Station
typedef std::multimap<std::string, Station*> CityStationMap;

StationMap保存ID和电台信息,一对一。CityStationMap保存城市和电台信息,一对多。

界面处理

两个容器初始化完毕以后,界面可以根据容器的信息生成。

for(CityStationMap::iterator it=cityStationMap.begin();
it!=cityStationMap.end(); ++it)
{
if(city.compare(it->first) != 0)
{
city = it->first;
CString c = city.c_str();
m_wndCity.AddString(c);
}
}

根据配置信息显示城市下拉框,由于multimap不支持直接把所有的key的集合读取出来,所以需要遍历,把不同的城市信息显示到m_wndCity下拉框中。

LRESULT CMobileRadioView::OnComboCityCbnSelChange(WORD wNotifyCode, WORD wID, HWND hWndCtl)
{
CString str;
int sel = m_wndCity.GetCurSel();
m_wndCity.GetLBText(sel, str);
m_wndStation.ResetContent();

std::string city = CT2CA(str);
unsigned int i = 0;
for(CityStationMap::iterator it=cityStationMap.find(city);
it!=cityStationMap.end() && i<cityStationMap.count(city); ++it,++i)
{
CString s = it->second->Name.c_str();
int index = m_wndStation.AddString(s);
m_wndStation.SetItemData(index, it->second->Id);
}
return 0;
}

当城市下拉框的选择发生改变时,根据multimap的信息显示该城市下的电台信息。

LRESULT CMobileRadioView::OnComboStationCbnSelChange(WORD wNotifyCode, WORD wID, HWND hWndCtl)
{
int sel = m_wndStation.GetCurSel();
int id = (int)m_wndStation.GetItemData(sel);
//CString image = (GetCurrentPath() + "Image\\" + stationMap[id]->Image).c_str();
//m_wndPic.SetBitmap(LoadBitmap(NULL, image));
m_spWMPPlayer->put_URL(CComBSTR(stationMap[id]->Stream.c_str()));
return 0;
}

当电台下拉框的选择发生改变时,根据map的信息使用Windows Media Player控件播放该电台。

tinyxml10

下一次讲述程序如何支持accelerometer(重力感应器)。

 

关于Mobile Radio - Internet Radio Software for Windows Mobile项目

 

目前(2009年9月份)这个项目基本功能已经完成,只是界面方面需要改进,提高用户体验。我把项目host到 Mobile Radio - Internet Radio Software for Windows Mobile 了,我会持续改进,主要是提高用户体验方面。

需要了解项目最新动态,可以访问 Mobile Radio - Internet Radio Software for Windows Mobile  和我的Blog  精简开发 无线生活

 

源代码: 查看Mobile Radio最新源代码

环境:VS2008 + WM 6 professional SDK + WTL 8.1 + TinyXML



    本文转自Jake Lin博客园博客,原文链接:http://www.cnblogs.com/procoder/archive/2009/07/21/Windows_Mobile_TinyXML.html,如需转载请自行联系原作者


相关文章
|
5月前
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。
|
8月前
|
IDE 开发工具 C语言
C++一分钟之-嵌入式编程与裸机开发
通过这些内容的详细介绍和实例解析,希望能帮助您深入理解C++在嵌入式编程与裸机开发中的应用,提高开发效率和代码质量。
196 13
WK
|
10月前
|
机器学习/深度学习 人工智能 算法
那C++适合开发哪些项目
C++ 是一种功能强大、应用广泛的编程语言,适合开发多种类型的项目。它在游戏开发、操作系统、嵌入式系统、科学计算、金融、图形图像处理、数据库管理、网络通信、人工智能、虚拟现实、航空航天等领域都有广泛应用。C++ 以其高性能、内存管理和跨平台兼容性等优势,成为众多开发者的选择。
WK
464 1
|
11月前
|
Rust 资源调度 安全
为什么使用 Rust over C++ 进行 IoT 解决方案开发
为什么使用 Rust over C++ 进行 IoT 解决方案开发
272 7
|
12月前
|
物联网 C# C语言
物联网开发中C、C++和C#哪个更好用
在物联网(IoT)开发中,C、C++和C#各有优缺点,适用场景不同。C语言性能高、资源占用低,适合内存和计算能力有限的嵌入式系统,但开发复杂度高,易出错。C++支持面向对象编程,性能优秀,适用于复杂应用,但学习曲线陡峭,编译时间长。C#易于学习,与.NET框架结合紧密,适合快速开发Windows应用,但性能略低,平台支持有限。选择语言需根据具体项目需求、复杂性和团队技术栈综合考虑。
WK
|
10月前
|
开发框架 移动开发 Java
C++和Java哪个更适合开发移动应用
本文对比了C++和Java在移动应用开发中的优劣,从市场需求、学习难度、开发效率、跨平台性和应用领域等方面进行了详细分析。Java在Android开发中占据优势,而C++则适合对性能要求较高的场景。选择应根据具体需求和个人偏好综合考虑。
WK
292 0
WK
|
10月前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
357 0
|
11月前
|
NoSQL API Redis
如何使用 C++ 开发 Redis 模块
如何使用 C++ 开发 Redis 模块
|
API C++ Windows
windows C++ 多任务并发执行设计
windows C++ 多任务并发执行设计
windows C++ 多任务并发执行设计
|
4月前
|
安全 数据安全/隐私保护 虚拟化
Windows Server 2022 中文版、英文版下载 (2025 年 5 月更新)
Windows Server 2022 中文版、英文版下载 (2025 年 5 月更新)
681 2