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/

2009年3月31日星期二

【原】Boost库之assign的使用

Boost库的assign可以帮助我们把一系列的值赋给容器,并且语法更加清晰和简洁。下面我主要以vector和map容器为例,介绍assign中比较常用的赋值方法。其他容器的赋值方法与此类似,故不再赘述。

1. 使用重载操作符+=
vector<int> vctTemp;
vctTemp += 1, 2, 3;
// 打印出1,2,3
copy(vctTemp.begin(), vctTemp.end(), ostream_iterator<int>(cout, " "));

2. 使用push_back
push_back(vctTemp)(4)(5)(6); 或者
push_back(vctTemp) = 4, 5, 6;
另外,如果某容器有push_front函数,也可以使用assign中对应的push_front。

3. 使用list_of
vector<int> vct2 = list_of(7)(8) (9); 或者
vector<int> vct2 = list_of(7)(8) (9) .to_container(vct2);
array<int, 3> ay = list_of(1)(2)(3); 或者
array<int, 3> ay = list_of(1)(2)(3) .to_array(ay);
stack<int> sk = list_of(1)(2)(3).to_adapter(sk);
注意:用list_of给容器适配器赋值时,必须使用to_adapter,否则无法编译通过。

4. 使用tuple_list_of
vector<tuple<int, string, int> > vctTuple = tuple_list_of(1, "hi", 2)(3, "hu", 4);
BOOST_ASSERT(get<1>(vctTuple[1]) == "hu");

5. 使用repeat
push_back(vctTemp)(7)(8)(9).repeat(3, 10);
其中repeat函数的第1个参数为重复的次数,第2个参数为参数的值。

6. 使用range
push_back(vctTemp)(7)(8)(9).range(vct2.begin(), vct2.begin()+2);
其中range(iterBegin, iterEnd)函数使用的数值范围为[iterBegin, iterEnd)。

7. 使用insert
map<int, string> mapTemp;
insert(mapTemp)(1, "Hello")(2, "world")(3, "crearo");

8. 使用map_list_of(只能用于map容器)
map<string, int> map2 = map_list_of("hefei", 1)("nanjing", 2)("wuhan", 3);

2009年3月30日星期一

【原】设计3+2之认识粒子

3D中有着很炫很吸引人的一项功能就是粒子系统,它在模仿自然现象、物理现象及空间扭曲上具备得天独厚的优势。(烟云、火花、爆炸、暴风雪或者瀑布、雨、雪、流水和灰尘等)随着功能的逐步完善,粒子系统几乎可以模拟任何富于联想的三维效果,同时为了增加物理现象的真实性,结合了空间扭曲能对粒子流造成引力、阻挡、风力等仿真影响。使其更加震撼我们的眼球。目前,粒子系统技术被广泛用于电影、电视及大型3D游戏地制作。还记得《蜘蛛侠3》中的可以随意变换并操控沙子的沙人吗,《指环王》里大型的战争场面,《最终幻想》中美幻的空间场景吗....
可以说你的想象力就是三维创作的领域!

放个很土很山寨的粒子尝试:

2009年3月29日星期日

【原】ArcGIS中最短路径的实现(二)

上次介绍了用几何网络实现的“最短路径”,姑且这么叫吧。这次我们用网络数据集实现真正的最短路径功能,跟上次一样,我们先准备数据。
  1. 先打开ArcCatalog,连接到目标文件夹,假定该文件下有一个名为road的道路图层。
  2. 在road图层上右键新建一个网络数据集,并按照其默认设置直至完成。
  3. 打开该地图的工作空间,把刚才新建的网络数据集添加工作空间中。
  4. 在网络分析菜单中选择新建最近设施点。

这时在工作空间里,可以看到多了一个名为“Closest Facility”的图层。它下面还有4个子图层,名字分别为“Facilities”,“Incidents”,“Barriers”,“Routes”。“Facilities”就是设施点图层,也就是目的点,“Incidents”的意思就是出发点,“Barriers”是障碍点,意思就是地图某条道路附近有一个障碍点,如果障碍点与道路距离在容限范围内,则表示此道路不通,“Routes”就是最终的结果。这样我们编程实现最短路径的思路就出现了:

  1. 添加出发点。
  2. 添加目的点。
  3. 生成最优路径,获取结果。

