65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ATL COM 的可扩展汽车描述格式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (6投票s)

2011 年 4 月 6 日

CC (ASA 3U)

12分钟阅读

viewsIcon

41821

downloadIcon

851

介绍了 XCD 格式,该格式将汽车描述为按品牌和年份分组的集合,并提供了一个移植到 COM 库中的 API 来访问这些集合。

引言

您将如何选择一辆私家车?大约有 50 家主要汽车制造商提供有关其车型的逐车信息,还有专门的网站。将一个文件集中包含特定制造商在特定年份发布的所有汽车的图片和描述,是否会节省时间和方便?例如,当您对本田 2011 年发布的汽车感兴趣时,您只需要下载一个文件,就可以在您选择的平台上在线或离线分析规格。本文假定答案是肯定的,并定义了一种可扩展汽车描述或 XCD 格式,用于描述汽车集合中的汽车,该格式按品牌(汽车制造商)和年份进行分组,以便任何扩展名为 .CAR 的文件都包含所有相关的图片和快速规格。本文提供了一个 API,用于在任何兼容 Win32 的平台上浏览 CAR 文件。实际上,一组代表所有汽车制造商的 CAR 文件体积小巧,并且易于在任何桌面或移动平台上进行浏览和分析。读取 CAR 文件的程序示例随下载提供。

目录

背景

按年份和品牌分组的汽车图片和快速规格集合用于 Car Explorer 程序,该程序提供了一个免费下载 CAR 文件的接口。

XCD 格式详细描述了一种将一组通用图像和描述保存在一个文件中的格式。后者自 2005 年以来已在 MSB LLC 发行的多个应用程序中使用。

XCD 设计目标

XCD 格式描述了 CAR 文件的内容。XCD 的设计目标是:

  1. 一个 CAR 文件应描述一个品牌和一年的所有汽车(当前版本不包括子车型)。
  2. 有效的 CAR 文件应包含所有汽车型号的图片和快速规格(自 XCD v1.1 起)。
  3. 有效的 CAR 文件应至少包含一个汽车描述。
  4. 汽车描述以摘要形式提供,根据 XML 格式的单个汽车描述。
  5. 任何 CAR 文件都应在使用的应用程序中提供唯一的字符串标识符。
  6. 在应用程序范围内,CAR 文件中的任何汽车型号都应具有唯一的字符串标识符(可以是年份加上图片标题或程序化的)。
  7. XCD 应支持在 CAR 文件中添加、编辑和删除汽车图片和描述。
  8. 保持有效的 CAR 文件体积小巧,通常小于 1 MB。
  9. XCD 格式至少被一家汽车制造商接受。
  10. 免费共享 CAR 文件。

从目标 1 得出:

  1. 任何 XCD 集合中的所有汽车都属于同一品牌和同一年份,并且
  2. 由于品牌相同,集合中的所有汽车都属于同一国家,不考虑同一品牌可能在不同国家生产的情况。

从目标 2 得出:

  1. 如果一个型号在一个集合中缺失,则该集合不是有效的 CAR 文件。
  2. 如果一个型号在一个集合中缺少图片,或者缺少或不完整的快速规格,则该集合不是有效的 CAR 文件。

请注意,“所有汽车型号”是指包含不同型号的汽车,但不包括不同配置、颜色、不同发动机或可选设备。

从目标 5 和 6 得出:如果标识符不符合设计目标,则 CAR 文件无效

事实上,第三个设计目标是第 1 条和第 2 条的结果。

使用术语

在本文档中,“CAR 文件”和“集合”的含义与 XCD 设计目标中所述相同。“should”、“required”、“shall”、“optional”等词的解释应按照 RFC 2119 中的描述进行。

示例应用程序

