博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows Mobile和Wince下使用TinyXML进行Native C++的开发
阅读量:6136 次
发布时间:2019-06-21

本文共 6076 字,大约阅读时间需要 20 分钟。

背景

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

 

Mobile Radio项目可以参考:

 

简介

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

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

 

环境搭建

下载

请到 下载最新的release。

新建项目

新建Smart Device项目tinyXML。

 

点击Next

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

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

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

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

设置依赖性

 

在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配置文件的结构可以参考 。大体的文件结构是分两层,第一层是城市,第二层是具体的电台信息。

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 ()。

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
StationMap; //City -> Station typedef std::multimap
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
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控件播放该电台。

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

 

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

 

目前(2009年9月份)这个项目基本功能已经完成,只是界面方面需要改进,提高用户体验。我把项目host到 了,我会持续改进,主要是提高用户体验方面。
需要了解项目最新动态,可以访问 和我的Blog 。

 

源代码:

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

转载地址:http://zgkya.baihongyu.com/

你可能感兴趣的文章
怎么给视频添加音频或配乐
查看>>
怎么转换音乐格式
查看>>
Leaflet-Develop-Guide
查看>>
每隔1s打印0-5
查看>>
Angular6错误 Service: No provider for Renderer2
查看>>
聊聊flink的BlobStoreService
查看>>
洗牌算法具体指的是什么?
查看>>
HBuilder打包手机app的方法
查看>>
解决Mac下SSH闲时自动中断的问题
查看>>
在JavaScript中理解策略模式
查看>>
ArchSummit 深圳 2017 成功举办,探索未来互联网架构
查看>>
不知道如何提升深度学习性能?我们为你整理了这份速查清单
查看>>
Go 2提上日程,官方团队呼吁社区给新特性提案提交反馈
查看>>
技术绩效考量:你们可能都做错了
查看>>
“亲切照料”下的领域驱动设计
查看>>
除了输入法,移动端AI还有哪些想象空间?
查看>>
回家路上想起来关于Js一个有趣的东西
查看>>
B端大数据应用的架构实践与思考
查看>>
2019 SRE 调查报告:事故处理是主要工作,SRE 压力山大
查看>>
React创建组件的三种方式及其区别
查看>>