这里的添加出发点或者目的点,是往“Facilities”或“Incidents”图层上添加元素。获取结果也是从“Routes”中获取Polyline。往“Facilities”或“Incidents”图层上添加元素用到的主要方法是INALocator的QueryLocationByPoint函数,生成路径主要接口是INASolver和它的Solve方法。获取结果是按属性查找,因为“Routes”类其实就是一个图层类,只不过只是存在于内存,这个查找方法网上很多。

相关链接:ArcGIS中最短路径的实现(一)

【原】Boost库之timer的使用

我们在编程中有时需要计算运行某一段代码所花费的时间,通常的方法是通过计算该段代码首尾的GetTickCount的差值来获得。这种方法虽然可取,但需要调用两次GetTickCount函数,总让人觉得有些繁琐。Boost库的timer提供了对计时特性的封装,简化了代码的编写,并且它具有跨平台的优点。

Boost库的timer主要封装了timer、progress_timer和progress_display这3个计时类,使用起来非常简单,下面逐一介绍。

timer类的构造函数会在内部获得一个起始时间并开始计时,其elapsed成员函数会计算所消耗的时间,其restart函数重新开始计时。示例代码如下:
timer tx;
Sleep(1000);
cout << tx.elapsed() << endl;

progress_timer类是对timer类的进一步封装,使用起来更加方便,它会在析构函数中自动打印出所消耗的时间。示例代码如下:
{
progress_timer pro;
Sleep(1000);
}

progress_display类以图形化的方式给出了当前所花费的时间刻度占总时间刻度的比例。其构造函数为:
explicit progress_display(unsigned long expected_count, std::ostream &os = std::cout, conststd::string&s1="\n", const std::string & s2 = "", const std::string & s3 = "" );
其restart函数用于重新开始计时,count函数用于获得当前所花费的时间刻度,expected_count函数用于获得总的时间刻度。另外,progress_display类还重载了+=和前缀++操作符,用于增加当前的时间刻度值。示例代码如下:
progress_display pd(15, cout, "hello:\t", "hujian:\t", "Start:\t");
for (int i = 0; i < 15; i++)
{
Sleep(100);
++pd;
}

这3个类的实现比较短,均在timer.hpp和progress.hpp头文件中,大家有空可以阅读一下源代码,以加深对这3个类的理解。

2009年3月26日星期四

【原】关于Visual Assist X(VC助手)几个最新版本的比较与破解下载——更新到10.5.1715.0

下面归纳下VA近期几个版本的问题:

1557:对宏的支持不好,经常无法提示;跟以前的所有版本一样,注释超过一定行数就被“...”代替了,郁闷。

1561:比以前版本最大的改进就是注释能够显示完全,超爽;对宏的支持也好多了,但是在有些情况下宏的提示还是有问题,并且goto不到源代码。

1626和1640:VA工具栏耳目一新;增加了一些更加人性化的配置选项;但先天有一个超级大Bug,AutoText在系统是中文用户名的情况下不会自动提示(这个问题VA提供了一个变通的解决办法,参照相关文章1),而且听说在有些用户的环境下对中文的支持很不好(我用的时候没有发现问题)。后来又发现一个问题是当VC工程打开一天或者更久后,所有建议和颜色都会失效,不过这个ms是由于破解不彻底导致的。

1649:修复了1626和1640的一些重要Bug, 包括上文提到的系统中文名下AutoText失效和对中文支持不好的问题,并且开始了对VS2008的支持。但是我只试用了几分钟就又遇到了两个很让人郁闷的问题。第一个是注释格式错乱:(图1:1561的注释 vs 图2:1649的注释 )

1561的注释 1649的注释

第二个是高亮关键字这个过程效率很低,我在新打开一个文件的时候都是先看到字是黑色的,然后才变成蓝色或其他对应的颜色,这个过程看的一清二楚,让人非常不爽。

1711:这个版本是目前最新的(其实最新的已经到1715了,但据说1715的破解版不是很稳定,所以还是用回1711),但是1649的那两个问题依然存在。

所以对比之下我总结出的结论就是,如果不用VS2008,那么就选择1561,问题算是最少了,对于VA的最新版本,可以尝试一下,一定会有全新的感受,不过新鲜劲儿过了可能就只剩下失望了,让你不得不换回以前的老版本^_^;如果用VS2008,那么只能选择最新的1711。不过我们还是继续期待着tomato能够尽快推出更加稳定、性能更好、更适合中文用户的新版本。

Visual Assist X 破解版本下载地址:1561 1711