本文随附的示例应用程序(MFC、C#、VB)使用 VS 2008 开发,允许您读取 CAR 文件。它们本质上具有相同的视觉界面(MFC 示例具有额外的可扩展功能),并使用名为 XCD.dll 的 ATL COM 库(也使用 VS 2008 开发)来访问 CAR 文件中的数据。任何与自动化兼容的客户端都可以访问 XCD 库的功能。首先构建 XCD_COM 项目(如果复制了 XCD.dll - 使用 regsvr32 注册它,但在注册之前,如果您的目标系统未安装 Microsoft Visual C++ 2008,您可能需要运行 Microsoft Visual C++ 2008 SP1 可再发行组件包),然后构建使用 XCD 库的 XCD_Client_MFC 项目。您将在下载中找到 Peugeot_2011.car 示例集合,并且可以从 Car Explorer 网站下载其他 CAR 文件。这是 XCD_Client_MFC 应用程序的对话框。

首先,单击“选择 CAR 文件”按钮从目录中选择一个 CAR 文件。对话框的“集合”区域显示有关 CAR 文件作为集合的信息,例如集合标题、集合中的图像数量、集合版本。“汽车”区域显示有关集合中特定汽车的信息:使用旋转控件选择集合中的下一项。集合中的每辆汽车都有一个图像;单击“显示图片”按钮查看该项的图像。从 XCD v1.1 开始,集合中的每辆汽车都标记有快速规格详细信息。从组合框中选择汽车详细信息,然后单击“获取值”按钮以查看其值。组合框中的项被称为标签,因为汽车技术描述可以表示为 XML 文件(XCD 也代表 XML 汽车描述)。

MFC 示例应用程序具有其他功能。“获取数据”按钮位于单击“更多”按钮时显示的对话框底部可扩展区域,它提供了通过一次调用获取集合中汽车所有技术信息的替代方法。通过单击“显示图例”按钮可见的右侧可扩展区域指示了左侧区域中所有相关调用的函数原型。

对象模型

XCD 库提供读取 CAR 文件中数据的方法。如下图所示,它是一个 COM DLL,包含两个对象:Collection 和 Car。

Collection 对象用于访问有关整个集合的信息。客户端应用程序应在使用对象的方法之前,使用 FFN 属性设置集合的位置,其中 FFN 代表 CAR 文件的完整文件名。Collection 对象被单独放在 Car 对象之外,作为一个不同的实体,这是因为有些应用程序只需要读取集合的通用信息,例如其标题(字符串 ID)、版本字符串,或验证文件是否为 CAR 文件。

Car 对象的方法用于读取集合中特定汽车的信息,例如汽车图片(GetPicture)、汽车规格的特定功能(GetValue),或一次性获取整个汽车规格(GetData)。由于每个 Car 对象方法都读取 Collection 对象中设置的 FFN 字符串,或如图中所示“使用”Collection 对象,因此必须先创建 Collection 对象,然后才能创建 Car 对象。技术上,您可以创建 Car 对象而不创建 Collection 对象,但这没有意义,因为如果没有 Collection 对象,就无法设置 CAR 文件的位置。这种逻辑关系(组合聚合)用黑色菱形表示。

与您的应用程序集成

任何与自动化兼容的语言都可以使用 XCD 库来访问其对象的成员和属性。由于 Car 对象的方法读取 Collection 对象中设置的 FFN 字符串,因此必须先创建 Collection 对象,然后再创建 Car 对象,如下所示。

C++

' Import description of the XCD library as XCD.tlb from XCD's COM project.
#import "XCD.tlb" no_namespace, raw_interfaces_only

CoInitialize(NULL);

m_pCollection = NULL;
CoCreateInstance(__uuidof(Collection), NULL, CLSCTX_INPROC_SERVER, 
                __uuidof(ICollection), reinterpret_castvoid**>(&m_pCollection));

' Set the location of CAR file.
CComBSTR bstrFFN(
             "C:\\Documents and Settings\\I'm\\My Documents\\Peugeot_2011.car");
m_pCollection->put_FFN(bstrFFN.m_str);

m_pCar = NULL;
CoCreateInstance(__uuidof(Car), NULL, CLSCTX_INPROC_SERVER, 
                             __uuidof(ICar), reinterpret_cast<void** />(&m_pCar));

结果是获得了 Car 对象方法的 m_pCar 指针。请注意,#import 语句使用了 raw_interfaces_only 属性来处理具有相对 HRESULTXCD API。如果删除该属性,您将直接获得返回值。例如,而不是

BSTR bstrCollectionTitle;
HRESULT hr = m_pCollection->GetTitle(&bstrCollectionTitle);

您应该写

BSTR bstrCollectionTitle = m_pCollection->GetTitle();

有关详细信息,请参阅下载中的 XCD_Client_MFC 示例。

C#

假设已在项目设置中设置了对 XCD 库的引用,则可以按以下方式获取对其对象的引用。

private XCD.Collection objCollection;
private XCD.Car objCar;

objCollection = new XCD.Collection();

' Set the location of CAR file.
objCollection.FFN = 
         "C:\\Documents and Settings\\I'm\\My Documents\\Peugeot_2011.car";

objCar =  new XCD.Car();

有关详细信息,请参阅 XCD_Client_CS 示例。

VB

假设已在项目设置中设置了对 XCD 库的引用,则可以按以下方式获取对其对象的引用。

Dim objCollection As XCD.Collection ' enables IntelliSense
Dim objCar As XCD.Car ' enables IntelliSense

objCollection = New XCD.Collection

' Set the location of CAR file.
objCollection.FFN = 
    "C:\\Documents and Settings\\I'm\\My Documents\\Peugeot_2011.car"

objCar = New XCD.Car

请注意,在 VB 中引用对象有几种方法,也可以这样创建:

Dim objCollection As Object
objCollection = CreateObject("XCD.Collection")

Dim objCollection = New XCD.Collection

但是,如果您想在键入时看到 IntelliSence 上下文帮助,则应使用第一种方法,称为早期绑定。有关详细信息,请参阅 XCD_Client_VB 示例。

XCD API

下表列出了 XCD 中实现的成员和属性。对于字符串,使用 BSTR 类型以支持 XCD 与 C++ 以外的语言的互操作性。换句话说,XCD 支持自动化。所有方法都返回 HRESULT 值作为 COM 的默认返回类型。请注意,快速规格自 XCD v1.1 起可用;如果 GetXCDVersion 返回空字符串(表示 XCD v1.0),则只能获得汽车图片和标题。

对象 函数原型 描述
Collection put_FFN(BSTR bstrFFN /* in */) 设置要读取的 CAR 文件的完整文件名。
GetTitle(BSTR* pbstrTitle /* out */) 读取集合的标题。
GetCount(USHORT pnCount /* out */) 读取集合中项目的数量(汽车数量)。
GetVersion(BSTR* bstrCollectionVersion /* out */) 读取集合的版本。
GetXCDVersion(BSTR* pbstrXCDVersion /* out */) 读取 XCD 格式的版本。
IsCarFile(VARIANT_BOOL* pbCarFile /* out */) 验证集合是否为 CAR 文件。
Car GetPictureTitle(USHORT nItem /* in */, BSTR* pbstrTitle /* out */) 读取集合中第 nItem 辆汽车的图片标题。
GetPicture(USHORT nItem /* in */, IPicture** ppPicture /* out */) 返回指向接收第 nItem 辆汽车的 IPicture 接口指针的指针变量的地址,其中 IPicture 是标准的 COM 接口,可以获取有关图片的信息(get_Widthget_Height)并在指定的设备上下文中绘制图片(Render)。
GetValue(USHORT nItem /* in */, BSTR bstrTag /* in */, BSTR* pbstrValue /* out */)

读取集合中第 nItem 辆汽车规格中指定标签(bstrTag)的值。bstrTag 的可能名称包括:Year、Make、Model、Submodel、Type、Price、Country、Length、Width、Height、Weight、Power、Fuel、Clearance、Tank Volume。

此函数有一个缺点,即要读取一辆汽车的所有数据,需要进行十多次不同 bstrTag 名称的调用。为了通过一次调用获取整个规格,请改用 GetData

GetData(USHORT nItem /* in */, VARIANT* pData /* out */) 返回指向 VARIANT 结构的指针,该结构包含一个 SAFEARRAY 数据,代表集合中第 nItem 辆汽车的快速规格。

XML 汽车描述

汽车描述可以采用 XML 形式。XCD 格式以两种形式描述汽车。

快速 XML 描述

第一种形式采用汽车的快速技术规格,并根据下表(自 XCD 1.1 版本起)将其放入 XML 中。

Tag 描述
摘要 年份 指定汽车制造的年份。
Make 指定汽车制造商。
模型 指定汽车的型号。
SubModel 指定汽车的子型号,通常称为配置。
类型 指定汽车的车身类型,例如轿车、跑车、敞篷车、SUV 等。
价格 指定汽车的美元建议零售价 (MSRP),其中 MSRP 是制造商建议零售价。
国家 指定汽车制造的主要国家。
Measures 长度 指定汽车的长度(英寸)。
宽度 指定汽车的宽度(折叠后视镜)的英寸。
高度 指定汽车的高度(英寸)。
权重 指定汽车的整备质量(磅)。
Engine 指定发动机的马力。
Fuel 指定发动机使用的燃料类型,例如汽油、柴油等。
杂项 Clearance 指定汽车的离地间隙,即汽车最低点与路面之间的距离。
Tank_Volume 指定汽车油箱的容量(加仑)。

扩展 XML 描述

XCD 的第二种形式扩展了第一种形式的单个汽车的 XML 描述,并以扩展 XML 形式描述集合中的所有汽车。

<?xml version="1.0" encoding="Windows-1252"?>
<XCD>
<Collection>
  <Title>Peugeot 2011</Title>
  <Version>1.0</Version>
  <XCD_Version>1.1</XCD_Version>
</Collection>

<Car id="2011_Peugeot_207_CC">
<Summary>
  <Year>2011</Year>
  <Make>Peugeot</Make>
  <Model>207 CC</Model>
  <SubModel>Sport</SubModel>
  <Type>Convertible</Type>
  <Price>$27,678</Price>
  <Country>France</Country>
</Summary>

<Measures>
  <Length>159.20</Length>
  <Width>68.90</Width>
  <Height>55.00</Height>
  <Weight>2,959</Weight>
</Measures>

<Engine>
  <Power>120</Power>
  <Fuel>Gas</Fuel>
</Engine>

<Miscellaneous>
  <Clearance>No data</Clearance>
  <Tank_Volume>13.21</Tank_Volume>
</Miscellaneous>
</Car>

<Car id="2011_Peugeot_NextModel">
<!-- Next car in the collection -->
</Car>
</XCD>

这样,XCD 在其标题区域的 <Collection></Collection> 标签之间描述一个集合(CAR 文件),并在其主区域中根据 XCD 的第一种形式枚举集合中的所有汽车。此外,汽车的图片标题(加上年份)作为 XCD 文档中汽车的字符串 ID,例如 <Car id="2011_Peugeot_207_CC">。您可以在下载中看到两种形式的 XCD 文档示例。

浏览和分析集合

可以使用哪些应用程序打开和读取 CAR 文件?首先,从程序员的角度来看,您可以使用下载中提供的示例,并根据本文档的 XCD 描述按需进行定制。其次,作为用户,您可以使用 Car Explorer 程序,该程序具有更完善的界面,可以比较和分析不同集合中的汽车,并且还提供了一个免费下载 CAR 文件的接口。您能否编辑或创建 CAR 文件?是的,MSB Wizard(提供 Windows 7、Vista、Windows XP 版本)允许您执行此操作(只需将 CAR 扩展名重命名为 MSS 即可编辑,然后将其重命名回 CAR 以便与 Car Explorer 一起查看)。

结论和许可

有些事情需要比其他事情更谨慎。这绝对与汽车有关,尤其是在做出决定的时候。但是,一个人如何选择她或他最喜欢的汽车?他或她有什么选择?假设一个特定年份的汽车制造商发布的所有汽车的基本信息都保存在一个文件中,遵循统一的格式并且易于访问,那么当您对特定年份的特定品牌感兴趣时,您只需下载一个文件即可进行分析和决策。还有什么比这更简单?

本文描述了 XCD 格式的规范,该格式有助于回答这些问题。XCD 描述和本文下载提供的代码均在 Creative Commons 许可下获得许可,该许可允许在非商业和商业基础上基于此作品进行构建,条件是您注明出处。

Creative Commons License

本文所述的 CAR 文件或集合应免费共享,出售它们违反了相关条款。

© . All rights reserved.