2009年4月18日星期六

【原】Boost库之program_options的使用

我们在编写程序时,有时需要解析命令行参数,比如小蜜蜂调用聊天历史记录程序,监视器调用日志管理程序等。遗憾的是,C++标准库并没有提供解析命令行参数的功能,我们必须自己来完成解析工作。如果命令行参数比较复杂,要正确地解析可能并不是一件容易的事情。即使解析正确了,代码也不一定具有通用性。那么,有没有一个封装好的功能强大而且简单易用的命令行解析类呢?答案是Boost库的program_options。

Boost库的program_options相对于手工编写代码解析命令行参数具有以下几个优点:
1.使用更容易。定义参数处理的语法简单,库自身很小,像转换参数值到指定的类型和保存参数值到变量的事情都由库自动处理。
2.错误报告更友好,可以报告错误的命令行参数。另外这个库能自动生成使用帮助,避免了手工更新使用帮助而导致的不一致。
3.参数能从不同地方读取。当命令行参数不能满足我们的要求时,可以改用配置文件。

下面介绍一下使用program_options解析命令行参数的具体用法。
首先声明一个options_description类的对象,该对象用于添加我们需要解析的选项名字。

options_description myOptions("command line options by hujian");
int nLevel;
myOptions.add_options()("help,h", "Use --help or -h to list all arguments")
("file", value<string>(), "Provide input file name")
("level", value<int>(& nLevel)->default_value(5);

其中,长选项名(比如“help”)必须在前面,短选项名(比如“h“)可有也可没有,如果有,必须紧跟在逗号之后。另外,还可以给选项名赋默认值。
添加好选项名字之后,就可以开始解析工作了。解析的结果保存在variables_map类型的对象中。

variables_map vmap;
// MFC中使用__argc和__argv
store(parse_command_line(argc, argv, myOptions), vmap);
notify(vmap);

其中,store函数可以调用多次,以将多个不同options_description的分析结果存入vmap中。解析工作完成之后,解析的结果就保存在vmap中。我们现在可以从vmap中获取想要的选项值了。

if (vmap.count("help"))
{
cout << myOptions << endl; // 打印出使用帮助
}
if (vmap.count("file"))
{
cout << "file is " << vmap["file"].as ( ) << endl;
}
cout << "level is " << nLevel << endl;

必须使用as来获得选项值;如果类型不符和,program_options会抛出异常。
总结一下,从上面的介绍可以看出,使用program_options来解析命令行还是非常方便的,推荐大家使用。

2009年4月15日星期三

【原】创世科技无线视频助阵电信3G业务新闻发布会——全国首例基于3G网络的外景视频直播

4月13日下午,安徽电信3G业务正式商用新闻发布会在五里墩电信大楼20楼演示大厅隆重举行,发布会上省电信领导向在场的几十家媒体展示了3G无线宽带的神奇魅力。手机网上观景,您足不出户,此时此刻黄山的美景尽收眼底;3G视频连线,外景记者无需庞大的卫星转播车,通过一个轻便的背包式3G无线视频终端将采访现场清晰流畅的声音和视频实时的传送到演播大厅。3G改变生活,每种应用都让人耳目一新,犹如置身于一个虚幻的世界。国内无线视频领域的领导者安徽创世科技为这些应用提供了便携终端、系统平台和现场技术支撑,展现了创世科技全球眼无线监控系统的强大魅力。

2009年4月12日星期日

【原】SuperMapObjects中最短路径分析的bug

最近在对以前SuperMapObjects最短路径代码进行了改动,用了一个成员变量 CsoPoints m_objPoints保存了设施点,结果在测试中发现最短路径分析时,得到的结果老是错误,看起来貌似最后一个添加的设施点没有在分析中起作用。于是在函数内下断点跟踪,发现经过一次路径分析后,果然是少了一个点。但是第一次分析的结果都是正确的,如果再次进行分析,则结果就是错误的。当然解决办法也是有的,就是每次分析时,都构造一个临时的CsoPoints对象传进去,这样才能保证每次的结果都正确。

【原】如何给Facilities图层添加元素

这里所说的Facilities图层是指Closest Facility图层的子图层,就是设施点图层。我上次在做最短路径分析时,得到了Facilities图层的接口,但是不知道如何给它添加元素。因为ILayer实现了IFeatureClass的接口,所以很容易就获取到IFeatureClass接口,但是是不是直接就Create一个Feature然后添加、保存上去呢?打开ArcMap,先看看它的属性,有ObjectID、PosAlong、SourceID、SourceOID、SideOfEdge等等,在帮助文档里找到了注释:SourceID是网络数据集上所定位到的图元的源ID,可以从INetworkSource::ID获得此ID;SourceOID是定位到的图元的对象ID;SideOfEdge是指在边的左侧还是右侧;PosAlong是指定位到的图元沿边的距离。要是一个字段一个字段的去计算,然后再添加,累死你,所幸ArcEngine提供了一个方法QueryLocationByPoint,可以帮我们完成这件事。
它的接口如下:HRESULT QueryLocationByPoint(IPoint* point,INALocation** Location,IPoint** outPoint,double* distanceFromPoint);AE帮助上是这种说的,Using the input Point object, the method calls QueryLocationByPoint on each of its associated NALocatorAgent classes. The corresponding NALocation, the point where the location was found, and the distance from the input point to the source feature found are all returned.
下面是实现代码
ILayerPtr ipLayer = m_map.GetLayer(0);
INALayerPtr ipNaLayer = ipLayer;
INAContextPtr ipNaContext;
HRESULT hr = ipNaLayer->get_Context(&ipNaContext);
INAClassLoaderPtr ipNAClassLoader(CLSID_NAClassLoader);
INALocatorPtr ipNALocator = NULL;hr = ipNaContext->get_Locator(&ipNALocator);
hr = ipNAClassLoader->putref_Locator(ipNALocator);
IPointPtr ipPoint;INALocationPtr ipNALocation(CLSID_NALocation);
ipNAClassLoader->get_Locator(&ipNALocator);
IPointPtr ipOutPoint(CLSID_Point);
double dbLVal = 0.0;
ipNALocator->QueryLocationByPoint(ipPoint, &ipNALocation, &ipOutPoint, &dbLVal);

2009年4月8日星期三

【原】模块间(dll, exe)使用导出变量、静态变量和外部变量的试验与结论

// Dll头文件声明

AFX_EXT_DATA int D1_nCount;

extern int D1_nCountE;

static int D1_nCountS = 0;

AFX_EXT_API int D1_GetCount();

// 结论:多模块调用时,或重复调用时,模块内的静态变量是唯一的,不会重复分配内存
int nCount = D1_GetCount();
nCount = D2_GetCount();
nCount = D1_GetCount();

// 结论:dll中声明的静态变量在每个使用的cpp下均有一份拷贝,多模块更是如此(静态变量在编译时会分别拷贝)
nCount = D1_nCountS;
D1_nCountS = 2;

// 结论:dll中声明的外部变量不能用于其他模块,链接失败(基地址都不一样,肯定不行)
nCount = D1_nCountE;
D1_nCountE = 2;

// 结论:dll中导出的数据到处都可以用,在模块内部只有一份拷贝,每个用到的模块各有一份拷贝
nCount = D1_nCount;
D1_nCount = 2;

其实上面有些结论是不太正确的,以下后续试验得出了新的结论:

// Dll头文件声明

#ifdef DLL2_EXPORTS
#define D2_API __declspec(dllexport)
#else
#define D2_API __declspec(dllimport)
#endif

D2_API extern int D2_nCount;

// 结论:dll中导出变量在其所在模块为导出,在其他模块必须为导入
// 结论:dll中导出的外部变量到处都可以用,在所有模块中都只有一份拷贝
// 结论:dll中导出的变量到处都可以用,在所有模块中都只有一份拷贝,
// 但是在其所在模块只能包含一次(否则为重定义),所以只能声明为外部变量

nCount = D2_nCount;
D2_nCount = 2;

// 总结论:dll中的变量一般情况下是以函数接口形式导出,
// 但在某些情况下可能需要在模块间直接使用,那么就有两种方法:
// 如果需要该变量在每个模块都有一份拷贝,那么可以使用static声明,
// 不过这种用途一般比较少。。还有就是使用__declspec(dllexport) extern声明,
// 一般都是需要各个模块公用一份拷贝,注意在其他模块使用时需要用
// __declspec(dllexport)导入该变量,否则就又是导出了,而且没有实现

2009年4月7日星期二

一些FLASH组件学习小结

1.关于命名:
在程序命令里,有些命令是几个单词都连接起来了,像createEmptyMovieClip,看起来很长,但你E文足够好,应该能看出来,这就是创建空的影片剪辑的英语,并且中间每个单词的第一个字母大写。Flash里边的变量名、属性 、方法、命令等等,基本都遵循这种规则。如果你希望写的程序看起来比较专业,同时还容易理解,希望一开始 就能养成良好的命名习惯,还有一点需要强调的是,flash是严格区分大小写的,所以,“myMc”和“mymc”并不 是一个东西,如果在调试中出现错误,也可以检查下这方面的问题。
2.组件样式的几种设置方法:

组件是一些组件和类的组合,有些样式是需要其它此类组件和资源中的资源,在这里讲下在非修改资源的组件样式定义。
A.对一个组件实例设置样式
这样的设置方法最直接和便捷,针对单个的组件会很方便,但也有一定的局限性,比如场景上有很多组件需要定义,就要定义不同的名称和样式了。
B.使用全局样式声明对文档的所有组件设置样式
如:_global.style.setStyle("themeColor", "0x00CCFF");这样的设置针对场景较多的组件定义会很便捷,as也很简洁明了。
C.创建自定义样式声明并应用到指定的组件实例
如:var styleObj = new mx.styles.CSSStyleDeclaration;styleObj.styleName = "newStyle";_global.styles.newStyle = styleObj;styleObj.fontFamily = "Verdana";//设置样式属性styleObj.fontSize = "10";styleObj.fontWeight = "bold";styleObj.color = "0x990000";styleObj.setStyle("themeColor", "0x00CCFF");
CompA.setStyle("styleName", "newStyle");//对组件设置样式(这里要说明下CompA,CompB,CompC是实例名)CompB.setStyle("styleName", "newStyle");CompC.setStyle("styleName", "newStyle");
D.为组件类别创建样式声明这种方法为场景内某一类型的组件定义样式,只对此类别有效。
如:var btn = _global.styles.Button=new mx.styles.CSSStyleDeclaration();//为Button类型定义btn.fontFamily = "Verdana";btn.fontSize = "12";btn.fontWeight = "bold";btn.color = "0x000000";var rb = _global.styles.RadioButton=new mx.styles.CSSStyleDeclaration();//为RadioButton类型定义rb.fontFamily = "Arial";rb.fontSize = "12";rb.fontWeight = "bold";rb.color = "0x003399";
3.常用的属性设置:
themeColor 主题颜色:如果对色彩样式配置不想过多的去设置的话,themeColor是一个选择。它可以让你选择一种基本色彩,然后组件的边框,外观等色彩将会以此色彩为基础构成一组缺省的样式,组件均可使用此样式属性。
arrow  设置滚动条和下拉菜单中箭头元件的颜色
background 设置列表框、组合框、单选钮和复选框组件背景部分的颜色 
backgroundDisabled 设置被禁用的列表框、组合框、单选钮和复选框组件背景部分的颜色
darkshadow 设置组件内边框和暗面阴影部分的颜色 
face  设置组件的主要颜色 
foregroundDisabled 设置被禁用的列表框、组合框、单选钮和复选框组件前景部分的颜色 
hinglight    设置当组件被选中时,其内边框和暗面阴影部分的颜色          
highlight3D 设置当组件被选中时,其外边框和亮面阴影部分的颜色 radioDot 设置单选钮被选中后其间中圆点的颜色
scrollTrack 设置滚动条中滚动槽的颜色
selection 设置列表框、组合框组件中选定项目的突出部分显示的颜色
selectionDisabled 设置被禁用的组件中选定项目的突出部分显示的颜色
selectionUnfocused 设置当组件不在焦点状态时,选定项目突出部分显示的颜色
shadow 设置组件外边框或亮面阴影部分的颜色 textAlign 设置组件中文字对齐的方式,其值有“right”、“left”和“center”
textBold 设置组件中文字是否使用粗体
textColor 设置组件中文字的颜色          
textDisabled 设置当组件被禁用时文本的颜色
textFont 设置组件中文字的字体名称
textIndent 设置组件中文字的缩进
textItalic 设置组件中文字是否使用斜体
textLeftMargin 设置组件中文本左边留白的宽度
textRightMargin 设置组件中文本右边留白的宽度
textSelected 设置列表菜单中被选定文本的颜色 textSize 设置组件中文字的大小
textUnderline 设置组件中的文字是否有下划线

2009年4月6日星期一

【原】引玉系列之AE特效——Shatter

在工作中经常会遇到文字特效的制作,以往多是使用flash软件,或者flash相关字体插件制作,这次尝试了一下After Effects的文字特效。
相关图片:

说明:
使用Shatter特效,重点是要掌握Shatter的各项参数作用和意义,以及做路径shatter的方法。由于可以使用预处理的图片,所以在文字样式上有相当灵活的选择。而且可以实现各种不同的shatter效果,甚至模拟合成较为真实的爆炸场面,运用在一些电影电视特效中。

引玉系列之UI设计心得

注:文中的一些观点和结论并非原创,只是做了分析整理。
UI的本意是用户界面,是英文User和interface的缩写,基本上分为三个方向,分别是:用户研究、交互设计、界面设计。
软件界面设计就像工业产品中的工业造型设计一样,是产品的重要卖点,一个友好美观的界面会给人带来舒适的视觉享受,拉近人与电脑的距离。界面设计不是单纯的美术绘画,它需要定位使用者、使用环境、使用方式并且为最终用户而设计,是纯粹的科学性的艺术设计。
界面设计里有一个很重要的组成部分,就是界面图标设计。图标设计在很大程度上决定了软件界面设计的好坏。
图标应该有趣,色彩丰富而且充满活力,因为系统支持32位图标,并且边缘非常光滑。图标设计要从三个方面考虑,创意,细节,整体性。
设计图标时,要使用已有概念以确保真实表达了用户的想法。考虑图标在用户界面环境中以何种形式出现,以及如何作为图标集的一部分使用。考虑图形的文化背景。避免在图标中使用字母、单词、手或脸。必须用图标表示人或用户时,请尽可能使其大众化。如果图标中的图像由多个对象组成,应考虑如何使图像尺寸更小。建议在图标中使用的对象不超过三个。对于 16×16的尺寸大小,还可考虑删除某些对象或简化图像使之更容易辨认。
XP系统下常用的图标尺寸有四种:
(1) 48×48像素
(2) 32×32像素
(3) 24×24像素
(4) 16×16像素。
图标样式的特性:
(1) 色彩丰富,是对WindowsXP外观的补充。
(2) 不同的角度和透视特性为图像增添了动态活力。
(3) 元素的边角十分柔和,并略微有些圆滑。
(4) 光源位于图标的左上角,同时有环绕光照亮图标的其它部分。
(5) 渐变效果使图标具有立体感,进而使图标的外观更加丰满。
(6) 投影使图标更具对比度和立体感。
(7) 添加轮廓可使图像更清晰。
(8) 日常对象(如计算机和设备)具有更现代化的个人外观。
在Denis Kortunov的文章里描述了图标设计中比较容易犯的一些错误,在我们的设计中,应该要尽量避免:
1. 图标之间没有明显的差异化(太相似,难以辨识)
2. 在一个图标中设计了太多的元素(windows vista的图标是反面教材)
3. 加入不必要的元素
4. 一套图标中的图标统一性不足(颜色主题,透视角度,尺寸,绘图技法等)
5. 在小图标中(24X24以下)使用不必要的透视和阴影
6. 过度原创使语义不明确(比如将回收站设计成碎纸机的样式)
7. 国家区域和文化特征没有被考虑进设计中
8. 在图标中使用纯界面化的元素(比如泛滥的mac aqua效果,用户会认为你的产品是苹果的产品)
9. 在图标内部使用文字(特别是不容易辨识的)
10. 图标外部边缘没有做像素化处理

2009年4月4日星期六

【原】Boost库之function的使用

Boost库的function是一组函数对象包装类的模板,实现了一个泛型的回调机制。Boost库的function与函数指针相比,优点在于它允许用户在目标的实现上拥有更大的弹性,即目标既可以是普通函数(自由函数),也可以是函数对象和类成员函数,而且可以给函数添加状态。

使用Boost库的function,可以很好地与现有的代码融合在一起。另外,function还可以与Boost库的bind和lambda配合使用,从而极大地扩展了function的适用范围。function库支持的函数参数个数最多为10个,其头文件为function.hpp或functionX.hpp(其中,X为0到10之间的整数)。如果你的程序中只使用了X个参数的function,那么你可以只包含对应的functionX.hpp,当然,你也可以只包含function.hpp(它包含了所有的functionX.hpp)。
下面介绍function库的具体用法。

◆ 普通函数(自由函数)用法
int Add(int x, int y)
{
return x+y;
}
function<int (int,int)> f; // 或者 function2<int, int, int> f;
f = Add;
cout << "f(2, 3)=" << f(2, 3) << endl;
其中,模板参数的第1个int为返回值类型,后两个int为参数类型。

◆ 函数对象用法
class CStudent
{
public:
void operator() (string strName, int nAge)
{
cout << strName << " : " << nAge << endl;
}
};
function<void (string, int)> f; // 或者 function2<void, string, int> f;
CStudent stu;
f = stu;
cout << "f(\"hello\", 25)=" << f("hujian", 25) << endl;

◆ 成员函数用法
struct TAdd
{
int Add(int x,int y)
{
return x+y;
}
};
TAdd tAdd;
function<int (tAdd *,int,int)> f; // 或者 function<int (tAdd &,int,int)> f;
f = & TAdd::Add;
cout << f(&tAdd, 2, 3); // 如果前面的模板参数为值或引用,直接传入tAdd即可
其中,模板参数的tAdd *为类的实例的指针,当然也可以传入类的实例或其引用,只不过调用时需要做相应的修改。

使用function时,可以通过empty函数或与0比较来判断其是否指向一个有效的函数。如果function没有指向一个有效的函数,调用时会抛出bad_function_call的异常。function的clear函数可以使其不再关联到一个函数或函数对象,如果该function本身就是空的,调用该函数也不会带来任何问题。
以上介绍了function库的最基本的一些用法,关于function库的其他应用,大家可以参考《Beyond the C++ STL》。

2009年4月1日星期三

常用HTML转义符

在blogger里发贴、修改网页模板的时候,经常需要将一些符号转义才能正常显示,blogger这点确实非常不便...这里给出一个常用HTML转义符的参考:http://114.xixik.com/character/