关于1649版本Bug的官方解答:http://www.wholetomato.com/forum/topic.asp?TOPIC_ID=8244
关于1640版本Bug的官方解答:http://www.wholetomato.com/forum/topic.asp?TOPIC_ID=7965
关于1626版本Bug的官方解答:http://www.wholetomato.com/forum/topic.asp?TOPIC_ID=7948

【原】Boost库之format的使用

Boost库的format提供了类似于C标准库函数printf的格式化字符串功能,并且它是强类型安全的。由于format重载了%操作符,因此,通过单次或多次调用%操作符可以非常方便地格式化字符串。
format的基本语法结构为:format(需要格式化的字符串 ) %参数1 %参数2 …%参数n。下面介绍format的几种使用方法。
1. 直接使用format
cout << format("%2% and %1% and %2%")%16 %"hello" << endl;
其中%1%表示第一个参数,%2%表示第二个参数,其他依此类推。另外,参数是可以复用的。

2. 使用format的str函数
format fmt("%2% and %1%")%16 %"hello";
string s = fmt.str();
cout << s << endl;

3. 使用全局的str函数
format fmt("%2% and %1%")%16 %"hello";
string s = str(fmt) ;
cout << s << endl;

4. 多次调用%操作符
format fmt("%2% and %1%");
fmt %16;
fmt %"hello";
cout << fmt << endl;

5.使用printf风格
cout << format("%d and %s")%16 %"hello" << endl;

6. 使用混合风格
cout << format("%2$s and %1$d")%16 %"hello" << endl;
其中%后面是参数的序号,$后面是printf风格的格式符。

另外,format还提供了一些其他的格式说明符。比如:%nt用于产生一个固定在第n列的\t;%nTx可以将x作为填充字符以代替当前流的填充字符(默认是一个空格)。当实际传入的参数个数与格式化字符串中需要的参数个数不一致时,format会抛出异常。举例如下:
cout << format("[abc%10t]") << format("[%10T*]") << endl;
try
{
cout << format("%1% and %2%") %16 << endl;
}
catch (exception &e)
{
cout << e.what() << endl;
}

最后谈一下使用format时需要注意的两点。一是使用默认的format风格(如%1%)输出浮点数类型时,只是将浮点数转换为对应的字符串,无法保证精度,如果需要保证精度,可以使用printf风格(如%f)输出浮点数类型;二是format不支持直接使用CString作为参数,需要先将CString转换为字符指针(如format("%1% ") %(LPCTSTR)szText)。

2009年3月21日星期六

【原】Boost库之tokenizer的使用

在tokenizer出现之前,如果我们要对一个字符串进行分割,可能要自己封装一个函数。如果有n种不同的分割规则,那么你要封装n个不同的分割函数……太麻烦了!现在好了,Boost库的tokenizer封装了统一的语法来分割字符串,并且提供了三种常用的分割方式,足以满足我们的绝大多数编程需求。
tokenizer主要由分割器和迭代器两部分组成。分割器用于指定字符串的分割规则,如果不指定任何分割器,则tokenizer默认将字符串以空格和标点(键盘上除26个字母(包括大小写)和数字外的其他可打印字符)为边界进行分割。迭代器用于保存字符串分割后的结果。下面着重介绍tokenizer的三种分割器。

■ char_separator是默认的分隔器,它以一组特定的字符来分隔字符串,其构造函数为:
explicit char_separator(); (默认构造函数)
explicit char_separator(const Char* dropped_delims, const Char* kept_delims = "", empty_token_policy empty_tokens = drop_empty_tokens);
其参数的详细说明如下:
◆ dropped_delims和kept_delims:是两个字符数组,这两个数组中的每个字符都是一个分割符。不同的是,dropped_delims中的分割符本身被丢弃,而kept_delims中的分割符本身作为一个单独的记号被保留在迭代器中。默认构造函数的dropped_delims为空格符,kept_delims为标点符号。
◆ empty_tokens:是否保留长度0的记号。它有两个可选值,keep_empty_tokens表示要保留空记号,而默认的drop_empty_tokens表示丢弃空记号。默认构造函数的empty_tokens为drop_empty_tokens。

■ offset_separator主要用于解析长度和格式都固定的字符串,如身份证或电话号码等。其构造函数为:
template<typename Iter> offset_separator(Iter begin,Iter end,bool bwrapoffsets = true, bool breturnpartiallast = true);
其参数的详细说明如下:
◆ begin和end:指向一个整数容器开始和末尾的迭代器,其中每个元素表示要分割的字段的字符数。
◆ bwrapoffsets: 如果字符串长度大于整数容器中所有字段长度的和,是否重复解析字符串。
◆ breturnpartiallast: 当字符串解析到末尾剩余部分的长度(注意:包括结尾的空字符)小于字段长度时,是保留还是丢弃剩余部分。

■ escaped_list_separator主要用于解析包含转义符、分隔符和引号的字符串。其构造函数为:
explicit escaped_list_separator(Char e = '\\', Char c = ',',Char q = '\"');
explicit escaped_list_separator(string_type e, string_type c, string_type q);
其参数的详细说明如下:
◆ e:为单个转义符或包含多个转义符的串。转义符后跟引号表示引号,转义符后跟n表示换行,连续两个转义符表示作为普通字符的转义符本身。
◆ c:为单个分割符或包含多个分割符的串,字符串以该分隔符为边界进行分割。
◆ q:为单个引号或包含多个引号的串,两个引号中间出现的分隔符不再作为分割标志,而是作为普通字符处理。

最后给出一组简单的测试题,大家既可以借此看看tokenizer的语法,也可以根据回答结果来考察一下你对tokenizer的用法有没有理解透彻。稍后我会在评论中给出正确答案。
a) string s = "hello, crearo-sw blog";
tokenizer<> tok(s);
for (tokenizer<>::iterator beg=tok.begin(); beg!=tok.end(); ++beg)
{
cout << *beg <<endl;
}

b) string str = ";!!;miaocl|zhangwh ||-hujian--terry|";
typedef tokenizer<char_separator<char> > tokenizers;
char_separator<char> sep("-;", "|", keep_empty_tokens);
tokenizers tokens(str, sep);
for (tokenizers::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
{
cout << "<" << *tok_iter << "> ";
}

c) string s = "20090321";
int offsets[] = {4,2,3};
offset_separator f(offsets, offsets+3, true, false);
tokenizer<offset_separator> tok(s,f);
for(tokenizer<offset_separator>::iterator beg=tok.begin();
beg!=tok.end(); ++beg)
{
cout << *beg << endl;
}

2009年3月20日星期五

【原】Team Logo

创作思路概要:
1.以CREARO-SW软件团队的英文首字母“S”为主体,体现本Team的软件开发相关内涵。
2.以蓝橙色为主色凋,两只交汇的箭头组成的“S“为主形体,蓝色代表科技、高端、时尚、而橙色体现着创意、
情、活泼,同时也寓意着团队中工程师和设计师思维的相互学习交融。
放图(原创作品,请勿盗链):

【原】svn服务器与客户端hooks脚本的使用

——主要谈提交前阻止空信息(pre-commit)和提交后自动发邮件(post-commit)这两个功能

本文用到的所有代码及工具下载:svn-hooks.rar
——包括pre-commit.bat,Post-commit.bat,blat.exe,maillist.txt等。

关于svn几个常用的hooks网上写的不少,相关代码被改的五花八门,很难有可以直接拿来用的(拿来主义总不像想象中的那么顺利...)。我这里只写Windows平台的,也不用python或者perl之类的需要装解释器的脚本,麻烦,只用bat,能达到目的不就行了嘛。

总的来说服务器脚本更实用一些,除了传入参数之外,更多参数可以通过svnlook命令来获得,所以能得到更多的信息来组织邮件内容;而客户端脚本虽说有传入参数比较多,但有些重要参数还是无法获得,所以并不好用。比如提交后自动发邮件的脚本,有些版本库我想实现只有管理员提交才发邮件,而其他人提交则不发邮件的功能。本来我想在管理员所用的客户端上加post-commit脚本,但很无奈版本库和提交文件列表两项参数无法获取(可能有绕弯的方法但我没找到),所以后来就在服务器脚本里加了对提交者的判断,从而达到了过滤的目的,也比较easy。
  • 提交前阻止空信息(pre-commit.bat)
这个比较简单,用svnlook log可以查询到log内容,判断它为空或者少于n个字符都可以返回错误并反馈到客户端,可参照附件Server目录下的pre-commit.bat。
  • 提交后自动发邮件(post-commit.bat)
主要实现思路是把提交版本的相关信息合成一封html邮件,再利用blat(一个著名的无界面邮件客户端)将邮件发送给配置好的邮件列表,相关附件为blat.exe、maillist.txt和Server目录下的Post-commit.bat。blat.exe最好放到系统盘System32目录下,这样在使用时就不用带绝对路径了,用之前首先要初始化一下,调用blat -install <server> <username> <try> <port>,<server>是smtp服务器的url,<username>是登录用户名,<try>是尝试重发次数,<port>是smtp发送端口,比如blat -install 192.168.1.254 xxx@crearo.com,后面两个参数如果不需要改可以默认。

最终发邮件时调用:blat "%LOG_FILE%" -tf %MAIL_LIST% -f %SENDER% -s "[svn] %REPOS_CP%, rev %REV%, %AUTHOR%" -base64 -charset Gb2312,这是针对发送邮件不需要认证的的命令。如果服务器需要进行用户认证,那么就要加上-u <username> -pw <password>,即用户名和密码。经过我的调研发现,Gmail不能用,因为它需要SSL认证,要用也可以,需要配合stunnel一起使用,太麻烦了;163邮箱需要认证,因此要带上用户名和密码;而创世内部邮箱无需认证,所以最终还是选用了公司邮箱,其他邮箱没有再作调研。最后snv自动发送的邮件截图如下:


其实除了发邮件,还可以根据自己的需要添加其他功能脚本,比如向公司内部即时通信软件发消息等,沟通效率会更高。这就可以任由你来发挥了,呵呵。

svn hooks科普教材:
http://www.worldhello.net/doc/svn_hooks/svn_hooks.mm.htm

2009年3月18日星期三

【原】引玉系列之“启航之旅”实习生计划海报设计心得

创意以及技巧上的东西就不多说了,主要写下整体设计思路及制作过程。
首先由“启航之旅”进行分析创意,设计草图,主要画面构思:海天一线的蓝色画面,蓝天上的白云,水面上的白帆。确定了思路之后着手进行海报制作:


1. 新建文件,确定画面色调,模拟天空水面。


2. 在已确定的色调基础上进行水面波纹效果制作。主要运用图层模式,做多图层的叠加效果,让水面和波纹融为一体。

3.这时候,水面的感觉还不够清澈,没有深度感。对其做光照处理,模拟真实水面的光线折射效果。

4.做水面上的白云,找合适的图片用蒙版进行编辑融合,然后用画笔工具进行局部及边缘调整,或者按所需要的形状重新绘制。PS自带的圆头笔刷,注意云彩的走向以及结构即可。

5.增加高空的云彩,根据透视原理及光的漫反射分析,这里的云层应该更加透明一些,饱和度略低于水面上的云。制作方法同上。

6.添加一个光晕效果,丰富画面。

7.在天空和水面之间加入一片绿地,标识地平线。弱化中间的部分,强调透视。
8.按照最初的构思寻找合适的帆船素材,抠图。


9.调节至合适大小,放在画面的预留位置上。
10.对船和水面进行合成,主要是处理船身的投影,以及驶过划开的波浪。

11.添加画面元素,空中的飞机,水面飞鸟。找合适的素材进行抠图处理。

12.对添加的画面元素进行合成加工,如飞鸟的倒影,飞机划过天空的尾气。
到这一步,整个海报画面已经基本完成。在以上的步骤中不断对画面整体色调进行微调。

13.按设计草图添加画面的主题文字内容以及辅助文字部分,完成整个海报的制作。

2009年3月16日星期一

【原】设计3+2之建模相关

浅尝的小结了下建模中常用到的相关命令:
1.Edit Mesh多用于多边形编辑
2.Shapes二维物体编辑
3.Editmesh修改器的相关参数
4.System Unit系统单位
很常用的快捷键:
ctrl+z 返回上一步操作
ctrl+x用专家视图方式显示
ctrl+o打开文件
常用视图:
/p 透视图
t 顶视图
l 左视图
f 前视图/
ctrl+u用户视图
m 材质编辑
f10 快速渲染
f9 查看渲染效果
一个简单的建模效果:

2009年3月15日星期日

【原】ArcGIS中最短路径的实现(一)

最短路径分析属于ArcGIS的网络分析范畴。而ArcGIS的网络分析分为两类,分别是基于几何网络和网络数据集的网络分析。它们都可以实现最短路径功能。下面先介绍基于几何网络的最短路径分析的实现。以后会陆续介绍基于网络数据集的最短路径分析以及这两种方法的区别。

几何网络是一种特殊的特征要素类,由一系列不同类别的点要素和线要素(可以度量并能图形表达)组成的,可在FeatureDataset下面创建,可进行图形与属性的编辑。包括流向分析和追踪分析两大功能。主要接口是ITraceFlowSolver。我们先在一幅地图上做出一个几何网络才能进行最短路径分析。下面是主要的一些步骤(ArcMap帮助中琐碎的说明有三四十项,被我省略很多):



  1. 打开ArcCatalog,连接到包含地图的文件夹。

  2. 在空白处,右键新建一个“Personal GeoDatabase”。

  3. 在生成的Personal GeoDatabase上右键新建一个feature dataset。

  4. 双击Personal GeoDatabase进去,找到刚才new出的feature dataset,右键Import导入Feature Class(Single),选择要建立几何网络的图层或者shape文件。

  5. 然后再右键新建一个Geometric Network,选择从已存在的图元中建立几何网络。

  6. 打开ArcMap,把刚才建立的“Personal GeoDatabase Feature Class”添加到地图中,这样几何网络就建立好了。

这样我们就建立好一个几何网络了。我们现在要通过编程来实现最短路径,用到的接口主要有INetworkCollection,IGeometricNetwork,IPointToEID,ITraceFlowSolverGEN(它实现了ITraceFlowSolver的接口),INetSchema,IEIDHelper等。主要步骤如下:

  1. 获取几何网络工作空间
  2. 定义一个边线旗数组,把离点串最近的网络元素添加进数组
  3. 设置开始和结束边线的权重
  4. 进行路径分析
  5. 得到路径分析的结果

具体的程序太过繁琐、冗长了,这里不便贴出,可以打开这个链接查看源程序。http://www.cnblogs.com/3echo/archive/2008/01/24/865527.html

相关链接:ArcGIS中最短路径的实现(二)

【原】涂鸦SD之二

直接上图:

PS:今天发现电脑坏了,资料都拷不出来,过程步骤后补。

【原】Boost库之tuple、any和variant的使用

Boost库中提供了三种比较实用的数据结构,分别是tuple、any和variant。它们的共同优点就是支持类型安全地存储和获取数据。灵活地使用这三种数据结构,对我们进行程序设计无疑是大有裨益的。下面分别加以介绍。
tuple支持一次直接声明和使用n个不同数据类型的变量。对于有多个返回值的函数,我们再也不用定义一个结构体作为函数的返回值类型了,也不用通过对参数进行引用来传出返回值(这样返回值的概念不太明确),而是可以直接使用tuple。
◆ 声明一个tuple类型的对象:tuple<int,double,string> triple(42, 3.14, "hello world");
◆ 获得tuple中某个变量的值:string s = get<2>(triple);
◆ 获得tuple中所有变量的值:tie(nAdd, dbSub, strText) = triple;
◆ 通过几个变量构造一个tuple类型的变量:tuple<int,int> temp = make_tuple(3, 5);
any支持存储任意类型的变量,但它只允许你在知道类型的前提下访问它的值。如果类型不符合,则any会抛出一个bad_any_cast的异常。如果访问的是指针,则类型符合时返回的指针是一个有效值,否则返回的指针为空(此时不会抛出异常)。
◆ 给any赋任意类型的值:any a; a = 42; a= string("hello world"); a=3.14;
◆ 获得any中存储的值:double dbTemp = any_cast<double>(a);
◆ 获得any中存储值的指针:string *pString = any_cast<string *>(a);
variant支持存储和操作来自于多个不同类型的变量。获得variant中当前存储的值时,如果给定的类型与实际存储值的类型不符合,会抛出一个bad_get的异常。如果要获得的是指针,则类型符合时返回的指针是一个有效值,否则返回的指针为空(此时不会抛出异常)。这里需要着重谈一下variant与tuple和any的区别:tuple可以保存n个变量的值,而variant只能保存一个变量的值; any可以保存任意类型的变量,而variant只能保存指定数据类型的变量。
◆ 声明一个variant类型的对象:variant<int,double,string> va("hello world");
◆ 给variant赋值: va=3.14; va=42;
◆ 获得variant中当前存储的值:int nTemp = get<int>(va);
◆ 获得指向variant中存储的值的指针:string *pString = get<string *>(&va);

2009年3月9日星期一

[原] 涂鸦SD

连绵了半个多月的阴雨天,今天终于露出久违的阳光,连带的心情都好了很多:-D
晚上整理电脑资料,看到许久前收集的一些SD娃娃的图片,忍不住有些手痒,随便涂涂,休闲一下.
发个简单的步骤图如下:

1. 铅笔把大形状勾画出来。


2. 数码喷枪喷绘出简单的黑白素描关系。


3. 加水笔柔化笔触。


4. 油画笔刻画细节,强调结构。


5. 建立颜色图层,叠加色彩。


6. 合并可见图册,整体调整刻画。


7. (偷个懒~帽子不画了 :-P )
在保证画面整体下,细节进行细微调整。

完成~~
PS:涂鸦性质练笔,很多方面没顾及到,随便看看就好~~ ^-^

【原】设计3+2

平面设计更多更多传统的归属与2D的范畴,的确,2D可以更精致细腻的表达图像,把一些细节完美地表现出来,但是,现在有越来越多的平面设计师把自己的设计与3D结合了起来,也就出现了越来越多的精致美观的有着更强的视觉冲击力的作品!
比如网站方面,基本上图片加文字,好一些的加入了FLASH动效果,而现在高档的网站则更多的结合了3D效果,可以让人真实的更加身临其境的,全方位体会它的产品和想表达的境界!最近一直在接触宣传册的设计,下面聊些关于用3D做宣传册效果的尝试,以前做印刷品的效果图,我通常还 是会用平面工具,这样也可以很好表达出想要展示的效果,但如果上,下,左,右效果都要的话,我就要出N张不同的图(同时还要注意透视关系),那叫一个烦琐,,如果利用3D对作品进行表现就可以大大加快制作速度,同时在不失创意的情下,可以更有效地把握自己要表达的意图。

同时3D制作过程中的:
1.视点(摄像机)是可以任意移动并改变角度
2.灯光(光影的变化)光源位置明暗效果
3.质感(材质渲染)

都显得非常灵活,不但能细致地表现对象,更能更易于修改画面!
本人还处在学习摸索阶段,希望以后能有更好的想法与各位分享!
:D以下是2张简单的建模贴图的应用:

【原】关于const修饰符的问题

对const修饰符的使用一直感觉疙疙瘩瘩的,因为用的不是很多。上周写了个小程序,搞清楚了它的用法。话不多说,先贴程序。
  1. const int n = 10;
  2. const char * pszTemp = "a";
  3. char const * pszTemp2 = "c";
  4. char * const pszTemp3 = "b";
  5. const char * const pszTemp4 = "e";
  6. pszTemp = "d";
  7. pszTemp2 = "e";
  8. pszTemp3 = "f";
  9. pszTemp4 = "f";
  10. lstrcpy(pszTemp, "d");
  11. lstrcpy(pszTemp2, "d");
  12. lstrcpy(pszTemp3, "d");
  13. lstrcpy(pszTemp4, "f");

把这段程序拿到VC6的环境下编译,会发现编译出错。第8、9、10、11和13行都有错误。我们先从第2行开始分析。第2行定义了一个名叫pszTemp 的字符串指针,const放在char *之前,表明它是一个指向常量的指针变量,它指向的常量值不可以改变,所以第10行会编译出错,但是它保存的地址却可以改变,所以我们仍然可以通过改变它指向的地址来改变它的值。第3行同第2行。第4行定义了一个常指针,表明它本身是常量,而不是它指向的对象声明为常量。所以第8行出错,而第12行却可以通过。第5行是定义了一个指向常量的常指针,所以无论是对它指向的值的改变还是指针本身值的改变都是不允许的。因此,第9行和13行写法都是错误的。
下面再贴几行代码,有兴趣的读者可以指出其中出错的行数。

  1. const int *pAge = new int(1);
  2. int const *pAge2 = new int(2);
  3. int * const pAge3 = new int(3);
  4. const int * const pAge4 = new int(4);
  5. *pAge = n;
  6. *pAge2 = n;
  7. *pAge3 = n;
  8. *pAge4 = n;
  9. pAge = &n;
  10. pAge2 = &n;
  11. pAge3 = &n;
  12. pAge4 = &n;

【原】Boost库使用入门

Boost库是一套开放源代码、高度可移植的C++准标准库。它相当于STL库的延续和扩充,其设计理念和STL比较接近,都是利用泛型让复用达到最大化。
Boost库当前的最新版本为V1.38.0,大家可以到Boost库的官网http://www.boost.org/去下载,下载后直接安装即可。这里需要格外注意的是,Boost的绝大部分库只需要包含头文件就可以直接使用了,而另外一些库,比如正则表达式库(regex)、线程库(thread),需要编译生成lib和dll后才能使用。
Boost库主要包含以下几个大类:
1.字符串及文本处理
2.输入/输出
3.数学和数字处理
4.泛型编程和模板元编程
5.函数对象及高级编程
6.数据结构、容器、迭代器和算法
7.杂项
大家在学习Boost库的过程中,肯定会遇到这样或那样的问题,这是很正常的。这里,我把自己在学习中总结出来的一些注意事项列出来,以供大家参考:
1.由于VC6对模板类的支持不是很好,因此,使用有些Boost库(如string_algo库)时在VC6下无法编译成功,可以使用VC7或更高的VC版本来解决这一问题。
2.由于VC6的编译器并不是完全支持C++标准,因此使用有些库时即使编译通过了,但运行的结果可能会不正确,解决方法同上。
3.安装完Boost库之后,需要将Boost库的根路径添加到VC的Include Files和Library Files中。
4.与使用STL库一样,使用Boost库时,最好使用using namespace boost来声明名字空间boost。
最后,列出学习Boost库的一些实用资源:
1.Boost库的SDK
2.《超越c++标准库——boost程序库导论》
3.Boost官方网站
4.Boost中文站
OK,Boost库的概述就讲这么多。让我们赶快进入Boost库的神秘世界吧,Let′s go!

2009年3月8日星期日

【原】AE之鹰眼的实现

大家都用过百度地图或者googole地图吧,在它们主地图的右下角,有个小地图窗口,这就是鹰眼窗口。用鼠标拖动鹰眼里的小窗口,则主地图便移动到相应的位置。下面就介绍鹰眼的实现。
鹰眼和主地图的互动,主要体现在两个方面:一是主地图的地图改变了,则鹰眼里的矩形框要移动到对应的位置,以指示当前地图在整个地图中的位置;二是鹰眼的矩形框移动了,则主地图中显示的地图要移动到相应的位置。
AE中显示地图的控件叫 ESRI MapControl,这里主要用到了它的OnAfterDraw事件。在主地图的OnAfterDraw事件中,根据当前地图的大小,改变鹰眼中矩形框的大小;在鹰眼的OnAfterDraw事件中,根据矩形框的位置,确定主地图中地图的位置。google地图的鹰眼还实现了矩形框的拖动,这个也很好实现,呵呵。在鼠标点击到鹰眼控件时,先判断是否在矩形框内,如果在的话,用一个状态量记住这个状态,此时如果鼠标移动,则矩形框跟着相应的移动;若不在矩形框内,则矩形框移动到鼠标点击的位置。

【原】谈谈网络视频监控系统软件平台的发展趋势

从当前行业的局面来看,伴随着各厂商硬件产品差距的日益缩小,视频监控在未来的竞争将是软件平台的竞争。谁家平台做的好,谁就在竞争中占有绝对优势。那么,软件平台会如何发展,向着哪个方向发展?个人看来有以下几方面趋势:

  1. 需要具备支持其他厂商设备接入的能力,我们称之为“吸收性”。做大系统,做运营,不能方便的接入其他厂商的设备怎么可以?吸收性强,系统才有可能做大。所以,系统在设计之初就要考虑这一点。
  2. 系统要有足够的扩容能力。当系统中的设备由原有的几十台突然上升为几百台甚至上千台的时候,如何才能够微笑着去面对?假设系统设计之初便考虑到这点,那么一个灵活而有效的系统结构将会使该问题迎刃而解。
  3. 必须具备一套功能全面、界面友好并且易于定制的客户端软件。以前我们说服务器的性能好坏很重要,但是将来客户端的性能会需要我们更多的投入,良好的用户体验不仅仅能够锦上添花,有时甚至可以起到决定性的关键作用。
  4. 系统要便于搭建和配置、易组网。在系统模块较多的情况下,这个问题需要尤为注意。
  5. 具备良好的平台兼容性,这可能已经是默认的潜规则了,不需要多说,Linux必须要支持。
  6. 具备良好的稳定性,这点真是易说不易做。监控这个行业要求我们服务器稳定,客户端也要稳定。做一个系统很简单,想做好就要下功夫。

目前应该还没有一个厂家敢说他的系统已经做到最好,事实上很多厂家还没有自己的系统。这让我们的竞争变得更加残酷,也让我们对未来充满信心。因为创世已经走在了前面,我们还将继续大踏步向前迈进。

2009年3月5日星期四

寄语CREARO-SW

既来之,则留之,请在下方发表留言,谢谢@_@

2009年3月4日星期三

Hello everyone

欢迎来到创世软件团队,让我们在这里记录下团队以及团队里每一位成员的成长历程,展示和分享大家的研究成果,共同致力于打造行业内优秀的网络视频监控系统软件平台。