Google
 

2008-12-30

MSXML删除节点

  昨天遇到一个问题,用MSXML操作XML时,删除一个子节点,可是死活删不掉。后来想到一个变通的办法,把这个子节点的标志性属性值改掉,这样其他处理过程就认不出这个节点了,就相当于删除了,很黄很暴力。
  今天再去定位这个问题时,发现原来那子节点真的被删掉了。进一点试验发现,只要在删除该子节点前,先随便改一下这个子节点的一个属性值,下面的删除操作就正常了,但如果没有那个修改操作,就删不掉,真是怪事!
  我当时还以为是不是因为子节点下面还有其他孙子节点,还想是不是要修改一下删除子节点的封装方法,递归地删除掉所有子孙节点呢!看来不必了!

2008-12-29

e这么烂的程序也卖

  今天在公司看到一个同学在用e,有点好奇,早听闻它有“Windows下的TextMate”之称,以前也下载来装过,只看到界面很简单,功能也很简单,于是就没下文了。今天又有点兴趣,就让同事共享给我再试用一下。
  还是老样子,界面上没什么改进,也许比之前我试用时功能上有所增强,但以我目前的眼光看来,它还是太简单了。总的说来,只有一个特色功能,就是bundles。不过可能TextMate赖以成名的就是bundles了,e就是全盘照抄了,从网上看到,说e的作者和TextMate的作者是老乡,两人协商过,让e可以直接使用TextMate的bundles。所有的人都说,e只有TextMate的一小部分功能,这我也是相信。但是最让人受不了的是,e运行极其不稳定,随便点几下就是挂起,或者崩溃。这么烂的程序居然也来卖,而且听同事说可能卖得还不错,我想这全沾了TextMate的光啊!因为说,它的一切思想,无论是从程序开发的角度,还是用户体验的角度讲,都是很好的,但这一切都是TextMate赐予的,e里唯一有点自己特色的是,用类似异步可插入协议的方式来修改配置。我没用过TextMate,不晓得它在这方面是怎么做的。
  看了e后,另外一个同事就说,我们现在的Impeller应该也好卖吧,有语法结构树,有自动完成,有调试执行,我笑!

2008-12-28

阴雨天睡午觉之安逸

  昨天晚上跑去KTV唱歌,后来唱歌腻了他们就放起的士高来,我是不会蹦迪的,可是看着那些人在那跳得那么起劲,我也有点蠢蠢欲动了,于是去胡乱蹦了几个。结果,今天就显效了,虚脱了,背痛,下午一下就睡着了,好久没在家里睡过午觉了,醒来的时候发现天灰蒙蒙的,还有雨声,还以为睡到天亮了,心里不禁大喊,天呐,我居然从前一天下午睡到第二天早上,还没吃晚饭!后来挣扎着要不要起床,看了一下时间,才18点,心里顿时安定了不少,原来还没到第二天啊,刚刚还郁闷着这周末就不知不觉地让我睡过去了呢!
  再说点正儿八经的事。话说我一直想要设计一个基于C++ GUI框架的脚本扩展架构,不过到目前,还没有一个完整的清晰的思路,我只有一个大致的目标。一直想着,这样的架构实现后,只要C++部分实现一些基本的底层支撑,剩下的脚本就可以直接拿出复用,实现所有业务逻辑。为了证明这个架构的通用性,我觉得自己似乎有点儿贪心了。我希望在MFC+XTP的基础上、WTL+TabbingFramework的基础上,以及wxWidgets的基本上都实现一遍。MFC的是因为工作上的需要,WTL则是因为想写一个WIND,而wxWidgets的则是想写一个通用的跨平台IDE。今天只想到一点,所有的逻辑处理都应该交由脚本实现,C++部分只提供最基本的底层(原子)操作。

2008-12-26

检测不到Excel文档的修改

  昨天偶然发现,我的程序根本检测不到Excel文档的修改,太让人郁闷,之前完全没料到这个结果啊!后来回想一下也想通了,Excel文档那么复杂的一种文件格式,不使用像txt之类的修改方式,完全是可以理解的。不过理解归理解,问题变得棘手了,怎么才能实现那个需求呢!
  今天没写代码,倒是在自己建的wiki上写了几篇文档,有关于设计方案的,也有关于使用说明的。我要开始准备撤退了,出于道义上的,或者说职业道德上的考虑,也是为了让自己以后少被人骚扰,我要输出尽量能解释清楚我目前所做的一切的文档。
  写文档也是个很累人的体力活啊,也许是因为几乎从来不写文档,让我觉得很多事情都不知道从何说起。心中很清楚明白其中的每个细节,却不能用文字表达出来,或者说即使能零碎地写些文字出来,却不能有效地串连起来,形成完善的文档。
  今天质量部的老大把我叫去,谈了一下之后的计划,我刚好趁此机会明白地告诉他,我对之后的维护性质的工作实在没多少兴趣的,而他居然出乎我意料地说,如果是这样的情况,可以换个人,而且还肯定了我之前所做的,这让我心里比较高兴,哈哈,仰天长笑!

2008-12-24

UNICODE与Scintilla合用的问题

  今天做另外一个工具的一点维护工作,需求是通过用户输入的宏名,宏值,类名,函数名以有函数返回值,工具要能自动到指定的文件中找到指定的位置,自动插入生成代码。本来这个需求是上个版本就已经实现了的,今天只是对需求有略微一点修改。可是最大的问题是,今天发现以前实现的这个根本不能用啊,文件是能找到,可是位置却是错的,根本毫无联系。
  调试了很久,实现过程是首先利用MSR的greta来找到参考标记,取得标记的位置,然后插入生成的代码。一开始怀疑是取得标记的位置不对,其实冷静地想想,这种可能性几乎不存在。不过我还是傻傻地加入代码,看标记位置取回的字符串内容,毫无疑问,肯定是对的。接着怀疑是Scintilla的插入方法有问题,同样事后想想,这种可能性也微乎其微。不过我也不死心地,加入代码,看该位置的Scintilla文本,果然已经是不正常的内容了。
  正在束手无策之时,突然不知怎的,灵光一闪,可能是因为看到其他一个项目中使用多字节编码的greta,觉得可能是这里引起的问题。greta在匹配文本时,在unicode情况下,一个中文字符和一个英文字符都是一占一个长度,而此时Scintilla还是以多字节方式处理,一个中文字符占两个长度,所以greta算出的位置对scintilla来说并不能对应上。想通了这一点,立即将工程编译选项切换到多字节方式编译,果然就正常了。
  这次遇到这个问题,也能为以后实现相关需求,或者解决类似问题,提供了极大的参考价值。

2008-12-23

培训计划

  老大叫我整理一份项目组内成员的C++相关内容的培训计划。我还是兴冲冲地去弄的,不过基本上是参考我自身的情况制订的,内容方面不是我比较熟悉的,就是我比较欠缺但又在工作中比较需要的。
  主要分了8大类,分别是C++对象模型、C++模板、STL、Boost、面向对象程序设计、Windows API、MFC、COM。每一类,都又划出好几个培训课程,我还根据自己所了解的,分别给每一类都备注了参考资料,每一类的的参考资料大多只是两三本经典书籍,比如COM类的,我就写了《COM本质论》和《深入解析ATL》,而Windows API类我就写了《Windows程序设计》和《Windows核心编程》,等等。
  等我把这份列表发给老大,老大又转给更大的老大,更大的老大则回复说,内容太多了,要分轻重缓急。我觉得很有道理,这样的培训是很耗费资源的,当然应该拣最有用的来。不过他列出的前3位是Windows API、MFC和COM,对于我来说,就有点兴味索然了。虽然这些方面我也远远说不上精通,甚至连熟悉都不够,但我自以为,应付工作上的要求是够了。比COM举例来说,我虽然排斥COM,但必须用地方还是会用的,我会调用COM服务器,同时我也写过COM组件,我觉得自己够了。
  既然不能把这份列表作为组内的培训计划,我看了看,觉得依照这些列出的参考资料,也可作为我自己的增强计划。这8类我都有所了解,在实际工作中也都或多或少地有所运用,但我不禁要考虑,学到什么程度算是够?
  我个人倾向于学习和使用一些比较通用的技术,比如STL、Boost之类平台无关的知识我就很有兴趣,而COM则是有点深恶痛绝的感觉,MFC稍微好过一点,不过也不是很喜欢。这不是我研究了这些东西后主动有了喜恶观念,而是不知不觉在一个比较长时间内养成的兴趣倾向,直到后来自己总结的时候才发现这个规律。
  其实我根本没多少想法,要尝到什么程度,目前而言,我只好给自己暂订个目标,STL、Boost、C++模板和对象模型,以及面向对象程序开发,是能学多少算多少,而其他的,则是够用就行。

2008-12-21

使用wxWidgets一天有感

  幸亏有Code::blocks和CodeLite两个的源代码可以参考,可以省事不少,不过还是发现,要像现在用MFC一样的比较熟练地使用wxWidgets仍需要先阅读一些基本的资料,当然wxWidgets的manual也是必不可少的。
  学习一种新的GUI框架的使用方式,关键还是在于了解并掌握它的消息处理机制。通常见到的GUI系统都是消息驱动的,所有所有的编程框架都不可避免地要有一套自己的消息处理机制,而且这套机制的设计好处,直接影响到整个框架的运行效率和使用效率。
  总的说来,我感觉目前wxWidgets已经有点庞杂,好处是有些问题可以有多种解决方案,坏处是增加了学习成本以及降低运行效率。总觉得它不但最终生成的可执行文件体积大,而且运行效率太低。不过似乎用gcc编译出来的代码,运行效率也不如用VC编译出来的。假设能用Intel编译器来编译,是不是运行效率能更高呢?
  现在用wxWidgets来写程序,还有个比较麻烦的问题是,跟用MFC开发相比,缺少一个好用的开发工具。以目前凡事都追求效率的情况来讲,写程序早已不是随便找个文本编辑器就能写代码的时代了,不光要有基本的文本编辑能力,其他自动完成、重构、提示、引用跳转、向导等等,无不影响着程序员的心情,以及开发效率。从这方面讲,目前已经没有哪个环境能跟VC+MFC比了。用vc也能写wxWidgets程序,但跟开发MFC程序相比,它缺了各种向导,比如Property视图,可以直接为各种系统消息、命令ID生成对应的函数声明,还有常用类派生的虚函数实现。
  不过,总算起步了!

2008-12-20

在家包饺子

  本来计划是明天的,因为冬至要吃饺子,结果F说明天要加班,于是只要提前到了今天。
  那几个家伙也够懒的,能睡那么久,不过也让我有点羡慕,因为我到了早上7、8点的时候,就开始睡不着了。
  结果等cm0同学过来的时候,已经1点了,然后跑去超市买菜。安排的是中饭吃炒菜,晚饭吃饺子。买了130多的东西,当然不全是吃的,还有cm0买的什么卫生纸之类的东西。F去超市旁的KFC买了鸡米花、圣代、薯条、蛋塔,因为实在不知道我们什么时候才能吃上中饭。
  中饭的菜基本上是我弄的,也跟平时我自己弄的一样,一个肉丝、蒲瓜、金针茹、香干丝混炒,一个白灼基围虾。味道自我感觉还是满意的。吃完就已经4点半了。
  吃过中饭,就打了一会儿升级,我的手气不是一般的差,不知道那个跟我搭档的cm0有什么感想,哈哈,反正我们一直都是打2,没升过级,而对方已经打到7了。
  7点时,开始准备晚饭,即饺子。我没有动手,因为我实在没有经验,就看着他们三个包,份量挺大的,满满一大盆的馅,厚厚的两叠皮。最后吃剩下15个左右,没办法了,只好浪费了,唉,可惜!
  另外还剩下鸡汤和鸡肉没动呢!

2008-12-19

最近脾气比较坏

  被另外一个同事说了两次了,说我最近越来越酷了。今天我就问哪里酷了,他说竟然敢当面顶撞王总了。我心中冷笑,多从来不认为公司里这种领导对下属可以指手划脚,颐指气使,我从来只觉得领导也不过是个打工的,只不过与其他下属的工作内容不一样,他的职责不是领导人,而是协调各种资源,包括人力。
  不过最近脾气比较坏倒是真的,我完全是被搞烦了,我也顾不上那么多了,气不过我就要反驳。今天早上的站立式会议时,我还对老大出言不逊了,我就直言他们对COM的过度热衷和盲目崇拜。
  后来老大找我沟通,说我是不是对现在的项目很有情绪,我说是不爽,而且感觉付出和回报不成比例,付出得太多,回报得太少。
  下午在回顾今天发的版本发现的问题后,质量部的人又在那里摆了很久龙门阵,知道我们想要撤出,便在那里说了一通项目的前景,个人的前景,画了好大好大一个饼,呵!

2008-12-17

好大一块巧克力

  大牛上周从俄罗斯出差回来,今天给了我好大一块巧克力,哈哈!
  单从包装外来观察,这块巧克力厚就不止1cm吧,宽不止10cm,长不止20cm。包装上全是俄文,我也找不出哪里写了具体的体积规格参数,手头也没有尺子可以量一下,反正就是很大一块。中午猫猫还说,大牛把最大的一块给我了,给她的就没有我的大,哈哈,想起这个就觉得开心!
  我们公司的人去国外出差,习俗就是带当地的巧克力回来给同事朋友们尝尝。以前吃过那位cm0同学不知道谁给她的德国巧克力,薄薄的一盒,里面是一小条一小条,味道比小卖部的德芙好多了。只可惜我是没什么机会出国出差了,除非赚了钱自己去旅游去。
  其实我很喜欢吃巧克力的,只是太容易长胖了,哈哈!

2008-12-16

解决构建时间超长的问题

  今天终于搞明白为什么昨天构建我的项目要2个小时了,原来是内存耗完了!
  本来一直没这种问题的,也就昨天突然发现,我的项目集成构建一次,最多的时候要206分钟,瀑布汗!当时还以为是中间的哪个环节出问题了被阻塞在那里了,看了下进程状态都是好的,主要的时间都花在doxygen生成文档上了。但看看doxygen也是正常的,有条不紊地dot。
  其实昨天就已经搞好了,因为当时发现本来2GB的物理内存,又设了2GB的虚拟内存,可是看看整个系统的内存使用量居然也是3GB多。关了一票的没用的进程,包括普通应用程序和系统服务,发现又变快了。
  今天重启了系统,同样关掉那些没用的服务和应用程序,再看CruiseControl,终于恢复正常了,15分钟就能完整地执行完一次构建!
  唉,服务器资源还是有限啊!

2008-12-15

先把框架搭起来再说

  一直沉迷于网络小说,完全属于玩物丧志的类型!今天无聊完,郁闷完,打开VS来,决定先把框架搭起来再说。
  总的说来,这是一个需要用外部脚本和配置文件协同扩展才能让业务逻辑正常运行的系统,而C++部分纯粹是为了实现用脚本比较困难的核心功能。虽然想了很久很久了,但一直迟迟没动手,玩物丧志是主因。
  另一个不太重要的借口是,没找到好用的开发工具。微软的一个很好的实践是dogfood,很早以前看《微软的秘密》一书时就知道这个了,前些天听那微软的专家交流时,又看到这个,觉得很有趣。像Code::Blocks和CodeLite都是典型的dogfood,使用自己来做为开发工具。而我目前还处于一片空白的阶段,被Visual Assist X惯坏了的我又受不了其他工具的弱智,于是一直停在那里。今天想通了,就用VS来作开发环境好了,先用VC编译一个debug的wxWidgets,要retail版本时,就写好makefile,用gcc来编译。
  这次恢复系统后,只装了个VS2008,这一方面可以让我不至于为众多的选择而分心,同时也减少多版本并存而可能出现的各种奇怪问题。前两天把原本只能用VS2005打开的WIND工程尝试着用VS2008打开,居然没崩溃,高兴之余把用WTL封装了的Scintilla代码也精简了一把,删掉了几千行代码,这下应该更不会崩溃了吧!

2008-12-13

用wiki记录开发文档

  前天,公司请MS的人来做交流,我也去听了一下,虽然只听懂了20%~30%,还有有翻译,尽管翻译的水平不咋的,连蒙带猜的大致上也能搞明白他在讲什么。其中让我印象最深感触最深的一个实践,是用wiki记录开发文档,其他人也可以修改文档,有新人加入时,就可以通过wiki进行学习,我深以为然。
  昨天,老大提出,我们项目组也要组建公共知识库,也包括开发文档。有个同事提出,他倾向于使用Word文档来进行记录这些内容。这不禁让我开始思考,用wiki和用Word来记录开发文档,各有什么优缺点。
  大体说来,我是倾向于用wiki的,因为我觉得wiki的形式更能鼓励人们不断跟着代码变化而自发地更新文档,并且wiki一般自带版本管理功能,使用更方便,另外一方面,开发文档并不需要多丰富多样的格式,有简单的文本和插图一般够用了,而Word文档拥有的其他功能,可算是累赘了,比如要比较两个版本的差异,就相对要麻烦一点点。
  说到底,我其实最看重的是wiki形式的约束下,人们会更多地完善文档,我们项目组目前的一大问题是,并没有多少文档,代码中偶尔有几行注释就算是全部的文档了。假如我们也像产品开发人员那样有非常详细的从SRS到HLD,再到LLD,那用wiki和用Word文档,或者其他什么记录形式,根本没有区别。

2008-12-11

template method果然安逸

  今天去把那几个函数重构了,第一印象中用template method pattern是可以解决的,于是翻了下GoF,里面对template method的描述基本没出我的意料之外,还是可以理解的,不过可能是受限于当年的C++技术水平,也可能是其他未道明的原因,GoF中说是在派生类中用覆盖方法实现的。
  我却认定了要用callback,因为我想用boost.function和boost.bind,于是三两下就搞好了,果然很简单,而且仔细想想,似乎相比用继承的方法实现,我现在的方案有一个优点是,可以把可变逻辑控制在更小的粒度上。比如本来我是一个算法的几个步骤,其中一个步骤是调用STL中的算法,而该算法需要一个谓词,这个谓词是可变的量,该谓词要被提取出来,这可以通过boost.function和boost.bind实现得像一个closure一样,在template method的领域内不需要知道谓词的具体实现形式,它只知道它接受一个boost.function,该function接受一个参数,之后返回一个值,至于到底是用functor实现,还是C global function实现,或是C++ class static function实现等等,它不需要关注,因为boost.function会打理好一切。而如果是用继承的方法实现,可能我就需要把那整个调用STL算法的步骤提取出来了,这样粒度就大了,就削弱了原本使用template method的意图和优势了。另外还有一种方案,还是用继承,只把谓词逻辑提取出来,STL算法调用时,用boost.bind来封装,但我想这是行不通的,因为编译期并不知道要调用哪个派生类的方法。
  用boost.function和boost.bind实现template method果然安逸,design pattern果然只是一种思想,而不受限于实现,哈哈!

2008-12-10

加多4个tab页

  今天整了一天,把原来的一个列表,整成了5个tab页分成的5个列表,每个列表显示不同的内容。
  这次是深切体会到当初设计的草率,把许多应该放在文档类中的数据成员和方法都放到视图类去了,结果现在本来还是同一份数据,要给多个视图共享使用时,就需要大量的修改。
  不过这样的修改从长远看来,说不定是塞翁失马。不光结构上有调整,在某些接口实现上,也有修改。总的说来,比又前更合理,更简单。
  当然一天下来,功能匆匆忙忙实现了,代码实现细节上却没有多加考虑,还是需要后续重构的。比如有一份代码,在4个视图类里各写了一遍,应该是用模板方法可以重构掉的,还有份代码,在2个视图类里各写了一遍。以前遇到这种情况可能会头痛一下,现在有了之前的使用boost.funciton和boost.bind的经验,应该很自然地能解决了。
  本来这个需求并不是最紧急的,但是一方面我自己比较想做,另一方面,它涉及到的面比较广,早弄好,其他部分也方便点。

2008-12-09

初玩PSP和NDS

  周日头脑发热,去买了一台PSP2000和一台NDSL,总共花掉2700大洋,我哭丧着脸跟同事说,半个月工资就这么没了。同事则也说还好呢,才半个月工资。我说难道是要想想那些花掉2个月工资的。
  买回来,其实没玩多少,因为对我来说,还是有很多方法打发时间的,消磨时间并不是我买它们的主要原因。为了省钱,我没买那些数据线,所以也不能自己下载游戏来玩了,都是铺子里给我装的几个。
  简单玩了一下,发现NDS这个机型的机能不足了,确实只能从游戏性上下功夫了。有一个Mario篮球游戏,通过触笔来控制人物进行各种篮球运动中的动作,比如运球、传球、射篮、抢断等等;有一个养宠物狗的游戏,可以通过触笔来做手上的动作,比如挠痒、抚摸等等,还可以通过语音来实现命令的下发,比如呼唤宠物,让宠物做动作。总之,因为有了麦和触摸屏,游戏的方式就改变了,虽然它的色彩不如PSP丰富,运算性能没有PSP强大,但它的游戏趣味性和多样性可以做得比PSP好很多。
  PSP的屏幕分辨率高,上面的游戏画面效果真是令人震撼,当然这也跟它的处理能力强悍有密不可分的关系。当然有点让我觉得无趣的是,PSP除了可以玩游戏,还加了太多其他功能上去了,看视频什么的,我觉得完全没必要嘛!

2008-12-08

轻车熟路的需求实现

  今天去整编辑器了,加上了函数定义的跳转功能,总共大概花了4个小时左右吧,因为没有功能良好的语法解析器支持,所以基本没什么技术含量可言了,就是判断一下当前光标所在位置的单词,假设该单词是一个类的方法名,去数据库中查询一下该方法所在的文件路径和行号,如果有多条记录,则弹出个对话框,列出所有的位置,让用户自己选一个。
  下午的时候跟老大说,老大竟然说我做那么快,看来以后得多分点任务。我郁闷!不过做这部分的时候,倒确实有点轻车熟路的感觉。添加对话框,给对话框添加必要的控件,给控制添加必要的消息响应,等等。以及添加新的类,在类中实现该它实现的功能。
  不过又想到语法解析器,没有它,做什么都是残废的,唉,什么时候一定要抽时间实现一个。

2008-12-07

恢复系统的心得

  从学校出来后,重装系统的次数大大减少,自从买了个本本,只是恢复过一次,今天是第二次,当然不算帮别人装的。
  为了减少工作量,有些小小的算不上技巧的伎俩。记得第一次恢复是用的光盘,今天拿出光盘,发现读不出来了,大概是光驱的问题,于是直接选择恢复到出厂设置,反正我的恢复光盘中的内容跟出厂设置差不了多少。
  选好后,可以去干点别的事,比如我就出去边吃饭边看电视去了,这样不知道总共花了多少时间,最后一直到设置机器名和用户名密码的地方,这时才需要人工介入。首先需要安装中文支持的MUI包,装完跑到控制面板里设置一下语言,使得界面上可以正常显示那些能完善支持中文的软件。
  然后是安装那些必备的软件。
  对于那些绿色版、免安装版、安装后更改文件夹后仍然可用的软件,则应该放在非系统分区中。这样下次恢复系统了,使用可以直接使用。比较典型的是Foxmail、QQ、Firefox(它要通过命令行参数实现)等等。
  对于必须要运行安装程序才能使用的软件,则根据一般建议安装在系统分区,这样在恢复系统时,也能自动清理掉。这样软件包括Visual Studio、Office(虽然现在实际上不装这个了)等等。
  接着是安装系统补丁。有个比较省事的办法,是装个360安全卫士,用它一扫描,发现所有的hotfix,自动下载自动安装,又可以去做些其他事情了。我就打了一会儿游戏,还去洗碗,整理床被等等,哈哈。
  做完这些,基本上可算是恢复系统了,但实际上要花很多时间,对于我来说,似乎需要6、7个小时才能搞定!

他妈的中毒了

  还是因为贪心啊,想用盗版软件啊,这下好了,中毒了,不幸中的万幸,不是一个后果很严重的,照赛门铁克的说法,是个误导性的病毒,老说你的机器有风险,还自作主张地把网络给拦截了,有的程序都不能正常使用了,比如foxmail,每次都说打不开socket,暴汗,IE则根本不能打开网页了,幸好一直用的Firefox,不过很多页面上方加了一条腥红的字“Warning! Your system is in danger. You need a full scan of your computer.”,还把很多的超链接的颜色也改成了腥红色,真恶心啊!
  盗版软件害死人啊!

2008-12-04

对目前项目状态的不满意之处

  程序终于改得主要的核心功能比较稳定了,这是最让我觉得安心的事了。这个项目无疑是到我投入时间和精力最多的项目了,中间过程也是竭尽全力、绞尽脑汁、使出全身解数,充分发扬拿来主义,使用了好几个第三方的开源代码,大概列数一下就有ACE、Boost、iconv、zlib等。眼下流行的工程方法,开发方法也被我有选择地用了一些,感觉自己的水平确实也有了一定的提高。
  但是我还是对项目、对我自己并不满意,随便列举一下。
  对系统的总体架构不满意,目前只有客户端,我的想法是至少要是C/S结构的,但是这样无疑会大大增加工作量,这也是眼下的无奈之举。
  对系统的性能和稳定性不满意,这是代码规模稍微大了点就出现的问题,而且一直也是无能为力的,这方面要有所改进,可能会涉及到整体架构的变更。
  对开发模式不满意,纯粹的乱搞方式,没有完善的流程和规范,敏捷很好,却没有实行起来。
  对程序结构和编码能力不满意,有不少看起来很丑陋的设计,有不少看起来很丑陋的代码,这点基本上可以通过开发人员的主观努力慢慢提高的。
  对自动化程度不满意,现在可以在每次build时自动修改资源中的版本号,每次commit后又可以通过CruiseControl自动集成最后生成安装文件,但测试却只有少量单元测试,还有崩溃报告每次只是通过邮件发送到邮箱中,照我的理解状况是有一个后台服务可以自动收集这些崩溃报告,然后自动进行分析,把尽量详细明显的分析报告提取出来,而且对于已知问题可以直接提示用户。
  对持续集成程度不满意,中间的各种测试、度量功能没有好好地利用起来。比如圈复杂度度量、源代码行数度量、重复代码行度量、PCLint、单元测试等等,有的没做,有的做了却没关注。
  对与客户之间的关系非常不满意,开发人员太弱势,对于需求基本上没有拒绝的权力,在我看来做了一些可有可无的功能,还做了一些愚蠢错误的设计,对于版本规划等主动权也不够。
  这些是大的几点,有的是可以通过自己努力得以改进的,而有的则会涉及到其他方面的人,则只能听天由命了,呵呵。

2008-11-30

马峦山溯溪

  今天去溯溪了,在一个叫马峦山的地方,早上7点半起了床,出门大概8点,之前想得好好的,到梅林关去坐车到银湖汽车站,再转车到小梅沙,可是到了出门了,就突然改变主意了,觉得转车两次也太麻烦了。于是直接到小区对面坐380B,可以直达目的地小梅沙海洋公园。以前没坐过,对需要多少时间也没有什么概念,但总觉得保守估计也是2个小时应该绰绰有余了。结果实践证明,大约1个半小时就够了,可能是因为早上路上车少人少开得快的缘故吧。
  大概提前了半个小时就到了目的地,倒是在车上遇到2个同事,他们本来是参加另一个户外团的活动的,就是出来晚了,人家已经出发不等他们了,于是就让他们加入我们的团。
  最后出发的时间基本上比预定的晚了近20分钟,唉!这次溯溪路程不长,而且人太多了,中间遇到好几个其他的团的人。这次大概就走了2、3个小时就到了吃饭的地方,结果等到吃饭的时候,又是差不多3个小时后了,而且最最重要的是,味道实在不咋的,而且7个菜,最后还要平均每人25元,划不来啊!
  下山就快多了,不过真的是上山容易下山难,路比较陡,而且很滑,得非常小心!比较累,呵呵。

2008-11-28

谁是最可爱的库

  这个标题很恶心,不过暂时想不出更能容易我现在心情的话来了,就先这么着吧。我就是想表示一下对boost的崇敬和感激之情!
  昨天发现用boost.graph可以解决我的问题。今天还是继续昨天的遗留问题,boost.graph确实跟STL那样,提供了抽象的,类型无关(真的无关么?我不确定,但我猜应该是)的算法,但是为了能用它,也着实费了我好些功夫。
  我只是为了用它的DFS算法,找出一个有向图中的环。为了配合它的使用,我把之前的代码都丢掉了,重新写了一遍,不过逻辑似乎更清晰了。为了取得里面的back edge,要提供一个回调函数,而这个回调函数的参数类型都是模板参数,而这个参数却是包含了我需要的back edge信息。这就困扰了我大半天。翻了很久的帮助文档,也胡乱看了不少它的examples,最后终于发现有一个source函数和target函数,可以取出edge中的前后两个vectex。
  解决了,就像一个同事说的,舒了一口气!
  昨天还顺便统计了一下我在工程中主动用到的boost库,一共有9个,分别是utility、foreach、bind、function、lambda、graph、conversion、format、tribool,如果没有boost,我的日子应该会难过得多吧,呵呵。

2008-11-27

牛哄哄的boost.graph

  偶然发现需要一个遍历有向图的算法,而且遍历不是主要目的,而是为了找出所有环。翻了一下《算法导论》和《算法概论》,对遍历算法有了个大概的印象,用DFS或BFS就可以,不过要找出环,就晕了。
  同事说只要记住游走的路径,如果在一条路径遇到已经访问过的节点,就是环了。虽然说起来简单,但我想用代码实现起来我还是觉得吃力的。
  另一个同事说,用boost.graph好了,我早想到了,但出于天生的那点畏惧感,总觉得没那么简单。抱着试试看的心理,看起boost.graph的文档来,惊讶地发现,原来这些常用的图算法都已经封装好了,只要以规定的格式准备好图的数据信息,然后调用一两个函数,就能实现遍历或找出环,实在是太牛了!

2008-11-26

用boost.function和boost.bind解耦

  话说昨天被XML摆了一道,发现一种不同模块间交互的方式,就是使用回调。在早期的C语言实现中,回调函数的使用极其简单,Windows的API中就有很多使用这种方式的,可以是一个普通的全局函数,也可以是一个类的静态函数。在C++时,可调用体多了一种类成员函数,这种调用体在被调用时依赖于一个实例指针,因为编译器会自动在该函数的第一个参数前再插入一个函数,即实例指针,作为回调,就稍微麻烦一点。关于可调用体的封装和泛化,可以参考《Modern C++ Design》,中文版《C++设计新思维》。
  昨天最后的结果是用boost.function,不过并没有发挥出它应有的作用,还是傻乎乎地把实例指针也传过去了,这跟直接使用原始的成员函数指针没有什么区别。后来想起来,有boost.bind的配合,可以把一个可调用体再作封装,以boost.function的形式而行为上类似于那些脚本语言的closure。在这个案例中,就是把实例指针绑定上去,这样另一个模块就根本不需要知道回调函数的原始类型了,无论是C风格的全局函数,还是类成员函数,在boost.function和boost.bind的联手作用下,都是一样的外表。这带来一个极大的好处,两个模块从此彻底解耦了。

2008-11-25

又被XML摆了一道

  要做一个配置界面,用户通过该界面可以修改一些系统配置项。本来配置项是一直都有的,不过不需要用户修改,都写死在配置文件中,这次有了新需求。大体上分成两个部分,一部分用于操作配置文件,另一部分当然是用户界面!
  配置文件是XML格式的,用MSXML组件的CString封装版本来操作,用这样封装版本的好处主要有三点:一、所有接口都用CString而不用BSTR,方便与MFC程序交互;二、封装的方法中有一些简单的出错处理;三、有一种简单的用于跟STL中算法适配的迭代器,方便操作节点列表。
  问题出现了,图省事,我直接在界面类中获取配置操作类中的DOM数据结构,想直接在界面类中遍历XML,结果发现每个节点想取属性时都会异常。开始怀疑是迭代器封装有bug,于是换了几种访问元素的方法,还是异常。后来猜测难道是不同线程使用COM的原因,想想也没有多线程啊,加上CoInitialize和CoUninitialize,还是异常!于是病急乱投医,想会不会把操作XML的代码全都放在配置操作类中,就好了呢。说干就干,因为要根据读出的配置信息操作界面,所以需要一个通知界面类的方式,我选择了callback,又因为callback是个界面类中的一个成员函数,所以越弄越复杂,最后为了能少写点代码,或者说看起来直观点,动用了boost.function,其实不用它也不会麻烦多少。好不容易全都改过来了,还是异常!我已经接近崩溃的边缘了,再异常就是我神经要异常了!
  所谓柳暗花明,最后无意间看了看配置文件的内容,猛然发现根节点下的第一个子节点是条注释!用DOM解析时,注释也是一种节点啊,昏,耗费掉我差不多2个小时,又被XML摆了一道。

2008-11-24

又一次尝试失败

  周末无聊,就尝试着用VS以外的工具来写代码,都决定用MinGW+makefile了,所以不存在编译器的问题,不过最后还是放弃了,因为代码编写的原因。
  尝试了Eclipse3.4、Netbeans6.5,Nightly Build的Code::Blocks和CVS snapshot的CodeLite,总之一句话,写C++程序,VS+VA的王道!确切地说,其实我是离不开VA了。
  今天在公司的论坛看到别人在讨论代码编辑器要怎么做,有一个老员工列举了他用编辑器的需求,我都觉得那已经不是编辑器了,而是一个IDE了。
  看来,如果要有好用的IDE,除了VA,只有自己做了……

2008-11-22

深受MS毒害的代码民工

  昨天下班为止,也没把预定的版本发出去,因为预定的需求没有完全实现,一个大的特性不能正常工作。所以今天上午就跑去公司捣腾了一把,两个小时就搞定了,比较安慰的是架构没有错,只是几处很细微的细节上犯了迷糊,尽管调试到解决了花了近一个半小时。
  我有点怀疑的是有人说TDD的最高境界是不用调试,但之前的经历已经证实,我尽管有单元测试,但单元不通过时,我还是需要调试来查找原因!难道就因为我TDD没到最高境界?我想狡辩,不全是我的原因,肯定是他们的业务逻辑太简单了。这样又扯到另外一个问题,为什么我的业务逻辑会复杂,照Martin Fowler大叔的说法,如果一处代码太复杂了就,就要分解成几个简单的。可是以我现在的水平和智商看来,这是个悖论,分解后还不是要再组合在一起,仍然是复杂的,仍然逃不过调试的命运。但我又怕万一有不幸的人看到这篇文字,会提出另一个观点是,如果组合在一起仍然是复杂,那是架构有问题。那刚好把问题的责任转移到另一处,哈,我争辩不过。不过还好,我一点都不排斥调试,因为不得不赞美几句MS,他们做的VS里的调试器太好用了,或者说他们已经做出了世界上最好的调试器,别拿那些啥gdb之类来的扯淡。
  在公司的时候突然想起来,我要用MinGW+wxWidgets写GUI程序,是否可以用Eclipse+CDT呢,从此可以摆脱MS的诱惑了。下午回到家整蛊了一个小时,不得不说,我还是继续用VS+VA吧,我想到的也就是个自动补全、智能提示功能而已,可惜Eclipse+CDT还做不到那样。
  总之,我是个深受MS毒害的代码民工。

2008-11-21

rdoc流程

  今天听同事讲了rdoc的处理流程,他完全是通过阅读rdoc的源代码来理解的,而且似乎他根本没有多少编译原理的基础的,汗!
  总的说来,通过他的讲解,我了解到,rdoc的处理流程基本也是分为词法分析和语法分析阶段。首先,应该说有一个词法分析器生成器,叫SLex,然后由RubyLex提供规则,其实是一组正则表达式,SLex可以说是有一个正则表达式引擎,根据这些规则,生成token,提供给RubyParser使用,基本上是lex/flex做的事情。然后RubyParser根据这些token解析出class和model,建立起相关的实例,解析出相关的注释信息,通过yaml写到文件中。这里有点虎头蛇尾了,不过大体上也能表达清楚想要的意思了。
  比较佩服的就是同事仅凭这些ruby源代码,就看到流程来,我怀疑要我上的话,如果没有这些编译原理的知识作铺垫,应该达不到他这样的程度吧!

2008-11-19

SVNLabel

  今天把CruiseControl上的label改成svn的revision号了,在公司发现个问题,有一个项目里总是不能正确取到svn的revision号,虽然构建了,但从web上看不到结果,没有日志,晕!回到家,也改了一下,又发现另外一个限制,其实这个可能要算是svn的限制,当时我把源代码从vss迁移到svn时,所有项目都是放在一个目录下的,所以现在svn里各个项目的源代码commit后revision号是累加的,并不是各个项目独立的,于是在CruiseControl上显示的就是几个项目用了相同的revision号了,晕!不过第二个问题应该影响不大,因为照我现在的应用场景,一个时刻只会对某个项目的源代码修改,只要CruiseControl是一直开着的,出现这种冲突的机会也不多。

2008-11-16

穿越东西涌

  这次是从西涌到东涌这样的路线。以前听很多人说过,就是自己没去过,这次可是切身体会了一把。
  本来自己的负重差不多,不会让自己太累到,结果出发前有2个mm把一些水和水果放到我包里了,结果真的重了好多。
  今天才知道,原来东涌和西涌也就是两处海滩游泳场,穿越就是沿着海岸线从一端走到另一端。
  沿着海岸线很不好走,大半的是礁石,剩下小半的路程是在山上爬,真的是爬哦,我还带了跟登山杖去,没用上,太难走了。中途一mm要虚脱了,于是我发扬不怕苦不怕累乐于肋于舍已为人的国际共产主义绅士风度骑士精神,帮忙背上她的包,果然又重了很多!
  非常不幸的是,在从一高处跳到低处时,左脚踩到一块不平的石头上,于是扭伤了。不幸中的大幸是,已经离终点并不远了,咬咬牙总算也坚持下来了。
  拍了一些照片,总的说来,海景很不错,怪不得总会有拍婚纱照的要去海边,今天就碰到两对,呵呵。

2008-11-14

软件工程大会

  今天上午去听了软件工程大会的几个议题,发现挺没意思的,没有多少收获。大部分都是炒冷饭,没有激情,没有让人耳目一新的感觉。全是敏捷来敏捷去,持续集成来持续集成去,TDD来TDD去的。
  于是下午就没去了,写了几行代码,把log4cxx加到工程中了,用xml格式的配置文件,看起来比较统一,所有的配置文件都是用xml的,哈哈,不过我的配置文件也太多了点。发现还是不能直接在代码中用unicode,编译时没问题,但是链接不通过,不知道什么原因,难道是哪里设置的问题。不过中文倒是可以了,在家里编译的不行,输出全是乱码,而且同事也一直说是乱码,不知道是编译的时候用的操作系统影响的,还是编译器影响的。

2008-11-13

感觉像是一种耻辱

  不分还好,一分就郁闷了,感觉像是一种耻辱。

2008-11-06

软件可测试性设计

  可测试性设计,即所谓的DFT,今天又一次重重地感觉了一次它的重要性。
  系统中有一个权限管理模块,同一个物理用户可以不同的逻辑角色登录系统,系统中以各个逻辑角色为最小管理单元进行权限管理。一般情况下,用户可选择的逻辑角色范围是极有限的,绝大多数用户应该有只一个逻辑角色,当然在测试情况下,情况刚好反过了,基本上每个物理用户会有几个逻辑角色,容易暴露出问题。主要集中在,角色拥有的权限不正常,比如看到了不该看的,看不到该看的,可以做不该做的,做不到该做的。
  一直以来,对这块的调试/测试都是很困扰我的问题,主要就是DFT没做好。最开始,把所有业务逻辑和界面绑定在一起,差不多每一条规则都要在界面上点来点去,构造很多与真实环境类似的数据去测试,非常麻烦,不容易遍历到各种情况。
  后来将这模块重构了,把业务逻辑和界面分离,用单元测试来保障逻辑的正确性。从DFT的角度讲,这种代码架构方式,就是一种改进,对DFT的改进。
  有了单元测试,还不能保证程序能完全正确地运作,因为除了逻辑正确,还有可能其他地方出错,比如输入数据就有问题。在前些天他们测试的一个版本中,依然发现了一些权限相关的问题,让我觉得比较郁闷,因为我一直以为应该是万无一失了的。不过事实摆在眼前,也逃不掉,今天老老实实地在那里定位,不过开始的时候还是异常困难,因为测试场景的千奇百怪,我的开发环境下,有些场景很难模拟。
  后来突然灵光一闪,我应该为了方便测试,多写一点代码,多加点功能,比如当前这个问题,我可以加一个特性,能在某种特定条件下,使我可以以任意角色登录系统。说干就干,果然很容易地定位到了测试发现的几个问题的原因。
  今天的经历告诉我,在软件可测试性设计方面,有很多值得研究的东西的,天呐!

2008-11-05

炒冷饭

  说话那天还在抱怨嵌入Python真辛苦,后来突然灵光一闪,马上解决了那个执行外部脚本文件的问题!既然现在已经能做到这一步了,接下来就应该考虑,能利用这个能力做些什么事呢?
  总的说来,现在我已经有了嵌入4个不同风格各有千秋的脚本语言解释器的经验:Lua、TCL、Ruby、Python。以后如果有需求,我估计TCL是不会再使用了,总觉得它的语法太枯燥了点。剩下三者,对Lua和Ruby的了解稍微多一点点,但也还没达到能用来做独立应用的程度。相比之下,Ruby的那种怪异变态的语法,还是比较吸引人的,还有就是它带了那么多稀奇古怪的库,可以大大减少重复劳动,这比Lua来说,省事不少。但Lua的轻巧,却一直让我觉得是嵌入的最佳语言。实在让人难以取舍呀!
  想了想,WIND就只用Lua嵌入了,因为这是一个相对比较追求性能的应用。而WallpaperHelper其实用什么似乎没多少影响,而且照现在的趋势,WallpaperHelper的体积已经不成为主要关心的问题了,功能才是最重要的。另外还想过要写打谱程序的,也要嵌入扩展。StoneBase的功能让人比较满意,但从写代码的角度看,它的架构不行,可扩展已经成了继续发展的必经之路了。但我还没想好,是用MFC,还是WTL,或者wxWidgets来写呢?

2008-11-03

让SMTP支持中文

  项目里要有发送邮件的功能,想法非常简单,公司有个SMTP服务器,通过它直接就可以发送到notes中了。网上SMTP的源代码也是一堆一堆的,找了一个CodeProject上的,加上base64编解码也只有4个文件,接口非常简单,于是稍微改了一下,base64本来我就有,就只需要加入2个文件就可以了,附件也能正常发送,很是满意。不过上周五的时候突然发现,主题和内容中的所有中文都变成乱码了,有点气馁,随便又找了几个其他的代码,也是一样。
  今天闲起无事,就想改一下。只知道在哪里看到过说要用base64,就能解决这个问题。尝试着先把主题编码了,发现收到后就是编码后的字符串了,这也是预料之中的。上公司的论坛发了个帖,没人回复。后来自己忍不住了,用Outlook Express写了个邮件,主题和内容都是中文,然后打开Wireshark,抓包,比较了一下CodeProject上那个代码发送的,看出区别了,原来也就是加上个charset="gb2312",再base64,就搞定啦!

2008-11-02

嵌入Python真辛苦啊

  两年前,就嵌入过python,那时宿主程序是用C++Builder开发的,python还是2.4,没用第三方库,完全用python C API直接操作,而且当时要暴露的接口不多,才4个C函数,当然还是费了不少力气。嵌入python的目的是为了主程序可以实现外部脚本扩展,只有一个很简单的应用场景,点击一个菜单项,就执行一个py文件。首先是要让它能执行起来,python文档有很多C API,例程却极少,记得当时连接1个半月每天至少到后半夜2点才睡,最后累得上wc连掀马桶盖的力气都快没有了。而且很大的问题是,在家里自己的电脑上终于可以跑起来了,拿到公司的电脑上却不行,每天只能晚上回家调,白天再到公司测试,很郁闷,我已经忘了最后是怎么搞的,反正是最后发现在公司的电脑上缺少一个site.py文件,直到这一刻才发现,这是python官方发布包中的一个文件,当时是自己放了一个0字节的文件在那里搞定的。那次这么多精力的投入真是不值,做出东西来本来想得个满分的,结果只打了个C,而且当时指定了4名专家评审,结果只有2个专家发表了评论,另2个还没评论就走到下一环节,直接C了,唉!
  今天又看到很久之前写的计算hash值用的小程序CryptTool,核心功能早已完成,就是计算字符串,或文件的hash值,包括多种算法,比如MD2、MD4、MD5、SHA1、SHA256等等等等。后来出于尝试的心理,想给程序加上外部脚本扩展的功能,准备支持Lua、Python、Ruby三种脚本,而且不自己写粘合代码了,而是采用SWIG自动生成。Lua和Ruby的支持很快就完成了,可是Python的却一直有问题,网上翻了不少代码,以前C++Builder中的那个代码也翻出来,都是有问题,那时就搁下来,今天又心血来潮地想弄一下。
  最主要的困难还在于对Python缺少了解,但这并不能成为借口,Lua和Ruby不就好好地嘛!这里我用的方法是把外部脚本文件作为module,import进来,但是一直返回一个空指针。实在没办法,PyErr_Print打印的内容又是输出到控制台的,而我的是个标准的MFC写的GUI程序,所以只好另外建了个控制台的测试工程,幸好模块独立性较好,几个文件拷过去略作修改就可以了。通过控制台输出的出错信息才知道,原来是import时,还会连带着import一些python自己的库,于是把python的lib目录添加到sys.path里。另外,如果说import这外部脚本文件时,报找不到该名字的module,就把脚本文件所在的路径也添加到sys.path里。终于可以在import时,执行一遍该脚本了!不过还有另外一个问题解决不了,就是调用Py_Finalize崩溃!在网上找了一圈,也有一些老外遇到这个问题,不过要么就是没有下文,要么就是给出的解决方案不适合我这种情况。因为我是import来执行脚本的,当没有Py_Finalize,而同一进程内再import时,就不会再执行了,作为外部扩展,有一个办法是定义一个基本规范,脚本中一定要实现一个指定名字的方法,再由宿主程序来调用这个方法,但这太不友好了。其实如果能用PyRun_File之类的API来强制运行一个文件的话,也是可以达到目的的,但还是绕回原来的路上去了,我这里PyRun_File这类API死活不能正常执行一个脚本文件,天呐!
  于是还剩下一个遗留问题,怎么能解决脚本每次都能执行的问题呢?嵌入Python真辛苦啊!

2008-11-01

杨柳坑快乐游

  部门组织去杨梅坑游玩,之前只看别人去玩过,自己却没去过,所以在出游前,一直有点儿兴奋。
  早上等车等错了地方,有点囧,有点恼。坐了一个多小时车,终于到了目的地。每人都去挑了自行车,好久不骑了,有点感怀。租好了车,却一直不出发,等几个自驾车过来的人,有点不耐烦。估计等了有十几二十分钟吧。
  一路逆风,而且风很大,路上看到不少前面的人被风吹掉的旅游帽。大概骑了半个小时,到了目的地,一个别墅,再过去就是悬崖了,悬崖不高,下面是海!在这么偏僻的地方看到悬崖,不禁想起很多肥皂剧里的那些跳崖的剧情,有点无语,当时的人们想像力还真是不够丰富啊。
  悬崖上也风很大,拍了几张合影,也没什么玩的,就回去了。回去是理所当然的顺风,大概15分钟就当了,然后就是吃中饭。中饭比较合我口胃,是海鲜,但称不上大餐。价格不便宜,但也算不上贵。海鲜也是最常见的虾、蟹、鱼、花甲、扇贝,其他的就没什么值得说了,不过我还是吃了3碗饭,哈哈。
  吃过中饭,就去桔钓沙。上一次去桔钓沙应该是2006年9月9日吧,记得当时小丫头不在深圳,说得她很遗憾的样子,小丫头应该很喜欢去海边玩吧。这次时节不适合下水了,风也很大,于是我只是躺在席子上用手机上网看小说,就这么过了一下午,直到4点半,打道回府。

2008-10-28

n多bug

  今天终于发版本发出去了,但是,用别人的话说,几乎不可用。
  这个版本确实进行了大幅修改,不但增加了新功能,还进行了重构,对原来使用的那一套机制50%被翻修过了。
  那些出现的问题,都落在没有经过单元测试的模块,但是那些模块都是我不知道如何进行方便有效的单元测试的。
  其中主要的还在于两个模块,一个是界面交互,确实不好测,另一个是数据库操作。当时的接口设计可能过于复杂了,导致后来想做单元测试时,很是畏惧。实际上,数据库操作部分,也是可以进行单元测试的,而且我想着要把本地数据库从Access换成SQLite,更是应该趁这个机会补充单元测试用例了。

2008-10-27

马不停蹄

  今天写代码可用马不停蹄来形容,一天下来,不停地敲键盘,不停地commit,不停地收到CruiseControl的构建报告。一直到下班,回顾一下,觉得好像也没做很多事情,可能是太零碎了,写日志的时候,看了看SVN里的commit记录,确实可以写好多条。
  明天就要发版本了,不知道有哪些地方落下没考虑到的!
  倒是在用hhc.exe编译doxygen生成的文档时,老是崩溃,搞得我有点郁闷。本来嘛,一个工程有一个chm文档就够了,现在好了,只能用zip把众多html文件打包,要看的时候还得解压,而且解压速度不快!

2008-10-26

在家烫火锅

  约了几个同事(F、S、W)来家里烫火锅,早上还是跟平时上班时一样准时自动醒来,已经麻木地不知道郁闷,在床上赖了一会儿,起来开电脑,看了一下更新的小说,然后无所事事,整那些代码,一直到9点多,出去剪头发。剪头发这件事已经酝酿了很久了,但一直没有兑现,今天终于狠了狠心,看了一下记录,上一次剪头发是3个多月前,汗!
  剪完头发,离约定的时候还早,便又回到家中玩电脑,一直到W给我打电话,匆匆赶出去,一起去超市买菜,买了不少,我也没有估计我们食量的能力,所以就尽量多买点。
  吃了两顿,挺好玩的!

2008-10-25

bug,死循环

  昨天就发现了,程序结束时,会退不出,看样子是死循环。今天单步跟了一下,发现特别恶搞的原因,在一个while后直接一个分号,单步时还没看清楚,只是奇怪怎么一直在这一行跳,还以为VC调试器出问题了呢,汗!
  中午时,突然想起来,这几天一直被之前的思路占据着,还是沿用老的那一套,结果搞得我午觉都没睡安逸,心里惦记着一件事情,真不爽啊,差点还以为之前写的都要推倒重来,下午调了调,发现还是可以保留一部分代码的。CppUnit用得还是安逸的,昨天从网上找来了CppUnitLite、CppUnitLite2、GoogleTest、UnitTest++几个测试框架,打算稍微看一下,最后选择其中一种来用。先看了CppUnitLite,没有文档,有一个简单的demo,对我来说,上手太不容易了。我估摸着,最终还是会继续使用CppUnit的。
  又有人提到加强编辑器的联想功能了!VAX确实可算是所有代码编辑器自动提示功能的典范,我们一直在说,我们做不到像VAX这种程度,是因为Ruby动态语言的特征,不能通过静态分析得到某个对象的类型。我有时在想,假如我们用的是C++,我们能做到像VAX那种程度吗?针对这个问题,我回了一封邮件给老大,分析了VAX的自动提示功能分成三部分来做,我们有什么对应的策略。这三部分分别是,分析源代码,得到各种变量、对象的类型进行提示;编辑代码片段,设置快捷键进行提示;加入拼写检查,可在一定程度拼写错误的情况下,进行提示。第一点,需要一个完善的语法分析器,目前我们没有;第二点,技术要求不高,原来我也想过要做,结果被其他事缠着,就搁浅了;第三点,从来没有研究过,没有技术积累,根本不知从何下手。邮件发出去,估计老大也是眼睁睁地看着没有办法,所以什么回应都没有。

2008-10-23

搞定弹出Windows域账户对话框

  今天上午下决心问了一下同事,又用proxy登出外网,搜了几下,终于搞定通过弹出Windows域账户对话框来输入新的用户名。代码在codeproject上有完整的,效果很好。弄得我心情很愉快,自我感觉良好,极大的改善了易用性啊!
  完成了这个后,却没有做多少其他事情。其实我也没有多少懈怠,只是偶尔停下来休息一下,但进展确实很缓慢。我现在丝毫不怀疑单元测试的作用和必要性,尽管它似乎花我了不少时间,但我总觉得是值得的,无论是对我心情的调节,还是对代码质量的保障,都有很大作用。
  后来主要集中精力在做组织结构管理模块。该模块将数据保存在远程数据库中和本地配置文件中,而两个地方保存的数据的格式差别比较大,读出来的还需要再互相转换一下。这不但需要多写不少代码,而且可以预见到的是,也会占用不少执行时间。我都开始怀疑当时把两边的格式差异弄得这么大,是否很不明智。结果到下班,还是没有完全搞定格式转换部分,只好明天继续了。另外想起来,应该提供一种途径,可以执行一些特权操作,比如明确从某配置文件加载数据,明确将数据写入数据库等等。总的说来,机制部分基本做得差不多了,后面实现用户交互部分应该没有多少工作量了吧!

2008-10-22

又被培训了一下ruby

  今天又培训了一把ruby,再次让我感受了一遍ruby的强大,真是一个无所不包的魔幻型语言啊!
  开始,老大先演示了一个分布式ruby包的应用,几行代码,就能实现一个服务器端组件,再几行代码,又实现了一个客户端,调用了服务器端的对象,其简便程度太让人吃惊了。这种应用很能吸引人,特别是可以做一些加密功能。但我想我还是不放心就这么去用它的,我很担心它的性能。反正WEBrick开的Gem server有内存泄漏问题,就一直让我对ruby做实际应用持有怀疑心理。在我看来,也许脚本语言的真的主要战场在字符串处理上,写个小程序也许可以应付,开发成本比起C++来确实低得多,但做稍微有点规模的应用,就还是让C++来吧。
  而Lua这种,在我看来真的还是用来做为C++应用的扩展机制,描述一下插件逻辑,我想不出还有哪里能更适合它的,和还有哪个脚本语言比它更适合来做这个的了。
  Ruby让我最不爽的是,对嵌入支持不好,《Programming Ruby》一书就提到,ruby不是设计成用来嵌入的。不过我在想,以我目前的需求,即使要嵌入,一个进程用一个解释器应该能满足需要了。看公司那个项目里,为了让嵌入的ruby解释器多做点事,就创建了一个又一个新的工程来嵌入,也是一种解决办法啊,哈哈。

2008-10-21

进展缓慢

  再一次出乎自己的预料,太慢了!
  不过通过单元测试,来保障代码的正确性,实在是一个非常不错的办法。我用的是CppUnit,写测试用例还是比较麻烦的,要在.h和.cpp两头写,每次都是复制其他的代码结构,据说CppUnitLite等等新生代的单元测试框架用起来要省事一些,不过我没用过,并且我现在很看重CppUnit能使用MFC的界面,也能输出XML格式的报告,而且还提供一个xslt文件,可以把报告格式转换成和JUnit类似的格式,这样CruiseControl就能直接合并到它的日志里。就是这些原因,使得我迟迟不愿意再花时间和精力去了解其他的框架,继续忍着那些小麻烦。
  现在用起boost.bind和boost.lambda来,比以前熟练了不少,但还是只用到一点它的皮毛。前几天看到一篇blog,讲boost.function和boost.bind结合使用的威力,让我大吃一惊,原来boost可以这样用!就这么投入中去了,再好好学习巩固一下STL,学习一下算法,学习一下boost的应用。

2008-10-20

彻底累了

  估计真的是体力透支了,影响到正常的工作了,提不起精神。
  说起工作,一个小小的需求实现,也原来要涉及到这么多模块,真是郁闷,我的架构设计能力还是不行啊,继续努力学习啊!明天开始着手另外一个大需求的实现吧,三天,能做成什么样子呢?我早已没有之前估计工作量时的那么乐观了,过高地估计自己的能力,过低地估计了实现难度,唉!

2008-10-18

自定义保存文件对话框

  早就想在保存文件时,能让用户顺便多输入点信息了,于是自定义保存文件对话框的需求就提上来了。在网上搜了一遍,各种方法倒是不少,不过都跟我想像中的有点区别,我想在MFC中做,就希望能尽量的简单方便。于是就搁下了,直到前天,在公司里想起这件事,问了问同事,同事给我一个例子,VC6写的工程,看了觉得很简单,但是回家自己弄还是不行。昨天又跟同事交流了一下,再加上晚上在网上找资料,结合着弄,终于成功了。
  首先,添加一个对话框资源,加上需要的各种控件,最重要的是要加一个ID为stc32的控件,可以是Static,至于大小、位置,可以之后慢慢调整,以及对话框的风格要加上WS_CHILD。
  然后,给该对话框添加类,基类就选CDialog好了,生成代码后,把基类从CDialog改为CFileDialog,尤其要注意,CFileDialog的构造函数需要更多的参数。
  再之后,要给m_ofn成员初始化一下,先是dwFlags要有OFN_ENABLETEMPLATE,再lpTempate要指定到刚才活到的对话框资源。
  最后,就是看情况,重载几个虚函数,比如OnFileNameOk,OnFileNameChange等等。
  搞定!

2008-10-17

搞定phpBB的NT域账号认证登录

  当时看到phpBB后台有选项可以选择认证方式,有三种,分别是DB、Apache和LDAP,我就觉得要糟,老大知道后肯定会要求用NT域账号方式认证登录。
  果然昨天下班后,老大就发了邮件,说最晚下周要搞定这个问题。我郁闷啊,其实我早就开始想办法去寻找解决办法了,当时直接切换到LDAP认证时,提示说LDAP扩展没有安装,而用Apache认证方式时,说什么账号名要一致云云。
  到网上找了很久,也没有发现有价值的内容,倒是sf.net上有个for phpBB 2.x版本的mod,可以使得支持LDAP认证,不过我装的是3.0.2,而且下载下来那个mod,我都根本不知道即使我装的是2.x版本的,怎么应用上去,所以此路不通。
  不过看到Apache认证方式,再结合项目组用VisualSVN Server搭建的SVN服务器,给我一点思路。我是可以通过Apache来实现NT域账号认证的,再让phpBB来使用Apache的认证结果。虽然思路是有了,但实际上,我根本不懂Apache的配置文件要怎么写,看了半天它的手册,也不知所云,只知道它是有mod可以支持ldap认证的。最后实在没办法,抱着试试看的心情在公司网上发了个帖子询问,终于有个人回复了,问他要了点例子参考,果然OK了!
  基本搞定phpBB的NT域账号认证登录问题!

2008-10-16

项目从VSS迁移到SVN

  今天开会的时候,不知怎么的,提到源代码管理的问题,直接就扯到要把源代码从VSS迁移到SVN。这是我之前几次考虑过的事情,不过当时的想法是,既然是迁移,就要把所有历史记录都迁移过去,费了好大的劲,最终还是没成功。当时的问题是,vss2svn并没有转换成功,后来想想继续用VSS也并没有多大影响,于是还是继续用。今天老大就说,历史记录丢了就丢了吧,反正VSS还在,到时候实在有必要的时候,还是可以看的。这样一想,也就霍然开朗了。会后立马动手,从VSS上Get latest整个目录,然后import到SVN上,基本没费什么力气。而且趁此机会,把方案、设计文档、帮助手册、会议纪要也都传了上去。然后绑定redmine上的版本库记录,不过有点问题,据同事说,不但需要svn的客户端程序,还需要重启系统,光是重启redmine服务是不行的,我大汗!
  

2008-10-15

新版本实现新需求

  今天继续昨天的工作,要能给流程也添加关联的文档和子流程,当时评审需求的时候,我还以为没多少工作量的,这两天做起来才发现,大大地错了,要做的事还是很多的,不过幸好当时也是怀着一点小心思,多报了点。
  首先,数据库处理模块需要增加相应的接口,因此COM组件也同样需要加一下封装。然后,核心业务处理模块需要封装数据库处理模块的接口。最后是界面响应增加入口,而且界面响应有三处需要增加入口的。
  有了添加关联,同时也就需要查询和删除功能,都需要做不少事情。而之前的代码写得也略微复杂了点,现在增加代码时,发现有不少需要重构的。自从读了《重构》后,把这种活动看作理所当然的,不知假如我没读过该书,仍然遇到这样的事情,会怎么处理呢?
  后来偶然看了一下版本计划,发现这些需求竟然不是要求最近这个版本实现,而是再下一个版本,这下我就怵了,宝贵的时间就这么消耗掉了。于是马上掉头做另一个需求,要能实现关联超链接。这时,又发现一个UCD的问题,关联时,弹出太多对话框了,版本历史上最多的时候有3个对话框需要用户进行交互,现在已经减少为2个,但还是不爽,应该在1个对话框里把所有这些都搞定,于是再次重构!
  没完!

2008-10-13

很流很水账,银湖后山

  昨天又跑出去玩了,玩得太high了,一直到后半夜1点多才回到家,对于不久前的我来说,这简直是太让人难以置信了,我不是应该是个宅男么,不是很不喜欢跟人出去high的吗!但事实就摆在眼前,我跟着一群不熟悉,甚至不认识,很多还是第一次见面的人一起出去玩,而且玩得那么晚!
  早上像平时上班一样的时间起床,收拾了一下便出门了,先坐317,到了市二医院转58路到武警医院,太早了!当时上了317我就想,这次应该会提前很多时间,果然,317坐了15分钟,58路坐了10分钟,总共半小时不到就到了集合地点了。本该9点才是出发的时间,结果8点10分就到了。
  爬山,仍是主题。这次爬山路线就比较隐秘了,那些路应该都是之前爬山的人走出来的,并不像莲花山、梧桐山、南山这种有专门修过的登山道,而且更陡!不过相比那次爬梅林后山,速度要慢一些,而且这次我为了防止重蹈上次梅林后山的复辙,背了双肩包,装了3瓶共1800ml的佳得乐,1包摩卡蛋糕,1包萨其玛,6个桔子,尽量最后没有用上多少。
  我们在差不多山顶的地方进食中饭的,我其实没吃自己带的这些东西,倒是吃了别人的一些枣,挺甜的。有3个mm还带了盒饭,式样全都一样,太可爱了。无聊时,杀人游戏是个老少咸宜的活动,但是和不熟悉的人玩,而且玩的规则也不是我喜欢和熟悉的那种,让我捉襟见肘,屡屡失误。
  众人都有些疲乏,便不再爬山,直接下了山,快到山脚时,进入了一片高级住宅区,别墅区,里面的保安还不让我们借道,我们只好从外边再绕出去,搞得另一边的保安们也很紧张!下来了,就是银湖公园了,那里没什么玩的,于是众人商量了很久,走走停停商量着,最后决定到八卦岭去吃饭,如果有玩的就顺便玩一下。
  结果是到了八卦一路的一家叫大骨仔的店,离吃饭的时间还早点,就几个人打麻将,几个人打拖拉机,然后吃饭。吃饭倒没什么值得讲的,跟所有下馆子吃饭都一样,喝点酒,吹下牛。
  吃完饭,人就先散伙了一批,有人说要去洗脚,哈,这是我很喜欢的一种放松方式,就留下,点一下人,刚好4男4女,不过形象真的不好,全身汗臭,背个大包,着装也不整洁。进了一家叫一方山水的店,装修倒是还可以,不过技师水平不怎么样,而且收得也贵点,38一个人,不过有茶和奶茶喝,成本也是这么高上去的。
  洗完脚,叫淡蓝色的mm硬是要叫人再去KTV玩,特别是威逼利诱群主,哈哈,开始群主还是很强硬的样子要回家,最后还是经不住淡蓝色的软磨硬泡,于是8个人再赶到华强北欢唱100,同样,装修不过,包间里还带卫生间。几个人唱起了歌,我就跟淡蓝色几个人玩起骰子,不过我玩不过她,郁闷,开始单玩的时候还好点,有个更差的人垫底,后来分组玩的时候,就惨了,不停地输,不停地喝,喝得我撑死了。
  大概high了3个小时吧,终于决定回去了,毕竟第二天还有些人要上班的,包括我。打车回家时,我身上的现金已经不剩下多少了,还好是与人拼的走的,可以不用付这全程的价钱,回到家,1:14!

2008-10-09

再次放弃升级工程到VS2005

  本以为今天闲一点了,可以干点其他事了,于是琢磨着把工程从VS2003升级到VS2005。升级的事,之前一直有想,但一直由于这样那样的原因而放弃了。这次又动了这样的想法,一方面是因为VS2005上才有Refactor!,另一方面是换了高版本的dot后,dot本身就带有8.0版本的crt dll,所以想着如果把7.1版本的crt dll换掉,感觉会舒服一点。
  先看了看最基本的ACE和XTP有VS2005编译出来的lib和dll,然后开始升级工程。这次学聪明了点,不停靠VS2005自己的升级功能,而是直接自己编辑.sln和.vcproj文件。基本上只要把版本号改了,就可以了。为了回退方便,我先复制了各个.sln和.vcproj文件,并改名,然后才改版本号。再用VS2005打开,编译链接。这个过程倒没出多少问题,2005和2003最大的几点区别是,2005中对字符串操作的函数作了扩展,其次是manifest的引入。这都没有引起多少麻烦的事,只略作修改就可以了。
  最后却因为另外一个没想到过的问题而促使我放弃了升级:编译太慢!真是没想到啊,也不知道是本来VS2005的编译器就比较慢,还是说这个编译器在遇到某些情况就会性能降低,比如使用了大量模板等等。反正最后我忍无可忍了,rebuild一次,就要好久好久,2003下明显要快得多,没多少犹豫,决定还是继续使用VS2003吧,顺便庆幸了一下,Impeller幸亏不是用VS2005编译的,不然会多花多时间啊!

2008-10-07

夜登莲花山

  本来没打算去的,直到今天中午的时候还没想要去的,结果下午的时候偶然发现飘飘在QQ上,就聊起来,于是被她鼓动了。
  下了班,匆匆去取了点钱,然后先坐车回家换衣服,飞快地再坐小巴到梅林关转车。结果给飘飘打电话,说还没出门,晕,于是我只好自己一个人先去了。爬上370,到北大医院下车,在附近转了转,没发现可以吃饭的地方,于是只好在莲花山公园入口处的书报亭买了包豆干来充饥。还没看到大部队,于是在门口随便吃了起来,几下就解决掉了。
  过了没多久,看到阿金,于是走过去,倒是认出几个人来。爬山之前等了很久,因为有很多人一起来。
  莲花山本来是很矮的,一小会儿就爬到顶了,所以估计也是出于这个考虑,我看领队的故意绕了好些路走,直到我出汗了,说起来今天还是很凉快的,而且结果我的那瓶脉动被飘飘解决掉了。
  还是很快,就到了山顶,人山人海啊,我直到今天才知道,重阳节是要登高的,汗!人太多,只是拍了几张照片,便下来了。到中途吃水果,似乎是有吃西瓜的习惯的,连拍照的时候喊的都是“西瓜甜不甜”,呵呵。
  吃完水果,因为时间、天气等原因,安排到公园门口集合,然后要吃饭的一起再去腐败。那一带我不熟,被他们带去一个湘菜馆,吃的当然是最普通的湘菜,当然吃什么不是最重要的,重要的是认识一些人,大家互相介绍一下,我还是第一次这么庆幸当然给自己取了这么一个特别的网名,哈哈!

2008-10-06

升级dot

  今天偶然发现有一个图,dot会崩溃,换到2.20.x版本后,就没问题了,看来在适当的时候,升级是很有必要的。但是同时又引出一个新问题,高版本dot生成的svg格式,里面使用的坐标系比以前的复杂了,居然出现了科学计数法和负数,这让原来勉强能工作的格式化后活动框的定位又不行了。经过一番研究,发现在svg的开头有一个transform属性,该属性的值分成三部分,其中一部分是translate,经过试验发现,该translate的值加到下面的坐标系中的值,刚好能对应上以前使用的那种方式的坐标系统表示的值。于是乎,也就是说,又要多一步操作了。
  升级到高版本的dot,同时也带来一个新问题,就是如果发布这个dot套装。反正我是不想在我的安装程序里面再执行一遍Graphviz的安装程序了,像Wireshark一样,感觉不是很舒服。之前的低版本(好像是2.05.x还是2.15.x)dot,很简单,一个exe文件,五六个dll就搞定了。而新版本的dot而远远不是,经过在一台没装过Graphviz的机器上实验发现,比较省事的一个办法是,复制dot.exe和所有同目录下的dll,一个config文件,一个msvcr80.dll和对应的manifest文件,以及Graphviz安装目录下的lib和etc目录下所有内容,大了不少啊!
  今天又想了想,要是有个服务器端的话,有些事情可以容易得多。比如今天突然给了我一堆域账号,我要一个一个在MS SQL Server里先添加账号,再把账号添加到数据库中,很是麻烦,如果有了服务器端,就不需要这步了,最多自己维护一个自定义的很简单的列表;有了服务器端,可以通过服务器端对所有客户端进行广播,而现在的架构如果来做广播,似乎有些不伦不类;如果有了服务器端,就可以优化网络连接和数据传输,从而对系统响应的速度有所提升。不过很大的一个坎,如果有了服务器端,开发、调试的难度将大大增加,维护工作量也随之增加。

2008-10-04

WallpaperHelper W.I.P.

  昨天说干就干,打开尘封很久的工程,添加一个窗口,把那几张现成的图片抠过来,然后计算一下桌面工作区大小,把窗口放在桌面右侧,像是侧边栏的样子。结果一开始,什么都没有显示出来,这是相对比较麻烦的出错情况,因为根据之前使用GDI+创建异形窗体的经验,这时候任何地方都有可能是出错的地点,所以要找出原因就要费点工夫。仔细对照之前写的代码,一点点的修改,终于能让它显示出一个窗口了,但是窗口仍然是窗口,没有按照预想的那样把png图片显示出来,并按图片渲染窗口形状。最后发现是在创建窗口的时候,因为心急,直接把窗口设置为桌面的子窗口了,如果把那几行代码去掉,就都正常了。经过这次实践发现,用GDI+实现异形窗体可以随意缩放窗口大小的,一般说来,要把窗口调整到需要的尺寸,通常是大于或等于图片原始大小,这时再把图片按窗口大小画上去就可以了,这种特性在绘制侧边栏的时候有用,比如可以只有小小一张图片,但侧边栏可能很长,就直接这样拉伸了。
  能显示出侧边栏的底座了,就要开始考虑接下去怎么做了。鱼鱼和雅虎是两套不同的方案。鱼鱼只是能计算一下各个widget的大小尺寸,根据当前侧边栏上停靠的widget计算出其他widget停靠的位置。雅虎的稍微复杂点,它的一个widget的可见内容分为两部分,一部分是在桌面上散布的体现真正内容的widget;另一个部分可算是widget图标,停靠在侧边栏上。这样对于widget开发者来说,刷新界面时需要刷新两部分的隐性要求比鱼鱼要大,鱼鱼的只要刷新widget主窗口就可以了。当然雅虎的也不是强制要求一定要同时刷新图标,只不过有这样的表现的机会,为什么不利用上呢!
  今天又偶然发现,雅虎的widget也使用了跟chrome类似的sandbox技术,从任务管理器上看多显示一个widget,就会多一个YahooWidgetEngine.exe进程,数完widget数目后,还多一个进程,我猜应该是侧边栏的。自从见到chrome后,我就莫名地对这种sandbox做法很有认同感,据说我们部门在北京的分部做的一个测试用例开发执行工具也是用的这种方式。不过相比Unix-like系统,在Windows下创建进程的开销相比就大了点,随便开了十来个widget看看,有两个进程内存占用10MB多一点,其他的都是1MB多,我估计如果它若是使用单片式结构的话,同样开这么些widget,占用的内存数应该没有这些的总和多吧。再说说由此引出的进程间通信的问题,毫无疑问,进程间通信的开销明显要比进程内通信的大,在Windows上应该更突出,不过对于像widget这种应用,进程间通信的频率和数量应该都不大,影响也倒不会太大;其次是从程序开发的角度讲,进程间通信应该更难使用,尽管Windows确实也提供了不少机制,但终归是难用啊。最后还有另外一个问题,对于稍微有点常识的Windows用户来说,这种方式是否也能得到他们的认同呢,某一天打开任务管理器突然发现有这么多相同名字的进程,会不会觉得反感呢,至少我是看到有人这样非议过chrome的。
  再说点WTL相关的问题。昨天发现一个用WTL写的应用,在VS2005下编译,Debug下好好的,到了Release下连编译都通不过,删了一些怀疑的代码,还是编译不过,最后从WTL的源代码看到,原来只要在工程设置里把是否使用ATL的最小CRT关掉,就没问题了,之前也有因为这个设置引起奇怪的编译不过的问题,缺少官方正式支持的东西就是累啊,这WTL光是这些头文件包含,宏定义,就让人头大了。
  最后八卦一下Inno setup,发现有时居然会out of memory,这时把里面两个压缩级别选项都从ultra改成max就好了,不知道是不是Bug?

2008-10-03

研究了几个widget工具

  昨天心血来潮,装上了鱼鱼桌面秀看了看,以前也是装过的,有乱码,现在经过几个版本的更新升级,软件名称也已经换过了,但是乱码问题还是没有解决,原来用Delphi开发的就这么郁闷啊!我用的是英文的XP,打了中文语言包,照理显示中文是没有问题了的,不过这个软件在安装路径中如果有中文的话,就不能正常启动。另外,界面上也不全是乱码,某些地方的中文还是能显示出来的。还有,装的2.1.1纯净版,运行非常不稳定,经常出错崩溃。如此看来,这个软件也就是界面上比较出色了。
  说完了缺点,来看看它的技术特点。现在这个软件也算是一个widget工具了,可以有一个侧边栏,依靠在桌面的右侧,在该侧边栏上的可以安放一些widget,一般就是显示当前时间,当前CPU占用率,内存使用率,某个城市的天气情况等等,翻来翻去就是这么固定的几个内容,主要体现在界面上的设计有所不同。看了一下它的SDK,终于基本搞明白,原来是程序内部固定了只提供这些服务,外部每个widget有一个脚本文件,可以是vbs或js,调用程序提供的那些对象、方法,然后绘制界面。除了一个描述逻辑用的脚本文件外,widget还会有一个配置文件,记录一些最基本的信息,比如图片文件路径等。widget可以通过鼠标拖拽,拖到桌面上任意位置,也可以停放在侧边栏上。稍微想了一下,觉得这个应该不难实现,也就是侧边栏是一个单独的窗口,在拖拽widget的时候,检测当前widget的位置,如果进入侧边栏窗口区域,则自动调整widget的位置,看起来像是多个widget贴在侧边栏上一样,实际上还是各个窗口各自管理。如果拖出了侧边栏,则拖到哪算哪。后来看了一下窗口类信息,果然跟我猜想的一样,说起来我的LLYFSpy都不能正常使用了,抽时间也得好好整一下,就作为WIND的一个插件好了。
  看完鱼鱼桌面秀,我又想起盛大的widget雅虎的widget,于是上它们的网站看了看。盛大的是能放到游戏中去的,这是一大特色,但目前似乎还不能放到桌面上。雅虎的看起来则要比鱼鱼的专业得多,widget能做的事也多一点,界面响应和交互能力也要强些。雅虎也是给每个widget一个配置文件,但是XML格式的,而且把逻辑处理的代码也放到这个配置文件里,说起来,单纯从用户角度讲,雅虎的方案更好一点,但如果能把一个widget的所有文件都打包的话,这个优点就不存在了。如果从widget开发者的角度讲,可能鱼鱼的方案稍微好一点点,因为不同的格式放在不同的文件中,用支持syntax highlight、auto-completion的编辑器来方便得多,现在还很少有编辑器能同时支持混合的语言。
  看了这些之后,我就想,我是不是能把WallpaperHelper里的桌面时钟日历功能扩展一下,不就也有一个widget功能了嘛!看它们用来扩展的都是vbs或js,鱼鱼似乎是直接用的MS的那个WSH组件,这有一个很大的好处,直接用WSH的强大功能,它内置了不少接口,像FSO之类的,还可以直接调用ActiveX,实在强大!雅虎的倒是看到一个js32.dll,可能是mozilla的那个js引擎。盛大的没看。但是我现在对于要嵌入的脚本语言,只能Lua感兴趣,公司里也曾经有人讨论过对于嵌入的语言使用Lua好还是js好,当时我的观点是看应用场景,希望脚本做些什么事,再来分辨做这些事用哪种语言方便。

2008-10-01

参观房展

  今天中午偶然得知在会展中心有房展,于是临时决定去参观一下,虽然买房对于现在的我来说还是比较遥远的事,但是感受一下那种气氛,了解一点市场行情还是可以的。
  本来以为会展中心可以坐391直达的,结果后来才发现,391早已经不知什么时候改线路了,而且改了线路之后我曾经坐过,只是当时没有留意而已。于是下了车,一直走路过去,大概也就是十几分钟的样子吧,不过也出了一身汗。
  展厅里外都有很多人,果然比较热闹啊!对于房展,需要关注些什么,我是一点经验也没有,所以像无头的苍蝇到处乱走乱看,看到很多地方都排起了长队等待领取纪念品,觉得还真是无聊。另外就是看到几处文艺表演,有个还算pp的mm在拉节奏轻快的小提琴,看她嘴角弯弯的样子,让我觉得像马姐姐,于是拍了两张照片下来,不过马姐姐的身材可比这mm的好得多!后来看到一处有六七个像幼儿园的小女孩在跳舞,也是很轻快活泼的节奏和旋律,很可爱,但似乎脸上又带有一种跟她们年龄不相符的成熟的神情,看了一会儿,想拍照,总是有人挡在前面,找不到好的角度,不禁又佩服起这些小女孩的体力还真不错!再后来,看到有两个mm在跳比较热辣的舞了,穿得也少,同样是有n多人挡在前面,还有不少人总是在她们前面1米左右的距离横穿而过,甚至有个中年妇女抱着个婴儿,直接坐在那个舞台边上拍照,唉!
  对于房子,倒真的没怎么关心,偶尔留心了一两处,总觉得价格上太划不来,比如有一处复式的空中别墅,167个平方,在盐田,总价大概三四百万,心里就很不屑,觉得太不值了。
  出来后,又走了很多路,累死了,还是得自己有车啊。

2008-09-30

软件开发所需的工具

  今天断断续续写了几行代码,再次感叹,在这VS中配合VAX写代码给人那种酣畅淋漓的感觉,任何其他地方都是体会不到了。网上有不少人不少文章在说,使用IDE有很多坏处,让人不知道背后的机制原理云云,对于此种言论,我很不屑。不是说,懒惰是程序员的美德吗,既然有工具能帮人完成一部分工作,为什么不放手,而去追求那虚无缥缈的所谓“高手”的虚名。
  从csdn上看到新闻谈及VS的下个版本,这MS的动作也太快了点吧,VS 2008才出来不到一年呢,CodeGear真的彻底完蛋了!再没有哪家公司能像以前的Borland那样生产IDE,跟MS抗衡了。
  今天写代码时,发现需要记录一些想法,或者是计划,但我找不到合适好用的工具。之前也看到一个群组里有人开话题讨论用什么来记录想法,有人提到evernote,这个工具我也看过,是个共享软件,而且对中文的支持不行,仅这两个问题让我就望而却步了。之后再也没有其他的类似的好工具了,平时如果只是为了记录下问题、需求这种跟软件开发强相关的信息,我倒是搭建了一个Redmine服务器,它也有一点项目管理的功能,但还是太弱。在公司里,流行的做法是用MS Project来做项目管理,用Excel来记录需求,用notes上的CMM库来记录问题,不过我因为所在部门的不规范性,所以更自由一点,或者说其实是没有机会使用那么高级的东西,只好还是在redmine中折腾。
  寻找好用的全流程软件生命周期管理工具!

2008-09-29

爬梅林后山

  今天是我第一次出去参加这种社会性质的户外运动团活动,吃了没经验的亏,当时没有准确估计行程,只买了一瓶脉动便跟人上山了。当时也是不了解,单纯地以为只要走个十几二十分钟路就可以了,谁知是足足4个小时,从上午10点开始,一直到下午2点,可怜我连早饭都没吃,到12点多时,那瓶水就喝完了,然后就又饿又渴又累地翻山越岭,又不好意思开口向别人要水,毕竟是不熟悉的人啊,忍了近2个小时!
  到下午2点过一点点的时候,终于到了吃饭的地方,最急着解决的事便是解渴,跑到自来水笼头那里,估摸着那水是山水,确实没有那种自来水出来的消毒水味道,大口喝了好多,还是不解渴,又买了2罐百事,没办法,没有其他适合的饮料。
  那些菜的味道倒真是不错,那汤也好喝,就是量不多,也过钱也不多才一人给了25块钱。到下午4点的时候就出发返回,这次走的路就没有之前那么困难了,都是平缓的石板路,跟着几个人一边走一边聊,还没觉得不适,前面那段路上我都没怎么说话,连拍照都只是照了几张风景,返回的时候倒是拍了些人物的。
  我还是内向了点,不知道怎么能挑起话题,唉!

2008-09-27

努力写好代码

  前几天偶然lint了一把我在做的项目的源代码,结果发现近千个error。这让我比较困惑,大致看了一下,有不少是我并不期望它进行检查的,但又不能简单地把这类检查项屏蔽掉,所有就不知道怎么办了,lint应该是有意义的,但具体要怎么做,做到什么程度,我就完全没有头绪了,如果仅仅是为了减少错误项的输出而屏蔽检查项,那就失去lint的意义了。
  我还是比较努力地希望自己能尽量写出一些优雅少错的代码的,也尝试在实际工作中使用一些方法和理念。今天在公司定位崩溃报告模块的问题,最后发现读取PE文件版本信息就有问题,但本来出于该模块的特殊性,很难直接在IDE里调试该模块,经过一些时间的折腾后,给取PE文件版本信息的类写了个单元测试,用CppUnit来跑,就算被测代码逻辑有问题,调试起来也方便多了!于是我又想到,这单元测试还真是个好东西,为什么我(们)就是不愿意做呢?我想主要原因还是在于,对TDD对项目进度的影响仍然没有足够的信心。另外再扯远点,我有点不想用CppUnit了,总感觉有点麻烦,现在这类框架倒也不少,google、Boost都有单元测试框架,其他还有什么UnitTest++、CppUnitLite等等,可选择的范围倒是不小,但我有一个顾虑是,这些框架输出的报告能不能像CppUnit那样跟CruiseControl日志合并呢!
  另外再说说重构。我现在倒也确实有这样的倾向了,不断地在重构和实现功能这两个角色之间来回切换,也很习惯这种工作方式。看这个项目的代码,虽然没有翻天覆地的变化,但确实也有不少的改变,而且代码量也比最高峰时期少了20000行左右,这个比例不小啊,1/4多。不过我还是很明显感觉自己在重构这方面有待提高,首先是缺少理论方面的学习,然后再来考虑怎么应用到实际的编码中去。真的要抽时间好好读一读书架上那几本书了!

2008-09-26

Office2007的改进之处?

  今天突然想到,之前遇到的两个操作Excel的问题,该不会是在2007里对2003版本的修正吧!
  最早使用COM操作Excel2003出现的问题是,在我的电脑上,打不开Excel文件,硬是说没有正确的序列号,我分特,公司花了那么大一笔钱买了license的!想了一些办法,仍然没有解决,为了不影响进度,忍痛在512MB内存的机器上装了个2007版的Office,但是奇怪的是,如果直接运行Excel 2003 SP2,编译文件什么的,都是好好的。
  第二个问题是,突然一夜之间,所有的使用Excel 2003的机器上,都不能对图形全选操作了,用鼠标是可以选择的,但如果通过代码来SelectAll则必定异常,无论是在VBA中,还是通过COM接口操作,屡试不爽!很无语的是,当时定位了好久,也因为只有我自己的开发机上是用的Excel 2007,根本暴不出这个问题,最后找到出错处后,仍然束手无策,一狠心,再也不copy图片了,而是提取出各个图形节点的位置信息,自己用GDI一个一个画出来,同时带来很严重的失真现象。自己画的线条没有抗锯齿,没能好好计划节点内的文字大小和位置,没能按照连接线的原始图样进行绘制,不过总算也勉强能蒙混过关。
  第三个问题是,发现解析所有图形节点时,发现多了一两条不可见的line,但是同样一个文件拿到我的机器上,通过Excel 2007的接口解析,却没有这两条line,瀑布汗!所以图形在我的机器上显示的好好的,到了别人的机器上就多出一个虚线矩形框和一个实线矩形框,只好额外写几句来特殊处理一下!
  我猜,第二个问题和第三个问题,会不会是由同一个原因引起的,会不会是由于2003和2007版本之间的一点不兼容性引起的,2003创建的文件被2007编辑过后,再拿到2003上去就会有点表现不正常?还是说本来就是2003就有问题了,只不过2007上有了改进?

2008-09-25

抛异常实现多级信息传递

  从没用过C++的异常,都是看到别的代码抛出异常来,我自己的代码里try...catch(...),甚至从来不知道catch里到底是要什么类型的。
  这次有这样一个需求,在一个比较深的调用层次的地方,不但要返回成功过失败,如果失败了,还希望能得到原因。其实这个需求之前就有了,但当时没有放在心上,觉得不做也不要紧,而且当时的想法是像Windows API那个,设置一个全局的值,即Error Code,任何操作之后都设置一下这个值,其他地方就可以直接获取到失败原因。当时想到这个方案时,心中也有点不舒服,这也是导致一直拖着不实现的一个原因。
  昨天做过功能的,直接就想到用C++异常来实现。今天先看了一眼msdn,然后就决定,这么简单的需求,就不需要自己写个异常类了,直接抛个字符串出来算了。字符串内容是从资源里取的,所以最后就直接throw一个CString出来了。效果还是不错的,不过有一点是需要特别注意的是,本来都已经通过返回值知道操作不成功,就可以跳出这个流程了,但有了异常,就需要在任何可能调用到这个路径的某处上层,进行try和catch,不然程序就直接down掉了!

2008-09-23

叫老大过去真是有效

  叫老大过去真是有效啊,哈哈,虽然加了一些额外的需求,却把另外一些需求的实现期限往后推了,这让我心里觉得无比舒坦,这才是正常的工作方式啊,哪有总是有突发的需求加进来冲击原本已经排得满满的进度。
  今天解决了两三个问题,花了几个小时总算实现把一个活动根据多个角色拆分成多个活动。结果下午4点的时候又被叫去讨论问题,这让我很头痛,那么多的讨论,纯粹是浪费时间,花在写代码上的时间就被不断缩减。而且一讨论就没完没了地纠缠一些毫无意义的问题和细节,自以为是地出些馊主意,还不能拒绝。

2008-09-22

从VS2008降到VS2005

  本来想用VS2008来写WIND的,但是这两天遇到几个问题,不得不降到VS2005来用。
  首先是装了Refactor!Pro,在VS2008编辑器变得迟缓无比,敲几下键盘,就会死半分钟,这是无论如何不能忍受的,于是在Refactor!Pro的配置项里改了一番,卡死的情况有所好转,但仍然处于不可用状态!而且在退出VS的时候,会写一个巨大的cache文件,工程中没有多少个文件,都会写入100多MB,估计随着代码量的增加,这个文件的体积也会不断飚升。
  其次是,我从PN中抠出来的Scintilla相关的代码,一添加到工程中后,VS2008就会updating intellisense,而且只updating到半途,VS就崩溃了,屡试不爽,无论是从命令行打开该工程,或者是从界面上打开该工程,都会updating直到崩溃!
  于是,我万般无奈下,尝试用VS2005。降级倒是很容易,直接用文本编辑器打开.sln和.vcproj文件,把里面最开头几行中的版本号改小就行了。再用VS2005打开工程,写几行代码,编译一把,似乎倒是没有在VS2008中的那些问题,只好先用VS2005来写了,生在中国可真幸福。
  这倒都只是IDE的问题,我猜如果只是直接从命令行来编译整个解决方案的话,应该不会有问题吧,而且升级也方便,只是改几个版本号。只是是否有这个必要,一定要用VS2008来编译。以后再说吧,本来最主要的也只是为了体验一下Refactor!Pro重构的快感。

公司电脑也加内存了

  一个月前申购的1GB内存条今天终于领到了,还顶着大太阳跑到K4地库去领来的,又等了快2个小时才让人装好,顺便还去领了根音频延长线来,不过已经最近没有机会用自己的电脑,所谓“兵马未动,粮草先行”啊,哈哈!现在应该跑VS要顺畅一些了吧,跟家里一样,把虚拟内存也去掉了。
  今天没干什么事,上午不知道怎么就混过去了,下午就是去领了下内存条、等人安装,接着又开了2个小时会,于是一天也就过去了,现在我真的很讨厌开会。不过现在也明白一个道理,以后开会一定要拉着老大一起去,他说话的份量确实比我足多了,我就在想要是还是我一个人的话,今天肯定还是会有不少情况下要跟人起争执的,而老大去了,很多时候他出面说话,别人都不怎么争吵,我那个汗啊!

2008-09-19

加了一天班

  今天去加班了,其实很不想去的,但是弱者是没有决定权的,连同自身的自由!
  终于搞定也几个催得最紧的问题,问题还在于逻辑跟界面绑定了,不能用CppUnit做单元测试,所以在这种纯逻辑的情况下进度慢了很多,因为测试验证相对比较麻烦。
  本来还想把开发环境从VS2003换成VS2005的,在冒烟服务器上也装好了VS2005,但最后还是没有继续下去,因为升级环境要做的事情还真是不少。首先,那些第三方库需要用VS2005重新编译,比如XTP、ACE、CppUnit;其次,VS2005之后引入的Side By Side,让我有点惧怕,谁知道会不会有什么不正常的;再次,担心有的第三方库在VS2005下直接使用会有问题,比如iconv,我是直接把iconv.lib拿来用了的;最后,我的机器上装的VS2005运行得好像有点点不正常,设置了编辑器字体背景颜色有时不能立即生效,如果设置了是浅绿色,则只有空白处才是浅绿色,有文字的地方还是白色的,而且连语法着色都没有了,前景全变黑色了!另外还有一点是,毕竟还是疲于奔命在项目的功能实现上,实在没有多余的心情去做那样的事啊!倒主要也是为了使用一下那个重构工具,唉。不过看来公司内也许像我这样边编码边重构的人还是不多的吧,至少我周围那几个人是不这样的。
  其实我也只会用那么两三种重构手法,最常用的便是提取方法,重命名方法名或变量名,将方法其实从.h文件移到.cpp文件。偶尔可能也会用用提取类等等手法,但这样的机会很少。所以还需要继续学习和实践啊。

2008-09-18

高兴得太早了

  又去受了一回气,要把google桌面搜索,google地图的功能都做进来了,真是痴人说梦话,还总是说没工作量,神经病!
  今天把格式化显示时乱码的问题解决了。其实不是MS SQL Server那里引起的,而是从Excel读取数据后转换成XML中间格式就出错了。如果是原始的干净数据,是没有问题的,只有当原来已经有同名的流程已经存在时,跟新的流程数据进行合并时,才会不正常,主要是没把连接线中记录的两端的图形节点uuid值改换回旧的,于是跟图形节点中的uuid值对应不上了,生成的dot文件中又是以uuid来作为节点标识的,当然出错了。
  另外又发现一个判断上下级关系的方法写得有问题,光是看代码就看出来了,果然他们实际试用的时候也是不正常的。但实际上这部分代码我都是纯粹凭想像写出来了,根本没经过什么测试。主要原因还在于这部分代码跟界面绑在一起了,都不好用CppUnit进行单元测试,所以逻辑正确性都不能保证了,看来抽时间还是得把这部分重构一遍,不要跟界面绑定了!
  今天又偶然看到一个可以Visual Studio 2005和2008下使用的重构Refactor!™ Pro for Visual Studio,在公司里找到一个似乎是免费版的,装了后在VS2005上看了看效果,从界面上看很酷啊,哈哈,不过公司里只用VS2003,真是遗憾啊,只能继续用VAX里带的那点重构功能了,尽管大部分情况下也勉强够用了!

2008-09-17

快到头了

  今天狠了狠心,直接又加了一张表,把原来用XML表示的组织结构信息存储到数据库中去了,原先过高地估计了难度,其实是心里有抵制情绪,心理暗示这用二维的关系数据表来表示树型结构很不方便。其实不然,只要每一条记录里保存一个指向父节点的引用就可以了。
  于是最后的攻坚战接近尾声了。权限相关的问题基本上从编码角度讲,差不多完工了,就剩下及时刷新客户端的组织结构显示了。而另一个主要问题,格式化显示流程图的问题,就我现在的猜想,问题还是出在MS SQL Server的使用上,自我感觉其他各部分的实现还是经得起推敲的。
  自打从CodeProject上又重新找了一个自动更新版本号的插件后,工程的版本号终于又能跟着每次编译而自动增长了,到今天为止,都已经到1000多了,这样好过以前要手动修改资源,但似乎有点不太专业。就我理想中的应该是,每次CruiseControl进行自动构建时,帮忙自动增长版本号,而不是我一个本地构建时进行增长。现在只有我一个人修改代码还好说,如果多人协作,目前这种做法明显行不通。

2008-09-16

觉得自己很可怜

  觉得自己很可怜,唉,状态很差,生活、工作都很糟糕。今天去汇报工作进度,被领导认为这两周来没做什么事,郁闷!遇到个变态的领导,让人如此无语,用小妞的话来说,有过这样的经历后,以后觉得什么人都是挺好的了。
  今天又因为忘了std::map的自动排序功能,而花了不少时间去修正那些bug。我把句柄作为key,该句柄上的标题文字作为value,本来想这样的结构用std::map挺好的,结果整了好久才发现插入容器时的顺序跟容器内的节点顺序不一样,才猛然想起来,这个std::map会自动根据key的值排序一把,而我恰恰不需要这个特性,于是想起去年,做编辑模块的语法提示功能时的情景,用了std::vector<std::pair<HANDLE,CString> >的结构,有一点std::map的样子,但又保留进入容器的顺序。
  代码真的越写越乱了,现在连接口都是混乱的了。相似的方法名,容易产生歧义的参数列表,以及更多耦合的类划分。为了完成功能,我只好不管这些了。还有,我似乎也有点完美主义,上周讨论下来的结果,那个方案,我总觉得太土太不专业,总想用另外一种我自以为要好得多的方法来实现,但是脑海里另一个声音却是“先完成功能,不要管实现得好不好看”!
  在公司论坛里看到一个monaco字体,等宽的,发贴的人说是最好的编程字体。开始我还不以为然,看到另一个人解释说什么叫好的编程字体,一要等宽,二要容易辨别o和0,1和l,剩下的则是见仁见智,觉得挺有道理的,虽然贴图上的样子看起来并不好看,我还是下载下来试用一把,把VC2003里用了一年的FixedSys换掉了,感觉还是挺爽的,看来大概是用了太久了,审美疲劳了。

2008-09-15

Opera确实比较快

  这两天还是照平常一样,在网上看小说,因为看的都是盗链,看到后面的章节一般都是截图的。昨天偶然开了一个Opera 9.51,猛然发现在它这里图片出来的速度比Firefox里快多了,很明显的现象。不得不承认,Opera在这方面的努力真的很有成效。而Firefox对现在的我来说,最大的让人不满之处就是它速度实在慢了点。如果换作以为,我肯定还会再加一点内存占用过大,不过现在1.5GB物理内存使得我不再特别关注这个缺点了。不过速度慢这个缺点却是没有明显的可以弥补的办法。
  都说Chrome的V8引擎已经作了极速优化,但是总的看来chrome还是个半成品,我已经太过习惯于添加了各种扩展的Firefox了,所以Opera也还是没能正式作为我的主用浏览器。而我就只能希望Chrome的出现能刺激一下Firefox开发团队,好好优化一下代码,提高点效率。

2008-09-13

开始使用WTL进行界面开发

  有点受不了MFC那比较累赘的几个在超大dll,同是Windows平台下做GUI开发,我只好选择了WTL。其实我已经比较习惯MFC那套东西,并没有发现多少网上说的种种使用MFC的不爽,相反我觉得还是挺安逸的,甚至对于使用了四五年VCL的我来说,MFC也没多少不方便的,虽然相对于VCL来说,MFC根本算不上可视化,但我也不清楚为什么自己仍然能这么乐于退回使用这种原始的framework呢!现在唯一让我觉得不爽的竟然是它要拖几个dll文件,也好,刚好学习一下WTL。对于目前我的状态来说,最大的困难是可参考的资料过少,市面上还没发现哪本图书是讲怎么使用WTL的,唯一的一份教程则是CodeProject上那流传甚广多少年前的那几篇文章。
  之前也用过WTL写过一个对话框程序。还有一个输入法辅助程序,本来期望是用它来做皮肤生成器的,结果和众多其他我写的程序一样,只是开了个头,然后就丢下了。如今要写一个比较大的程序,我自己也估计不好规模会有多少,猜一下大概C++代码行会过万吧,另外我希望大部分逻辑都是使用外部脚本扩展来完成。
  虽然几乎一点经验都没有,但还好有现成的代码可以参考,特别巧的是,我那程序中也需要一个代码编辑功能,本来就想好是用Scintilla的,但是我不懂如果在WTL中使用这种自定义的窗口,刚好就可以抄袭那些代码了,哈哈!
  编辑器能正常显示出来了,接下来要把TabbingFramework和DockingFramework加进去,之后再考虑其他问题!

2008-09-10

强大无敌的开源软件

  今天偶然看到一篇blog,讲述了chrome用到的各种开源代码库,至少有25种之多,让我不禁感叹,开源真是个好东西啊,真是软件界的共产主义啊。我内心是很认同这种做法的,觉得理所当然,而且自己平常也有这么做的倾向,只不过限于自己视野和认知,很多时候并不知道有合适的方案可供选择使用。
  以后要多多了解这方面的内容并在现实中加以应用啊!

2008-09-09

格式化显示流程图完成

  经过最近几天的努力,终于基本实现了通过dot的帮助,格式化显示流程图的功能。还记得当天晚上因为发现dot的功能,兴奋地睡不着觉。前天完成了把XML格式的数据转换成dot文件,再用dot生成PNG和SVG功能,昨天又换回GDI+,把PNG图片显示出来,今天则是把SVG自行解析了一把。dot生成的SVG文件确实是用UTF-8保存的,但是一开始发现用MSXML死活加载不上,后来慢慢定位发现是最开头位置有一句DOCTYPE,把这句删了就能好好地加载了。我估计是我没用好MSXML,不然也太扯了吧。不过这里我也懒得去追究了,直接处理了一把文本,把那句删掉了。然后装入,果然所有需要的信息都解析出来了。中途还遇到个小麻烦,发现识别鼠标位置总是有时行有时不行,还单步跟踪了好久,后来一狠心先把所有节点的坐标打印出来,再对应点击的坐标来看,到底是实现逻辑还是哪里有问题。发现原来就是一个单位转换的错误,一时疏忽了,SVG里都是用磅表示的,而这里我要的是像素,乘上这个比值就可以了。
  离最后期限发布还剩下的一个大问题是权限。权限系统当时考虑地太过简单了,不过也归结于当时的需求或者设计都没有想到现在会变得这么复杂。当时确实只想到了某个组织下属某些组织或个人,而根本没考虑某个人会需要作些特别的操作。现在的一大问题是,某个人可能同时分属于几个不同的组织,另一大问题是某个人需要有一种角色,管理员角色,这样可以拥有一些特殊操作的能力,还有一大问题是,在客户端对组织结构及角色进行修改后,该修改要让所有客户端知道。现在的做法很明显很难适应这些需求了,因为我把组织结构保存在一个配置文件中,而该配置文件是放在各个客户端中的,所以修改只在本地进行,不影响其他客户端。没头绪啊!
  下午的时候,算是阶段成果汇报,中途我溜了出来透透气。老大说我做这个程序,很有些想法。让我不禁有点得意,同时也特别悲哀,原来我这么容易满足,只是别人这么一句普普通通都算不上夸奖的话,就让我觉得高兴了。

2008-09-07

exchndl.dll提取出来了

  昨天好不容易咬咬牙,把捕获未处理异常的功能提取出来封装成一个dll了。这是一个很简单的功能,所有的代码都是现成的,我只不过是把它从源代码复用的方式改成了二进制复用。当时公司里的同事说我这源代码复用的方式太落后,想叫我改成一个COM组件。而我又恰恰对COM很反感,所以一直都没动手。这次在一体化平台中涉及到2个exe程序,而只在一个主程序中用到了这个功能,有一天收到一个报告,另一个exe程序也会崩溃了,所以就有了要分离出来的想法。
  提取成dll我当然不会用COM来封装,而是学MinGW中的exchndl.dll的方式,移植的主要工作是把MFC中的CString类都替换掉。这花了不多的时间,然后放在WallpaperHelper中进行测试。
  除了记录了系统简要信息和调用栈信息,我还另外加了几项也许有点用的内容,包括当前系统中所有的进程、环境变量、当前进程所有的模块、所有线程信息。本来还想加些其他内容的,比如当前系统的服务信息、系统设备驱动程序信息、当前进程的所有句柄、所有文件映射、所有窗口等等,不过想到暂时这些信息也不是很重要,而且这样会让生成崩溃报告的时间更长,先还是放一边吧。
  最近我想我真的是工作压力大了点,昨天下午睡午觉,梦到了很多乱七八糟的事情。最让我觉得气愤的是,居然梦到有个老女人,对我的工作指手划脚的,然后旁边两个同事也不知道在干吗,跟现实中的很相似。真是日有所思,夜有所梦,愤慨啊,竟然我的梦都被人这样强加干涉了!

2008-09-05

使用iconv转换字符编码

  昨天从网上查到,要让dot支持中文,必须得把dot文件保存成UTF-8编码,可是我用C Runtime、MFC CFile、C++ iostream都只会保存成ASCII的,于是不可避免地要再多一道工序把字符编码转换一下。
  从一开始我就想到了iconv。先拿来它的可执行文件,在控制台上尝试了几次,原来是要把中文的设置为gbk才行,如果是ascii或者gb_2312-80都是不行的。知道iconv确实是可以将编码转换后,就放心大胆地在程序中使用iconv库了。从公司归档库中找得到的只有1.9版的,但好在.h文件和.lib文件都有,看了一下头文件中的声明,猜猜也就是先iconv_open,然后iconv、最后iconv_close共三步操作而已。于是先把文件都读出来,然后iconv。可是死活不能把转换后的内容存放到目的缓冲区中,而源缓冲区,以及返回值,还是源数据长度和目的数据长度却都是对的,实在不得要领。这样郁闷了好久,还是不得其法,于是准备直接用iconv.exe来转换算了。
  iconv.exe转换时会把转换后的结果直接在控制台输出,可以通过管道重定向到文件中,可是在程序中要得到这个结果就遇到了些挫折。首先想到的当然是CreateProcess,然后通过管道捕获输出,可是发现这新生成的进程一直不结束,我估计是哪个参数没设对,这个API的参数也太多了点,昏厥!放弃,试了试C runtime函数system,倒是可以直接像在控制台上写一个有重定向的命令行,可是在执行时,会出来两个黑的控制台窗口,这用户体验也太差了!再放弃,看了看ShellExecute这个API,但好像不能重定向。
  还是转回来用iconv库吧!最后还是从网上找了一段代码,先要iconv传入几个空指针的调用,再一行一行地从源文件中读出内容,再一行一行地调用iconv,最后一行一行地写入目的文件,这样居然就行了,大汗淋漓!

2008-09-04

终于借到《Lex与Yacc》了

  几个月前,就想从公司图书馆去借本《Lex与Yacc》了,可是从在线服务中可以查到确实有一本没有借出去,但到了图书馆就是找不到那本书放在什么地方了,图书馆的人说他们也没有办法找到,因为书要么就是照着编号放在书架上的,如果在指定的书架上没有,那就没办法了。我还为此去了几次图书馆,希望碰碰运气万一某一天他们整理的时候能发现那本没有找到的书,但是一次一次都失望而归。也想过自己买一本,但逛过深圳的几处大型书城,都没有找到过,从网上倒是能看到介绍,可是都是断货了,太郁闷了!
  昨天觉得该去还那本《Windows技术内幕》了,虽然借了三个月,但没看几页。到图书馆一看,惊喜地发现有一本《Lex与Yacc》静静地躺在柜台面上,看来是刚刚有人还回来的,连忙抢到手中。
  实在觉得这词法分析和语法分析在处理模式化文本时太有用了。说起来虽然现在在做那个劳什子一体化平台,可是我心里却一直想回去完善编辑器,简直有种生不逢时,壮志未酬的感觉。本来同事是有一种语法解析组件的,大概浏览过那代码,其实是从ruby源代码里抠出来,在某一阶段直接把语法分析树dump出来。不过不知道为什么在源代码超过8000行时,分析出来的行号总是过绕接,从头开始。我也没仔细定位过这个问题到底是哪里出了错,主要是那代码全是别人写的,而且用了一些我个人极不喜欢的处理方式,我就懒得再去查错和修正了。我宁可自己再写一个解析器,因为我知道用lex和yacc可以做到。当时简单地看过ruby的源代码,发现它的词法分析器并不是用lex生成的,并且里里有一段代码是用gperf生成的,于是以为gperf也是一种词法分析器生成器,后来自己用了gperf才明白过来,原来ruby的词法分析器是手写的,其中gperf生成的那段代码只是为了识别出其中的保留字而已。而语法分析器确实像是用yacc生成的,不过由于ruby的语法太过于魔幻,所以语法分析器似乎复杂得超出我的想像。如果我回头再去做编辑器,这个语法解析器势在必行,不关是为了解析出语法树显示出来,另外还有些用途。其中之一是,其中有一个另外的需求是将表格化的描述与脚本来回转换,如果没有可靠的语法解析器支持,这个需求要实现就实在太过困难了点。另外还有个需求,是前两天才提出来的,说是要能跳转到方法定义处,于是当然要知道方法定义的位置,而这位置当然需要事先准备好。本来还以为rdoc从源代码中提取文件时可以顺便提取出来,后来同事一说,yaml中并没有保留文件名和行号,所以还得想办法提出来。我一想这个就太不可靠了点,万一某些方法就是没有注释文档呢。所以一定要另外有个模块来提取方法定义,我当时想到了ctags。今天试了试,发现用ctags还是有些缺憾,它只能提取出方法名称,以及匹配该名称的正则表达式,而并没有行号。另外,看了看ctags的源代码,发现另外更严重的问题,ruby并没有说定义方法时def关键字和方法名一定要在同一行中,如果是不同行中,ctags就不行了,所以还是得实实在在的语法解析器出马啊!
  当然,像ruby这种比较复杂的语法解析,我不需求全部自己从头开始写起,可以抄袭一部分它的代码,至少词法分析器大部分可以直接使用,而那语法解析里把BNF留下,把动作换掉, 这样虽然还是要读懂那部分代码,但总比全部自己来轻松多了,而且也可靠得多。
  得稍微系统点地学习一下lex与yacc了。

迁户口,迁档案之二

  今天去关内给小丫头迁档案和户口,早上睡到8点多,很不情愿地起床,不过也比平时上班时晚了一个多小时了,昨晚睡得也不晚啊,怎么会那么困呢。洗漱完毕出门,已经过了8点半了,等328路,结果一直等到9点才勉强挤上一辆。
  到了那公司,还不到10点,这出乎我原来的预料,心里顿时放松了一点。那么一个小公司,里面有个女人招呼我过去,我拿出迁户申请和商调函。被告知那些个人资料是要填好的,于是又打电话问小丫头那些东西怎么填。接着又被告知要交档案保管费,每月20元,从2007年2月交到2008年9月,还好不是很多,但我还是忘了拿钱上去,跑到楼下的招行ATM机上取了钱上去,结果那儿的财务部说他们不收现金的,但是大概看在我已经拿了几张红纸片的份上,乱糟糟地不知道从哪里找出一本开收据的本。最先招呼我的女人把档案都装入一个档案袋,贴上纸,盖了十几下章,然后找出小丫头的户口卡交给我,第一站的任务就基本完成了。
  随后是要去高新派出所办迁入户口,因为不知道坐什么车,所以一下楼就打了个的。也不知道是不是绕路了,比我想像的要久。而且想不到那派出所在那么一个偏僻的地方,不过好在一进门就看到办理的地方,取号排队,开始还取错号了,大概一直排了半个小时的样子吧,才轮到我,那办理的大姐一看就说出我们公司的名字,看来我们公司在那儿的业务很多啊。没几分钟就办完了,时间都耗在坐车和排队上了。
  出了派出所,看到路对面就是一个公交车始发站,看来只有转车了。这车也是绕路的,绕了好久,到了市民中心,本来想坐个391回公司的,结果等了10几分钟也没等到,失去了耐心,决定再次转车,先坐到梅林关,再爬上一个小巴,1点半差3分的时候终于赶回公司刷卡,这样就只需要报上午半天的假了。
  坐下吃了块巧克力,因为早饭和中饭都没吃,饿啊!然后给小妞打电话,问她有没有吃的,她说有小面包。于是我先跑到人事服务中心,把户口卡和档案交回去,结果那管档案的mm说还缺转正定级表,我郁闷,这党员还真麻烦啊!指不准还得跑一趟关内,累啊,要是自己有车就好了!

2008-09-03

Google终于也出浏览器了

  今天在公司就发现有人传了个chrome的完整安装包上来,都没有安装过程,直接双击,过n秒钟的后,窗口就弹出来了,很简洁,简洁得让人感觉像是个玩具。只玩了两下,就没了新鲜感,就凭它现在的状态,它是吸引不了我的,我还是继续用回Firefox,那些使用习惯设置,插件,都已经成为我暂时离不开Firefox的理由。
  回家打开Google Reader一看,n多blog和discussion在描述chrome,顺便让我有那么一点点惊喜地发现这还能直接从svn里下到源代码!不过就像其他的各种开源源代码一样,不到真的要用时,我是决计不会去看这些源代码的,尽管我确实已经下了不少源代码了,包括Code::Blocks、CodeLite、notepad++等等,都是因为在某些时刻突然觉得这些源代码有一定的参考价值,而且update这些源代码也成为我每次打开电脑后几乎必做的一件事。但实际上,我却还是没有真正能从这些源代码中获取过多少有用有价值的东西,这不怪这些源代码,而要怪我自己。公司里有个牛人,看部门似乎是个做硬件的,却好像看过n多开源项目的源代码,包括那些BSD系统、Linux系统的,实在佩服这种人的毅力和恒心。
  Google出浏览器了,对最终用户来说,也许是件好事,这样激烈的市场竞争,能促进产品进步。当然可能就苦了Web开发者,不同的浏览器之间必定有些不兼容的情况存在,而Web开发者则必然需要为了兼容几大主流浏览器而煞费苦心。
  对于我来说,暂时影响不大,继续留守Firefox 3观望中。

2008-08-30

唯心主义的领导

  此乃人生之大不幸,竟然让我遇到了。什么事情到了他嘴上都是很简单的,任何问题他都可以说得睁着眼睛理直气壮地说没有难度,还会装着问你一下有没有困难,如果你说有困难,他就会很不屑地说,这有什么难的,不是很简单吗!有着这样唯心主义的领导,事情做好了,是理所当然的,事情做不好,简直是罪大恶极。
  也许这就是所谓的驭人之术,可以被手下看不惯,甚至觉得愤怒,想法可以荒唐不切实际,但最终在一定程度上某些方面确实有所输出。
  工作以来,从来没有这么气愤过,最多是有过深深的失望和无奈,但这次真的是愤慨。
  我已经没有心情再跟他争辩了,反正无论怎么争辩都是做无用功。有句很流行的话,把生活比作被强奸,我想这句话套用在工作上也是恰如其分的。无论做什么,我同样是拿着这点微薄的工资,没了我,地球依然会转。
  最近倒是隐隐有种感觉,似乎自己写的代码,结构组织方面比以前要做得好一些了。但在那种大框架,或小技巧方面,还是没有长进。一方面,半路出家,没有经过系统的学习培训;另一方面,缺少大型软件架构设计的经验;还有,编写代码行数确实还不多。
  在技术方面的追求,未来的三到五年还是不能放下的,毕竟我年纪也并不大。只是除此之外,也要多关注学习一下其他诸如管理、营销之类的知识,这些方面跟技术才能相辅相成吧。

2008-08-29

被人pk了

  无限佩服cracker们,25日发布的Tiburon,今天偶然发现网上已经有对应的xx出来了,对于这种叫好不叫座的产品,实在是致命的打击。
  今天又被叫去汇报,气死我了,我的脾气现在也实在不是很好,可是又不能把人家怎么着。啥也不懂,却要装做啥都懂,偏偏又能以权压人。这样的社会真是太可恨了,这样的世界实在太没趣了。于是下午几乎就没什么心情干活了,随便整了一下,反正代码check in后CruiseControl会自动编译打包的,所以就出去闲逛,跟人聊天吹牛。一直到快下班的时候,才发了个邮件说可以下载最新的安装包了。
  倒是看到同事在用一个叫EA的东西,全称是Enterprise Architect,简单说来是个像Rational Rose一样的东东,用于画画类图、序列图,然后可以通过简单的配置直接生成代码框架。我问了下同事,跟Rose比,有什么区别,同事说EA功能多,支持全流程,而且体积小,才几十MB。然后我就顺便跟他扯起来,说我们也可以做个这样的东西,他就说这是需要一个公司来做的。于是我就举出StarUML的例子来说明,三五个人也是可能做出来这种东东的。
  想起来,做为一个开发工具供应商,比如原来的Borland,除了提供IDE,即开发阶段的支持,另外对设计阶段的支持也是很重要的,特别是现在各种软件工程方法论的越来越盛行,所有开发者,对建模的重视程度也是越来越高,现在好用的,功能强劲的,确实基本都是价格昂贵的企业开发,像StarUML这样的已经是免费软件中最好的一类了,其他廉价或免费的质量能达到这种程度的,确实也很难找到了。这类软件的利润应该很高,但估计对售后培训等的需求也比较高。

2008-08-28

一天Workshop

  开了一天workshop,上下午各3.5个小时,谈及了部门目前存在的问题,以后的发展方向,规划等等在我看来似乎离得不近的东西。不过通过今天一天的workshop,总算让我的心态又调整了一点,本来是很不爽现在做的事的,结果我又被说服了,我觉得现在做的事还是比较有趣的,有价值的,至少可以让自己的技术得到提升。话说昨天小妞的老公还叫我不要太沉迷技术,可是我发现我其他的什么谋生能力都没有,实在是不得已而为之啊!
  昨天晚上居然兴奋得睡不着,试用过dot的能力后,越来越觉得格式化显示流程图的功能可以用dot来做,可以让它导出成png(或jpeg或gif)之类常见的图片格式,再导出成svg这种文本格式,通过解析svg来获取到各个图形节点的坐标位置,通过png来进行实际的显示。只不过昨晚简单看了看dot生成的svg,里面用的尺度单位又是那该死的“磅(即pt)”,大概我们目前最常用的分辨率下是1磅≈0.75像素,这样就又多了一次浮点乘法运算。还是得去图书馆找一本讲svg格式的书来看看,主要了解一下它怎么描述坐标系统。
  自从基本用ACE搞定了文件传输功能后,我又开始在心里有点蠢蠢欲动了,在这个工具里面加入Kademlia会怎么样呢,当然现在这个工具的用户还太少太少,看Kademlia的那些参数定义和设置应该是依赖于一定量的用户数的基础上吧,可能是几十万,也可能是几百万,那样才能发挥出分布式hash的效用。看我做的这个工具,只有几个人用,最多也就是几十个人吧,也许通过一些政治手段,可能达到几百人,但还是太少了,根本不能体现这Kad的作用,不过我就是想把这工具做为一个试验田,既然干得不开心,就努力为自己争取些其他方面的收获嘛。

2008-08-27

今天进展不错

  今天终于把文件传输部分改得几乎能正常传输完整个文件了,试了2KB、84KB、2MB三个文件,都没问题,其中2MB的是个Rar文件,能正常解压缩,说明应该是没有一个字节是错的了,而且速度在局域网内也基本在一个可接受的范围内。
  昨天传文件的时候,还一直会丢失些数据,反正发送端是应该没什么错的,老老实实把整个文件的内容都读出来,然后一次1KB左右发出来,可是接收端总是收到不在期望内的数据,或者就是收到几个数据包后,就再收不到什么数据了。当时我还怀疑是不是因为发送得太快,但又觉得加个延时进去明显不太合理;又怀疑是不是收到数据包的顺序可能跟发送的顺序不一致,所以还试了试给数据包加入序号,但这个举措明显解决不了前面提到的两个问题。昨天可谓是毫无头绪,连猜带蒙地整了一天,结果就是证明了那些想法都是不可行的。
  今天也算是灵机一动,想到了曾经看到过http下载文件,多线程下载时,就是可以指定下载文件的偏移量,于是我想,我也这样做,而且每次只发送一小点,接收端收到后再请求下载另外一部分,这样就直到把整个文件下载完,于是,果然可以完整地传输完整个文件了,虽然代码写得很dirty。现在想起来,在这样的策略下,要让这个操作支持断点续传和多线程下载也不是很麻烦的事了。
  搞定了文件传输问题后,感觉心情一下舒畅了很多,换了另外一个工具的维护工作,要增加一个新功能,当时我估摸着可能要花些时间,于是跟那同事说要2天工作量。也不知道是不是心情好的缘故,不到3个小时就几乎搞定了,同样代码写得很dirty,而且这个工具最初代码是另外一个已经离职的人写的,他的代码风格跟我的路数不一样,我在这样的基础上进行维护,代码看着要多别扭就有多别扭。不过这只是个小工具,功能很弱很少,所以这些都不用太关注,要求实现的功能做了就行了。
  之后又看了一会儿dot的user guide,开始还以为用它来画流程图很符合格式化后流程图的显示的形式,只要用一组比较清晰简洁的语法,直接可以生成一张图片,但是后来发现我这工具中对流程图的可控性要求比较高,不但要求显示,而且要求一定程度的编辑的能力,即需要能随时方便地知道某个坐标下是哪个节点,或者某个指定的节点在哪个位置,但是今天看了dot的只是直接输出成某种图片的格式,可能比较复杂。现在想想还是有可能知道是,比如SVG、PS之类的格式dot也是直接支持输出的,这类格式的文件其实是文本内容,应该保存有这类节点标识和位置信息的映射关系的,只不过再要解析它们,复杂性如何就不得而知了。

2008-08-26

自省

  中午睡过午觉走下楼,在拐角的地方看到一个男的,直觉得好眼熟,想了一会儿终于想起来,不就是这些天在食堂吃早饭时经常看到的那个男的吗,当时还心想这男的长相也实在不咋的了点。可是这次匆匆路过的一瞥,却让我自惭形秽了起来,我缺少成熟的气质,而且缺乏自信。所以我一直都有意无意地走着邋遢路线,装着吊儿郎当的样子,抱守着那残存的点点自尊心,却是没来由的自负。
  为什么没有自信,说到底还不是跟自身拥有的客观条件有关系。真正拥有强大自信的人,实际上要么确实是自身拥有超乎常人的才能,或者是有其他强势的物质依靠,而这些也正是我缺少的。

2008-08-25

从今天开始重新魔王

  记得曾经有一段时间,我把自己的昵称或ID说明栏上改成“从今天开始魔王”,这是一部日本动画片的名字,当时觉得这个标题很适合自己的处境或心境或志向的,也不是说魔王要干坏事,而是要像入魔一样地写程序。当时确实有那么一小段时间,读书的时候也好,工作了以后也好,有点空闲的时间就去写代码,或者上网看编程相关的内容,或者买书看,或者就泡那些编程论坛BBS。结果后来还是不了了之,尘世的诱惑实在太大,哈哈!
  今天心血来潮打开久违的VS2008,打开最近创建的一个工程,看了一下SVN里的提交记录,最近一次是22天前,而想想22天前的那次提交,其实也不是自己写的代码,只不过是把别的地方的一些代码复制过来而已。
  这些代码在那样的需求下,工作得很好,可是我需要它能再更进一步。昨天重装了VS2003、VS2005和VS2008,但发现2008那个RC1107错误依然存在,于是外事不决问google,发现一篇文章,果然不止我一个人有这问题,很快解决了,看了看我的配置项,最后一个include的目录尾部的字符赫然是个反斜杠,换个末尾字符不是反斜杠的放在最后,试了试OK了,哈哈,仰天长啸!
  另外又看了看CppNPv2,里面关于ACE_Message_Queue的说明,原来这个消息队列有一种功能,可以限制存放在里面的最大的数据量,默认为16K,回想白天在公司里,因为我给每条记录是1024个字节,每次16条记录不就刚好是16K嘛,我汗颜!
  用VS2008写代码特别安逸啊,本身就已经做得挺不错的了,而且加上VAX的辅助,现在我已经真的再也离不开它的自动完成和重构功能了!也不知道是VC2008的编译器确实改进了,还是我的机器的内存足够大(1.5GB,用XP一般情况下根本用不完),反正觉得它编译速度好快啊!想想在公司里那个P4 2.6G,因为搭配了512MB的内存,用VC2003编译个东西,那个老牛拖破车啊,不过我已经申请加1GB内存了。
  还有,就是前段时间买的那个键盘打字果然很舒服啊,仿笔记本的超薄型,现在天气热,再放在本本上要烫死了,打着打着就会不自觉地加重手势,感觉超爽,哈哈!
  从今天开始重新魔王!

调了一天ACE

  上周没调完,今天接着调,调了一天,勉强可以实现点对点文件传输了,但还剩下不少问题,比如我会在服务器端先读入整个文件,如果该文件很大很大,岂不是很占内存,如果超过了物理内存的容量,要动用虚拟内存,岂不是效率又会降低不少!这只是众多问题中的一个,还有其他各种问题,只能走一步算一步了,关键是先把容错性做好,不要动不动就崩溃。
  现在的情况是一个程序里,又当服务器端,又当客户端,两边我都是用reactor实现的,其实我对其中的工作原理一窍不通,只不过抓来几个例子,照着书上写的拼凑起来,好在调试工具还算好用,加上一点点的抽丝剥茧,总算理出点头绪,也得到些经验教训。
  首先,不要为了图省事而使用那个全局单件reactor对象,我开始的时候服务器和客户端共用这个对象,后来觉得不妥,把客户端的改成一个客户端连接临时生成一个reactor,使用调试工具发现勉强可以用了,服务器端却不会自动调用handle_output,后来把服务器端的那个reactor也换成自己生成的,竟然也可以了,也许是我没用对,但反正现在它几乎能运行起来了。
  其次,无论reactor是用在服务器端还是客户端,都要run_reactor_event_loop一把,这个调用一直不返回,大概直到end_event_loop之后才返回吧,所以要另开一个线程来调用,除非是不想干其他事情了。这样,还可以看到一点,就是在适当的时机,要调用这个结束的方法。这和boost.asio的做法很相像。
  再次,发现ACE_Message_Queue里居然只能存入16个最初压入的记录,后面再压入的全都被丢掉了,也不知道是不是有方法可以扩充到更多个数的,或者我觉得STL里的deque也不错,可以在头尾任意一端进行存取,不过ACE_Message_Queue似乎可以通过模板参数指定线程同步等选项,deque大概就完全要靠程序员自己把握了。
  最后,要调socket程序,拥有和掌握好用的调试工具实在很重要,Wireshark这个开源的东东实在不错,只不过公司里居然装WinPCap是受限的,不过那个检查工具是防君子不防小人,好在可以通过改注册表中的卸载项来骗过它。另外从公司网上找到几个可以模拟TCP/UDP的Server/Client的小程序,很容易用,有这样的工具,就可以先调试其中的服务器端或客户端,等这样单独的调得差不多了,就可以进行联调。不然同时联调的话,出了错还不知道到底是哪边的问题。

2008-08-24

奥运会闭幕了

  时间过得真快,我们国家为了承办奥运会,准备了那么多年,从第一次申办失败,到后来申办成功,再到各项准备承办,两三年前就开始倒计时,还有几百天开幕。而8月8日开幕式,感觉就是昨天一样,当时还忿忿不平地说开幕式不好看。今天就是闭幕式了,还是老样子,除了排场足够大以外,其他的我确实找不出好的来了,从色彩,到音效,或者意境,反正没有一项是我喜欢的,也不知道花费了多少人力物力,当年各种专家预测的,奥运会期间给中国经济带来的巨大好处,不知道是否都应验了?
  作为东道主,中国确实历史性得获得了金牌榜第一的骄人战绩,但又一想,金牌多带来的又是多少好处呢?看到一些报道说,有些国家,比如美国、加拿大,那里的很多运动员都是业余的,平时都是有各自的工作,政府并不给运动员们发放多少金钱上的补助,相比之下我们国家的运动员呢?出了成绩,还说得过去一点,但成绩很差的那些呢,比如男足,那些钱都是从哪里来的,最后又花到哪里去了,是不是浪费了?我们国家作为发展中国家,却在这些方面作为远不如那些发达国家英明和有远见。
  算了,也是一家之抱怨,没意思啊!

VS出问题了

  发现机器上装的几个VS出问题了。6.0不说,因为压根没想过要用它。2003出问题似乎是最早的,大概是因为最早用得最多,就出问题也早,发现问题也早,现象是时不时弹出个消息框说什么GDIPLUS怎么出错了,而且一弹就会连续地弹好几次,让人受不了。2005本来还没怎么发现问题的,因为不常用,要用也是2003或2008,当时只是发现它的菜单怎么变中英文夹杂了,也没怎么在意,反正看得懂,最近一段时间想用它来创建个工程,发现这个wizard不能用了,估计也是因为这本地化引起的,老是去不存在的目录下查找那些html文件!最后说2008,2008是今年开始用的,春节回家的时候用它来写WallpaperHelper,当时安装的时候也费了些力气,新建个MFC工程来编译,发现还缺几个.exe文件,抱着侥幸心理从2005那里照着文件名拷贝过来,发现勉强也能用,结果今年上半年堕落颓废了,看小说去了,几乎写过代码,现在发现2008里的资源编辑器不能用了,资源视图里都打不开资源,只是报个RC多少号的错,我也懒得再去查这是什么错了,反正这个资源文件是肯定没错的,郁闷死!
  没耐心继续跟它们耗了,直接卸载,重装!

2008-08-23

想写个文档收集管理工具

  昨晚在整理硬盘上的电子书,顺便想到我零星收集的n多资料,一般就是一张网页,或者一个txt文件,里面可能是一篇文章,或者一小段代码,却很可能讲述了一个技术原理或一个小小的编程技巧,我没有计算过总共有多少个这样的文件,估摸着应该有几万个吧,这些只是平时上网,看到觉得有用才收藏下来的,不像那些电子书,很大一部分是去年从一个同事那里直接拿硬盘对拷过来,有些根本不是我关心的领域的,比如无线通信之类的。
  这些文档散落在硬盘上,虽然我也大体上划分了一些分类,比如algorithme、crack等等,但当真要找某个比较细节的内容时,很可能要花很多时间,还不一定能找到。于是我就想,要是有一个适用于编程资料收集管理的工具就好了。我是懒得再去网上找了,先不说能不能找到真的完全符合我的要求的软件,即使有(这个可能性很小很小啊),也不一定是免费的。以前看过几个文档收集管理工具,要么是纯粹的通用工具,缺少对编程资料的倾向性适配,要么就是纯粹收集源代码的,又缺少对文字内容的支持。所以又回到原来我说过的一句话上来,最好用的软件是自己写的。
  以前用BCB写过一个电子书管理的工具,花了些时间,但实际上并不好用,界面也其丑无比,太业余了,这是促使我后来义无反顾地投入VC阵营的重要原因之一,在像XTP、BCG之类的界面库帮助下,用MFC做界面其实并不比VCL麻烦,而且以我个人的经验看来,在同等工作量投入的情况下,反而更容易做出比较专业的界面来。又跑题了,那个电子书管理程序的功能太弱,虽然当时也想过不光要能管理电子书,还要能管理普通的文本资料,但后来由于对界面的极度不满意,直到完全失去了兴趣和信心,就放弃了。
  现在想用MFC+XTP写一个,数据库就用SQLite好了,不光能管理文本资料,也能管理电子书,这是我比较希望的一种方式。管理文本资料时,需要特别关注,可能有两种不同类型的内容,一类是文字描述,一类是源代码,所以要同时有两个视图来表达一份资料的内容。资料的分类管理是必须的,而且更需要的是一种比较方便的搜索功能,不但要能搜索标题,还要能搜索内容。再有就是文本资料和电子书的管理要融合在一起,看起来没有特别明显的分界,但又留有余地可以完全分离开来。
  这个工具不是通用目的的,是为程序员专用的,所以用户范围可能少了点,但这也算是围绕着我的整体规划目标了,developing for developers!

2008-08-22

相比之下SVN比VSS更好用

  最近这段时间,SVN和VSS混用,有些工程是放在SVN里的,有些是放在VSS里的,但总的说来,感觉SVN更好用些,也许VSS 2005已经提供了各种现代化的特性,但直到现在,我还只是以VSS 6.0的眼光看待。
  SVN在编辑前不需要check out,这点我就很喜欢,在VS 2005中,可以设置得让IDE自动check out出来,但离开了IDE,还是得自己去做这点操作。现在我用的VS 2003,就会自行弹出个check out确认对话框,这让用过SVN的人觉得很不耐烦。尤其是在某些情况下一个操作会要求先后对多个文件进行编辑,这时VS 2003就会不厌其烦地一次又一次地提醒要check out每一个文件,比如要编辑资源,就会要改.rc文件和resource .h文件,如果是添加一个新的类,就会要求编辑.h和.cpp文件等等。
  但是SVN也有很让人头痛的问题,比如它完全依靠文件夹下的.svn文件夹工作,而且似乎很容易出错,出错了还不容易修复,VSS就很少这类问题。还有就是似乎代码仓库也有类似的毛病,容易出错,出错也也不容易修复。
  今天得到一个经验,如果一次性要添加很多文件夹和文件到仓库中,最好不要用add和commit操作,而是用import。前者需要2步人为的操作,所以感觉要花费更多的时间。今天我就是需要添加4个文件,总共有130MB左右的数据量吧,n多个文件,用add还正常,commit时还会执行adding操作,然后是send content,到中途不知为何就阻塞在那里了,等了一会儿耐不住性子就x了窗口,到仓库里delete掉看到的几个文件夹,却有一个文件夹之后总是add不了了。后来改用import,就全加上去了,汗!
  但是如果是一点一点来的话,我更愿意接受SVN这种工作方式。

2008-08-21

迁户口,迁档案之一

  早上接到小丫头托人带来的身份证,马上打开ppt看了看各个步骤,还是不明所以,直接就跑去人事服务中心找人。等车等了10几分钟,开过了五六辆,全是满员的。先问开具迁档案时要用的《商调函》什么的,结果问我档案现在什么地方,我一听就愣了,当时我问小丫头时,她自己都不知道在什么地方。然后去开迁户口的申请,结果那mm说要证明,这也是情理之中的事,不过小丫头给我的那个ppt里留的两个联系人明显不对嘛!
  两边都办不成事,只好给小丫头打个电话先,让她马上发个邮件证明一下,又顺便扯皮了几句。开好迁户申请,打道回府,离回来快1个小时了,这办事效率也太低了点,瀑布汗~

2008-08-20

正式拿到驾照

  其实上周五的时候,晚上我在外面吃饭,手机没电了,回到家充上电,就发现江江发给我短信说驾照已经拿到了。反正我是懒得跑去F1那么远,就为了一个驾照,于是拖到今天,江江自己给我送过来了,不过相应的是我付出了几块德国巧克力的代价。宣宣还在那里告诉江江,说昨天她好求歹求了好久,我都不肯给她巧克力,哈哈。
  有了驾照,却没车,真是个头痛的事情啊!不知道半年后,假如有了车后,我还敢不敢开上路。

2008-08-15

内存泄漏

  今天偶然发现有时候会出现内存泄漏,于是照老样子打开那个编译开关,打印出所有内存分配的记录,但是却发现又不出现泄漏了,或者说可能是没有跟踪到。这样整了一个小时,毫无进展,只好放弃了,要多掌握几种比较可靠的内存泄漏定位方法才行啊!

2008-08-14

完全颓废

  一周一次的例会,没有什么新奇的内容,我猛然发现自己连原本仅存的那点激情和盼望都没有了,残念!
  下午帮一个同事定位内存泄漏的问题,倒是没有完全解决,只是指出了几处可能造成泄漏的代码,让他自己有空去调去吧。
  那天cm0说自己很迷茫,我想了想自己,我是有目标的,知道自己想要什么,却没有动力,完全颓废了,唉!

2008-08-13

比较轻松的一天

  今天倒没怎么投入到那个劳什子一体化平台中去,上午先是整了一下故障注入工具的PC端,只是加了个生成函数时的选项,最早是只能支持GNU编译器的,后来发现需要能支持Diab编译,只是在对话框上加了两个单选按钮,很简单,另外一个新需求更简单,只是改了下字符串。但也花了些时间,而且因为VSS不能访问了,于是索性把源代码都导入到SVN上去了,重新做了个安装包。
  下午先去了趟图书馆,还了两本即将到期的图书,随便逛了一圈,没发现什么想借的书,空手而回。然后还是看了一眼一体化平台中那个权限问题,一直我都对外强调这个权限问题很棘手,工作量很大,然而其实在前不久我已经完成了绝大部分的代码,虽然发现有工作不正常,但也正好应了我原本一直宣称的没做好的事实,今天看了看,好像只是因为从数据库中取记录时没有把文档密级字段封装好返回而已。接着又看了一下编辑器中自动格式化的一个问题,这自动格式化已经成了一个顽疾了,而且不时地爆出全文格式化和换行缩进行为不一致的问题,这让我感觉头痛不已。总觉得现在那套代码写得太混乱,根本没有清晰的思路,但是我现在却实在不想费心去搞那东西了,唉!
  今天是最近这段时间来感觉比较轻松的一天了,不是说工作量大小,而是说精神上的压力小了不少。

2008-08-12

很多崩溃问题

  今天发现很多崩溃问题,主要是因为前段时间确实作了大幅度的修改,连数据库表结构都做了改动,幸亏也是今天让人试用了一把,发现得早。但同时也似乎引入了一些很难找到原因或者即使找到原因也不容易找到好的解决方案的问题,这才是让人郁闷的。
  本来还想找来了个人一起做,结果是个新员工,还对C/C++、MFC并不熟,并不能立马就投入,反而要腾出时间来跟他解释原来的那些遗留代码是怎么回事,真是偷鸡不成啊!
  另外还有个挂在我名下进行维护的工具,今天又收到几条新的需求,结果发现前些天那个VSS服务器不能访问,现在那个工具的所有源代码和文档都在那个服务器上,都取不出来,暴汗!

2008-08-11

郁闷的格式化显示

  今天抓紧时间把那个格式化显示流程图的部分搞了一下,但是效果是很差的,这方面我一直都很弱,没有系统地学习过算法,更没有专业的图形算法知识。以前看过StarUML,可以格式化排版类图,现在要的就是像这样的效果,可我以为,这虽然可能可以做到,却是吃力不讨好的事。现在做的事情越来越偏离正轨,提出的新的需求总是搞混人和机器的能力,别人是扬长避短,而到了这里却总是安排些本不擅长的事情来做。
  总之很郁闷啊!

2008-08-09

看北京奥运会开幕式

  昨天下了班,跟两个cm0同学去喝粥,然后慢慢晃悠到百草园门口等车。到家的时候,奥运会开幕式已经开始了一小会儿了。
  排场是很大,很有张艺谋的风格,中间还让我想起过去阳朔玩时,隔岸观看的印象刘三姐的场面。但是我其实一点儿都不喜欢这样的节目,太古朴了,气氛太沉闷压抑了,我还是喜欢充满青春活动,满是激情和阳光的那种。不过我们做为四大文明古国之一,当然是一个好机会好好炫耀一下自己的古代文件,什么四大发明啦,四书五经啦,乐曲戏剧啦等等等等,倒是近代之后,却真的没什么值得称道的东西拿出来说,真是遗憾啊!
  文艺表演持续了没多久,不到两个小时,其中还有刘欢和“月光女神”莎拉布莱曼的合唱,也是让我好生失望,对于刘欢唱的歌,我并不熟,有印象的只有蓝色妖姬、新笑傲江湖和新水浒中的主题曲,水浒中的还感觉不错,到笑傲里就觉得恶心了。这次听来,也觉得不爽,而把人家“月光女神”请来,却来唱几句不伦不类的汉语,实在寒心到了极点。
  接着是200多个代表团入场,太多了,我就忍不住了,一直等到点火炬的时候才回去看,原来的体操王子长成这个样子了,瀑布汗!
  最后再没心没肺地重复一遍,这开幕式也忒难看了点,好生失望!

2008-08-07

路考pass

  仰天长笑三声先,哈哈哈……
  中午吃过中饭,便和江江一起坐车到四季花城门口,教练早就等在那里了,加上另外一对小夫妻,一共4个考生,那男的还教过我练九选三呢。到了车管所门口,4个人各绕着考试路线开了2圈,基本熟悉了一下路线。到考试的时候还是有点紧张的。我是4个人里最后考的,这是我最不喜欢的顺序,我一般倾向于占在最先的位置。不过没办法了,因为不好意思说。第一个GG很正常的地pass了,第2个mm紧张过度,第1次时低头看了一眼,便挂了,车停在路中央,考官立马说开始第2次,结果那mm更加紧张,一下挂了个倒档,车往后一溜就挂了。到了江江的时候,她真是好运啊,上车开了大概10来米吧,到红绿灯前停下,我还以为至少会让她过了这灯吧,结果考官说换人。郁闷,我紧张兮兮地等过了1个灯,转弯,考官就在那说挂二档,挂三档,三档减二档,车在挂二档的时候猛抖了几下(其实我压根都已经忘了这情节了,是江江后来提起来的,我又模模糊糊有点儿这个印象,就当是真的有这回事了),有惊无险地pass了!
  从此,这多年前已经流行的三大件技能我都勉强算是都有了,哈哈哈哈!

2008-08-03

去咖啡厅谈谈

  话说周五下了班,直接爬上335奔向莲花二村,根据同事给的地图,坐391到关山月美术馆似乎更近点儿,不过等不到391了。也不知道这段时间是怎么了,坐公交车入关,好像总是在查,堵得很厉害。好不容易晃悠到了莲花二村,看了一下公交车站上的地图,发现好像并不是很远,走路也赶得过去吧。结果走错方向了,绕了一点路,等我赶到那咖啡厅的时候,已经比约定的时间晚了15分钟了。
  两个人一边吃饭一边谈话,开始的时候还扯得比较远,后来渐渐地他把话题拉到TX公司上来,公司的过去、现在、将来,他负责的部门的情况等等,期间也穿插一些技术方面的话题,还好总的说来,他提到的一些关于技术上的事,我基本上都有所了解,也不至于太丢脸,那时我都自己佩服我自己了,居然知道那么多东西,哈哈。
  去之前,我还在想,如果对方再加点钱的话,我是否还会坚持得住。结果是我想得太天真了,钱是不会再加了,只不过真像小妞说的那样,给我画一个很大的饼,说是过不了多久,可以让我负责一个研究方向,带一些人,隐隐一种leader的架势,但实际上这只是一种事实上的leader,并不一定会被公司承认的。除了这些,他还提到他现在手下的那些人,去年进去的,今年准备给配点期权了,大概意思是说万一我现在过去,也许过个一年也就会有这些东西了。
  可能是看到我还是一点都不心动的样子,他似乎有点无奈或是无趣,问我究竟想要什么。我其实自己也不清楚想要什么,从薪水上讲,那个价也基本不算亏待我了,毕竟我这样的资历,没什么特长的人,是不会有特别的待遇的。其他的呢,我真不知道,那样负责一个方向,带些人,真的是我想要的吗?我发现我真的比想像中的更不爱钱,说起来这样的待遇,比起现在这边,几乎是长了30%左右吧,可是我却发自内心的一点都不在乎。
  我把我最近想做的事情说给他听,他说原来你就是想做一个完整的product,我说也不一定要product,他说那就是framwork之类的,我说对的,就这种东西。他也马上提出现在他手下就有这样类似的东西在做,但是我却依旧不是非常感兴趣。也许我真的只能自己出来干了,这大半年来,一直堕落地看着小说,一部接着一部,被这事一搞,反而弄得我有点紧迫感了。

2008-07-31

还要再谈谈

  本来周二电话里已经把人家拒了的,今天又接到电话,说要谈谈,让我有点觉得不好意思,看出来人家似乎还是挺有诚意的。不过小妞说,到时会给我画很大一个饼,让我觉得在那里会多有前途。小妞还说,反正是两边互相忽悠,没关系的。
  我都想不好了,到底应该怎么选择呢!因为电话里说不清楚,于是约了明天晚上下班后去关内的一家咖啡厅里聊聊,唉,心好乱!

2008-07-30

看mm,撞柱子

  早上去食堂,看到江江,就想跟她打招呼,可是隔得远了点,人也多声音也嘈杂了点,她硬是没看到了,于是我一边回头看着她,一边往前走,没走几步,结果整个人撞在石柱上了,头上撞得最厉害,好痛,搞得我头昏眼花。我知道后面一两米的地方有一个人跟着在走,觉得特别不好意思,头也不敢回,连忙走掉。丢人丢大了,想起之前也有一次是在食堂跟小妞挤眉弄眼的,结果连人带托盘撞在悍超身上,昏!

2008-07-29

使用gperf

  昨天就想把其中一段代码,一堆if...else比较字符串的代码替换成用gperf生成的hash来进行分派,但是昨天想了想我根本不会用gperf呀,晕死,于是想着回家上网找点资源。结果回到家还是什么都忘了,光顾着看小说和聊天了。
  今天到公司里看到那段代码才想起来,昨天晚上堕落去了,于是有点儿沮丧。后来偶然发现,嘿嘿,在资料共享区有几篇关于gperf的文章,看来是我跟同事的唠叨发挥作用了。看了一下,发现它的输入格式虽然有点学了lex/yacc的样子,却比它们简单多了,而且我的需求也是非常简单,就是可能会有6种不同的字符串,我现在想让它能自动映射到一个枚举值。gperf的秉承了开源命令行软件的一贯作风,虽然只是那么小小一个功能,也提供了好几个命令行选项,幸亏有比较详细的中文说明,再加上功能实在不复杂,试了几次,就可以了。跟最新的flex/bison一样,我用了cygwin中版本号3.0.3的gperf,它也支持输出C++代码,这是我比较喜欢的一点,毕竟C代码混在C++中还是感觉有点别扭的。
  另外一点说不上技巧的小提示,如果对生成的hash函数不放心,可以写个单元测试用例,跑一遍就安心啦,而且这种hash函数一般的应用场合下不会有太多的映射关系,看人家ruby用在识别关键字上,也就是几十个而已,单元测试遍历一个所有的映射关系,写一遍就一劳永逸,不错不错,哈哈。
  这个小工具值得推广,以后凡是遇到3个或以上字符串需要比较时,就可以考虑用gperf来做这种工作,不但代码运行效率高,而且代码可维护性也上去了,一举两得。

2008-07-28

修改版Cruise Control

  好不容易等到可以公开获取的修改版Cruise Control,装上来试了试,问题多多啊,还没有文档,这才是让人郁闷的,现在的我已经越来越习惯看文档行事了。
  这个修改版的Cruise Control有一个好处是,集成了多种工具,比如代码行统计、代码风格检视、代码静态检查、代码复杂度度量、重复代码检查等等,如果光是执行一遍这些工具,用官方发布的Cruise Control也可以做到,只不过这个修改版可以对每种工具的运行结果生成一个xml格式报告,最后将这个报告merge到Cruise Control的log里去,然后又扩展了对log的解析,可以以统一的报表格式查看各种工具的运行结果。
  但是这个Cruise Control集成的这些工具运行得并不稳定,首先代码行统计的好像没一次正常运行的,总是阻塞在那里,要手动杀掉进程才行,然后是复杂度度量的生成的日志因为太大,然后merge的时候老是有问题,还有就是这个改过后的Cruise Control不时地会出现运行不下去的情况,真是郁闷,当然最不爽的还数没有完整的文档,我发邮件给该项目的接口人,结果回了个邮件说还在某些产品线试用,等试点结束后让我去问各产品线的负责人,靠!

2008-07-27

coLinux没啥用

  公司内部的论坛里看到coLinux的介绍,于是从论坛里随手下载了一个装上试了试,只有最基本的一个可用的系统,这个系统作为Windows上的一个应用程序来运行,但表现上看,又是一个Linux,在shell下可以运行各种命令,查看各种系统状态数据。可如果仅仅是这些东西,对我还没什么用处,我至少也要在Linux下写几行代码吧,不过这些都需要自己额外安装,在公司不通外网的苛刻条件下,几乎没有了继续下去的兴趣。
  另外有个比较完整的发行版,叫andLinux的,还在beta阶段,这也是开源软件常有的现象,WINE不就beta了十几年嘛。andLinux似乎直接提供了大部分需要的软件,特别是那些GUI的是我比较关心的。但是后来想起来,其实我即使装了,现在也没多少用途,主要目标还是Windows下写写代码,最多最多以后,可能会需要在其他平台上,比如Linux,很可能也有Mac,也有可能一些嵌入式设备上,但这不是目前要关心的了。所以这个coLinux对我来说,没啥用哈!

2008-07-22

C++ Builder with Boost 1.35.0

  从David I的blog上看到,C++ Builder 2009会附带Boost 1.35.0一起发布。想起当初,我弃C++ Builder不用转向VC,其中一个原因就是Boost对编译器的支持上,VC远远好于C++ Builder,虽然几年前,都号称C++ Builder对C++标准的支持远远好于VC,但那也是2002年前的事了,当时就已经泛滥的VC6,虽然对标准的支持差了点,但还是很多人用,而C++ Builder对标准的良好支持只是作为广告的谈资,实际上可能并没有为它带来多少用户。后来随着VC2002、VC2003的发布,VC的进步也是突飞猛进,而且从那时起,很多第三方C++库也把支持VC作为优先考虑的事项,从此Borland的C++编译器就更没落了。
  其实以我个人狭隘的眼光看来,C++ Builder也没达到预期中的好的效果,有一个原因是,它使用了以Object Pascal写成的VCL库,而不是用C++写成,这样为它配合使用其他C++库,造成了一定的阻碍。虽然因为C++ Builder提供了一定的Object Pascal的支持,使得很多为Delphi设计的第三方组件,可以在C++ Builder上使用,但这并不是它使用VCL带来的好处。
  这次附带Boost库的行为,我以为,并不会为C++ Builder带来多少市场占有率,就好像其他编译套件都没有默认附带Boost,但它们的用户如果确实需要肯定会去自行下载、配置、使用,而从编译器角度来讲,其实最需要做的是改进编译器,提高编译速度、改善最优化能力、增强兼容性,使其尽最大可能地支持Boost。
  以后,在Windows平台上,会不会只有一个叫VC的主流C++编译套件了呢?

2008-07-21

长训归来

  长训回来了。昨天去的时候,我第一个开,除了经验不足,有些时候有点手忙脚乱之外,自我感觉还是不错的,主要还是靠熟练,多开开,也就会了,就像带路的教练说的他有个学员,九选三之后就去自己买了个车,等到路考的时候就已经开了5000公里了,其实如果只是单纯作为代步工具来说,开车一点技术含量都没有,全靠熟练。
  今天早上回来的时候,还是我第一个开,路上目睹了一起车祸的现场,面包车与摩托车,一个人已经脑浆涂地趴在路上,估计是那个开摩托车的,人的生命是如此脆弱。
  之后就是赚点钱,过个半年自己买个车了。

2008-07-20

要去长训了

  学个车还真是麻烦啊,这回要跑去韶关,来回需要两天,于是明天又要请一天的假了,想起来上周四下午请的假还没有填请假电子流呢,记性真是越来越差了,难道真是因为没有休息好。
  上路也才练过一次,还是跟江江两个人轮流开了一个小时,我总是集中不了精神,眼睛看着路,思想却不知道飘到哪里去了,于是车就方向乱转了,于是被教练骂了,于是我郁闷了!
  也不知道路上会遇到什么,教练说那条路上车很少,就算是学员也可以开得很快。我没有什么想法,只是觉得这考个驾照怎么有这么多事啊,过了这趟,下次还要再请假去考路考,烦死人了!

2008-07-19

代号Tiburon

  这几天看google reader上Codegear blogs一栏上,不时地贴出Tiburon这个词,开始还没留意,直到过了两天,目光稍作停留,才发现,原来是Delphi 2009/C++ Builder 2009的开发代号!上wikipedia查了一下Tiburon,似乎是一个加州小镇的名字,也不知是不是说的同一个。软件以地名作为开发代号的例子数不胜数,Borland系的产品更是如此。
  这两年是Delphi/C++ Builder的多事之秋,先是从Borland分离出CodeGear子公司,出了个Codegear RAD Studio 2007,之后就是将整条IDE产品线以两千多万美金的跳楼价甩卖给Embarcadero,一代传奇,以这样的方式终结,让人唏嘘。
  Tiburon最大的改进是对Unicode的支持,说是所有的都是基于Unicode实现的,包括编译器、RTL、VCL、IDE、COM、dbExpress等等等等。我也不知道到底用户对这个特性的需求有多强烈,只是感觉这太晚了点,如果早5~8年就有这个特性,也许情况会好一些。除此之外,增加了一些新的VCL控件,不过说实话官方VCL控件的个数多少其实影响并不是太大,好多第三方控件库,各种酷炫的控件都有。另外还有些其他的改进之处,比如对Delphi语言的修改,使其支持泛型、匿名方法等,还有IDE的增强。比较炫的是C++ Builder集成了UML建模工具,可以使代码和UML模型同步,来回在两边编辑,这个特性我比较感兴趣,一定程度上说,Borland系不愧是最会做开发工具的。
  然而,我现在已经不用C++ Builder了,转用VC一年多,也只是工作需要,以后会慢慢转向那些开源免费的开发工具上去,或者自己做。现在或许只是因为身上有那么一丁点自己也不太愿意承认的Borland情结,关注一下最新的发展动态罢了。

2008-07-17

最好的软件是自己写的

  想起一句老话,天下乌鸦一般黑。回头想想其实现在也挺好的,写写代码,拿点小钱,混个日子。于是突然又想起自以为很真理的一句话“最好的软件是自己写的”,客户为导向的策略告诉我们,最好的产品就是客户想要什么样的我们就做成什么样的,于是需求收集分析就是非常重要的环节,如何正确理解客户需求,满足客户无休止的要求,是我们制造业工人的头等大事。再回过来看,自己想用什么样的软件,当然自己最明白,所以省略了信息传递过程中信息损耗、变形的过程,最后可以得出前面提到的结论“最好的软件是自己写的”。

2008-07-15

收到Intel寄来的书了

  几天前突然想起Intel似乎是在网上可以直接申请指令手册的,大学的时候就申请过,不过都没看直接在毕业离校看给一个老乡师弟了。现在想起来可能会搞点跟汇编、CPU、指令集相关的东东,所以又想弄一套来。
  先在Intel的网站上找了一下,没找到相关的链接,于是google一下,还真能搜出来,以前可以直接在网站上填张表格就申请好了,现在是只能发邮件。于是照着示例写了个邮件,马上就有一封回信了,大致意思说是申请已经提交了,等fedex寄出后,还会发个邮件。结果等了好几天都没什么邮件,还以为中途出问题了。又等了几天,收到一个邮件说7月7日就已经寄出了,但我去fedex的网站上却查询不到。
  今天公司里,收到一封邮件,说我有快递,我猜也就只可能是这书了,跑去投递中心一看,果然是,好大一箱,比上次的还大,有点儿重。回家拆开看看,每本都是厚厚的,但重量却比想像的要轻不少,都是一棵棵的大树啊!
  估计我还是不会怎么去看的吧!

2008-07-12

钱就是这样花掉的

  平常经常抱怨,怎么也不见买什么东西了,怎么工作几年了还是没攒下钱来,真是太奇怪了。其实仔细算算,每笔钱的去向都是有据可查的,只不过我没有记账的习惯,更谈不上理财了,因此就有了所谓“你不理财,财不理你”的可悲下场。
  今天又跑去华强北一趟,已经计划很久了要去买些平常穿的衣服和鞋子。照例没吃早饭,结果看小说看到连中饭的时间也过了,后来实在心里记挂得厉害,就随便收拾了一下便坐车到了华强北。
  先跑去KFC里,吃掉¥36.5。
  然后去红利多看键盘,家里那套微软的无线套装,键盘用得很不舒服,现在天热了,手放在本本上也觉得烫,所以也筹划了几个星期了想换个好点的外接键盘。红利多也没有多少可选择的余地,当初我曾还想过去万商那些小铺子里买个二三十的就行了,结果同事说还是得买个好点的像微软、罗技的,说实话,有了之前的经验教训,短期内我是不会再买微软的了,感觉性价比太低,而罗技的,从大学起,就一直没多少好感,尽管这牌子的键盘鼠标确实做得挺火的。最后选了个LaVIEW,以前没用过,因为我其实只买过3次键盘,第一次是装第一台电脑时一起配的,大概就是30块钱的,不记得什么牌子了一直用得挺好的,直到大四时电脑搬回家,因为想减轻点分量,就把键盘丢下了,到了老家又买了个新的USB接口的,现在也不记得什么牌子了,因为本来就很少回家,所以用得少,印象极其不深刻,也不记得多少钱了,应该也不会超过100块吧,再后来就是在这里给本本买的微软无线套装了,除了无线这个看起来牛B哄哄的特性外,实在找不出它其他的优点了。今天买键盘,主要看手感和外观两方面,最后以129块的价格买了一个超薄的,手感跟本本键盘类似。
  买了键盘就去茂业买衣服。先到adidas买鞋,我也算是龙浩的比较忠实的客户了,每次买鞋首先想到的就是ad、puma之类的。随便挑了双很轻看起来很透气的运动鞋,打了8折还要576块。接着去买衣服,去杰克琼斯看看,好多人,因为在打5折,于是买了件T恤,也要124.5元。
  采购完毕,回家,看看也很不起眼的几样东西,除掉路费不算,今天下午就是860多花出去了。钱就是这样花掉的!

2008-07-11

郁闷,成质量部的人了

  睡得少,白天果然很吃力,这是已经亲身验证过无数遍了。
  本来想着是上午给个新的编译版本让他们测试一下,结果发现,一个最最最基本的功能都不能用,直接弹出消息框。其实是COM接口抛了个异常,虽然我没有用try...catch来处理,但最后还是被我挂接的未处理异常过滤函数捕获到了,弹出个没有内容的消息框。
  于是下午调了近2个小时来定位哪里出的错,因为我自己的电脑上无论怎么样都是正常的,而别人的电脑上无论怎么样都是不正常的。猜了几次,最后想到一个地方,Excel中的CShapes::SelectAll方法,不知道哪里吃错药了,只要一调用该方法,它就抛个异常出来,倒是可以用try...catch捕获到,但却没有什么实际意义,因为我不知道这为什么错了,我以为这就是最正确的用法。
  冥思苦想了1个小时,毫无进展,于是上楼去找老大诉苦,我当然不会指望老大知道怎么解决这个问题,而只是想让老大知道我很郁闷很痛苦。
  再回到座位上,照老大说的,把自己的进展,遇到的困难写邮件抄送给所有相关人,这样至少让他们自己我还是在干活的。一直到下班的时间,质量部负责这事的人跑来跟我说,这二三四季度的绩效考评放到质量部来做了,我彻底郁闷了,成质量部的人了!不要逼我啊!

2008-07-09

crash report

  以前对这方面没有多少关注,只是偶然看到LuaEdit用了个叫madExcept的库,可以让Delphi程序在运行时如果崩溃了弹出个看起来比较牛的对话框,显示一些当前进程和当前系统的相关信息,并可以让用户选择是否将这份报告通过email发送回开发者。当时很好奇这是怎么做到的,很希望在自己的程序中也集成进这个功能,但很遗憾地发现,这个库只适用于Delphi,而我偏偏就不是用Delphi的。
  后来,偶然,没错,以是偶然,看到公司网上有人说FileZilla有一部分这种代码,于是找来看了看,才大致了解了基本原理,并直接把这段代码抠出来用在了项目中,但到目前为了,这个功能虽然加进去了,却还没有发挥实际的功用。因为这段代码针对使用VC编译的程序会生成一个dump文件,该文件需要配合编译时的源代码以及编译器生成的pdb文件协同工作才会有实际用途,而我们的项目没有一个良好的机制把各个发布版本配套的源代码和pdb文件归档。
  这些天看了《软件调试》,稍微了解了Windows的错误报告机制,觉得这是一种能很好改善用户体验,帮助开发团队改进软件的方法。
  前段时间读Code::Blocks和CodeLite的源代码时,发现在Windows平台下编译时它们都动态装入了一个叫exchndl.dll的动态链接库,却只是装入,没做其他任何事情。根据代码注释中的只言片语,加上后来去down了Dr.mingw的源代码,发现这个dll就是做了捕获未处理异常,生成报告的工作。
  于是,我就有了现在这个想法,也许这个想法就是微软的错误报告机制的简装版。首先,确定这套机制由三大部件协同完成:1、未处理异常捕获;2、反馈崩溃信息;3、分析处理崩溃信息。在具体实现时,可按这三部分分别处理,未处理异常捕获,就像exchndl.dll一样,只需要提供一个dll,应用程序只需要装入后,什么也不用管了;反馈崩溃信息,可以另外再写个客户端,将报告信息(文件)传送给服务器端;分析处理崩溃信息,也就放在服务器端了,可以自动作些简单的分析(像WinDBG那样的,配合对应的源代码和pdb,可以找到引起崩溃的代码行),根据这代码行,可以给用户显示个html页面,说明一下崩溃原因等等,当然这需要一定的人工介入,而且也是三部分中最复杂的。这些工作都可以通过微软提供的技术来实现,但还是有不小的工作量,比如像WinDBG那样结合pdb和源代码分析dump文件,这都是调试器的一部分功能了,另外再显示html页面,肯定是需要有先例通过人工编制一个页面。
  而且这套机制似乎有个最大的不足,是只适用于VC编译的程序。也许其他的编译套件(Borland、DigitalMars、OpenWatcom、Intel……)也提供了类似的机制,但可能没有VC的完善,不需要人工分析即可定位到源代码行,这是何等方便啊!

2008-07-08

CodeLite源码阅读

  今天看了一段CodeLite的源代码,很小一段,从app开始看,到Frame。因为想学习使用wxWidgets,阅读现成产品的代码一种比较有效的方法。我并不知道到底有哪些程序是用wxWidgets的,到目前为止了解到的有FileZilla和Code::Blocks,以及这个CodeLite。
  学习的主要目标是掌握如何创建各种类型的窗体,如果为窗体设置消息响应。如果在绝大多数情况下,都能比较快速熟练地解决这两个问题,那么基本上可以认为算是会用这个库了。
  wxWidgets的处理形式跟MFC比较相似,都是有一个app类,代表当前程序,然后有frame类,表示主窗体,在frame类中再衍生出菜单、工具栏、状态栏等元素,也包括其他一些子窗体,比如CodeLite中,用到各种Pane,这些Pane通过wxAuiManager来管理,可在主窗体上依靠,或脱离主窗体浮动在外。CodeLite和Code::Blocks都用标签页(Tab)的形式作为主界面,也用标签页的形式做Pane,但两者在实现标签页时略有区别。Code::Blocks用了wxFlatNoteBook这个组件,而CodeLite则似乎是自己创建的一种组件,该组件将标签页头和页内容分成两个wxPanel来实现,标签页头部分又在这个wxPanel上使用Tab来展现出页头的效果。这样的好处是标签页头相比wxFlatNoteBook有更多的可控制选项,坏处则是需要自己写不少代码。
  现在我最大的困难就在于,还是没有完全搞明白,这个界面是怎么创建起来的,一旦这个框架建立起来了,那剩下的业务逻辑部分都是比较清晰明了的,至少知道大方向上应该怎么走了。

2008-07-07

《C++网络编程》

  心血来潮地翻出照例买来即束之高阁的《C++网络编程》,尘封不止一年了,只记得还是在测试组时买的,而且确实连目录和序都没看过,汗!
  这次也是因为项目里用到了ACE,看了一点《ACE程序员指南》(所谓的红宝书)中关于reactor中的一点内容,似乎勉勉强强可以凑出一个能用的系统了。才偶然想起,仅有的3本讲述ACE的翻译成中文的书我都有了。拿出这卷1和卷2,发现封面都泛黄了,这日子过得还真是让人哭笑不得!
  不负责任地说一句,这两卷《C++网络编程》其实是套讲设计的书。书中以网络编程这个话题为目标,用C++这把究极神兵,辅以设计模式这高等心法,大刀阔斧地讲述怎样设计,为什么这样设计,最后凝结成ACE这套演示成果。
  所以在我看来,这两卷最终成为学习使用ACE的入门及进阶的参考书籍,这样的效果只能说是原本功能的副作用而已。

2008-07-05

《软件调试》

  从china-pub上买了本《软件调试》,厚达1000多页的大砖头。开始拿到的前面有8页是空白,到china-pub上去说了一下,该书的责任编辑通过email跟我协商,最后又快递了一本正常的过来,我再把有问题的那本快递给她,如此服务质量,也让人称心满意了。
  难得原作者用中文写成,这样就可以让我们中文读者第一时间可以读到如此重量级如此深度的精品专著。
  该书从CPU(Intel x86系)对软件调试的支持、操作系统(Windows)对软件调试的支持、编译器(MS VC)对软件调试的支持三大方面进行了讲述,中间结合VC、WinDbg等实例进行讲解。
  昨天晚上躺在床上,快速地浏览了一遍,让我深深感叹Windows,噢不,应该是微软的强大。微软从操作系统到开发工具,都为软件调试支持了极其强劲而且方便的支持,窥斑见豹,微软做软件是多么认真,多么负责,微软帝国的崛起除了机遇外,其自身实力和不懈努力是起主要作用的。
  翻完这本书,我禁不住想自己写一个应用层的调试器,像OllyDbg那样的。粗略想一下,一个调试器需要具有的最基本的功能:反汇编、CPU寄存器读写、内存读写、单步、断点,以及跟系统相关性比较大的装载模块、内存映射、符号信息读取。这些在Windows上绝大部分都有现成的API可以完成了,除了反汇编比较麻烦点(看看IDA Pro做成什么样了,当然动态调试器是不需要这么复杂的),其他的至少从原理上看,是很简单的,困难的是细节。
  嗯,WIND Is Not Debuggger……

2008-07-03

ACE还算好用

  照着红宝书上讲的,用ACE写了TCP的服务器端和客户端进行文件传输,代码量真的很少,而且可读性也很好,虽然没经过测试,但我自以为应该不会有多少问题了。
  ACE还算好用,呵呵。既然这样,以后就考虑一直用ACE来做这方面的应用了,又能满足我跨平台的需求。
  另外,我还是想建一个图形库,像visio/rose那样的功能,也许功能没有那么强大,但是效果就是朝那个方向发展。

2008-07-02

引入ACE

  经过小小的思想斗争,最后我终于决定引入ACE,这个颇具盛名的跨平台网络库。犹豫是因为2个原因,一是我本来没有使用ACE的经验,如果在使用过程中遇到问题也没有求助途径,另一是以前在网上看到过有人说ACE跟MFC配合使用时会有内存泄漏的问题。
  但是想了想,如果直接使用socket来写的话,开发效率更低,需要编写的代码更多,更容易出错。之前也是用了boost::asio,大概是因为没用好,反正不但代码写得难看,也没有能照预料中的那样正常工作。
  同事在一个小程序中使用了ACE,虽然他用的是WTL,却仍然无形中给了我一种鼓舞,最终我还是决定用吧,泄漏就泄漏吧,反正只是个小程序,不会像服务器那样长时间运行的。稍微熟悉了一下reactor的使用方法,还算容易理解。它通过类继承,虚函数覆盖的方式来响应特定的事件。相比boost::asio使用functor回调的机制,更OO一点,而对于我来说,boost::asio可能多了需要对各种对象进行管理的工作。
  争取在剩下的两天里,完成点对点文件传输的功能!

2008-07-01

期待一个合法的强大的IDE

  虽然打算使用MinGW+wxWidgets来写程序,似乎是可以抛弃VC+MFC或者BCB+VCL这类商业软件了,但是,实际上我发现我根本离不了VC,主要是离不了VAX,这个超级好用超级变态强悍的VC助手。
  早先的时候,只用到VAX的智能联想提示功能和跳转到定义或声明的功能,自从看了Martin Fowler的《重构》,VAX的诸多重构功能也成了我目前最常用的功能,日常工作写代码,离了它简直痛不欲生。
  写代码最好用的是VC+VAX,但看代码最好用的,个人感觉还是Source Insight这个虽然不思进取,但基础确实不错的东西。Source Insight也可以用来编辑代码,不过比起VC+VAX来还是弱太多了,而且它也是要买license的,最关键的一点易用性方面不足是,多少个版本推出来,还是不支持标签页浏览,真是不可理喻,而且对中文的支持也是一直都没任何改进。
  所以最好的工具是能集VC+VAX代码编辑功能和Source Insight代码浏览功能于一身的。但是目前还没有找到能达到这种效果的软件,从免费到商业的,都没有。回到最开始提出来的,要用MinGW+wxWidgets来做开发,还是比较困难的,比较折中一点的办法是,先在VC里做debug版进行开发和调试,定期用MinGW生成release版本进行测试,先打造一个好用的CppCoding工具。

2008-06-30

九选三,pass!

  周五的时候才知道,原来我报的是6月30日的考试,一直都以为是7月10日的,所以一直都不怎么着急,还觉得练车次数太频繁,殊不知是30日。周六吃过中饭,正在睡午觉,教练还打电话叫我下午去练一下车,我说不行,要5点半才下班,然后拖到周日上午。今天又是6点半就起了床,匆匆赶到训练场,跟江江一起练了一个半小时,单边桥的我老是右边上不去,教练说不要紧。
  说好11点集合,还有2个小时空闲,于是无所事事地到百草园去,江江趁这个空隙跑去体检了,我就只好无聊地看看网页,偶然发现blogger又解封了,像是重刑犯放风一样。到10点半的时候去百草园对面吃了一碗炸酱面,太多油,腻死我了。刚好11点,教练简单讲了一下考试时的注意事项,然后把我们带到接送车的地方。
  12点半不到就到车管所了,一直到大约2点半的时候才轮到我们考,当时我还多紧张的,可是抽到的是3道,除了定点停车和侧方位停车外,另一项是所有项目中最简单的直角转弯,真是太幸运了。一上去就忘了起步打左转向灯,心里顿时瓦凉瓦凉的。好在后面的都冷静沉着地正常发挥,不但是我,连电脑也是,一点意外都没有,一次就pass了,心中那块石头放下来了。
  九选三,pass!

2008-06-27

如何利用机器资源

  今天突然发现,我在公司里有使用权的机器有好几台了,除了本来一直在用的,从进部门开始就配备的那台联想台式机外,还有一台2001年的老爷机,一台双核2G内存的工作站,一台双核双至强1G内存的IBM服务器,还有一台双核2G内存的服务器。这么多可用资源,现在却发挥不出作用,对工作没有什么帮助,实在让人觉得可惜。
  但是如何利用这些机器资源呢?我确实也想不出好的点子来。可以建些版本控制、数据库、HTTP之类的服务,但还是大材小用。隐隐约约脑中一个概念闪现——分布式计算!可是现在分布式计算能大众化实用化的也没怎么看到了解到,曾经用过一个号称可以加快编译速度的利用VC的分布式编译工具,但当时试用的效果并不好,四五个机器一些联合编译,最后不但编译出来的文件有问题,耗时也比单机编译的多,真让人失望。
  继续想、继续想,如何利用这些机器资源呢?

2008-06-25

Side by Side Again

  昨天随口给一个同事讲了一下怎么部署用VC2005生成的应用程序,才能解决因为先进的Side by Side技术引起的应用程序配置问题。其实我自己也是半生不熟,没有掌握到真正的精髓。今天那个同事就给我打电话,说还是没有解决这个问题。于是我就亲自出马,上午搞了半个小时,还是没搞定。于是看我原来用VC2008写的WallpaperHelper怎么弄的,以及人家的Edraw是怎么弄的。一点一点凑,最后发现那个么临界点,只要先到VC安装目录下有个redist目录,里面能找到发布用的dll和配套的manifest文件,复制出来,然后把manifest中的内容复制出来,自己填写一个新的manifest文件,作为RT_MANIFEST类型添加到exe的资源中,这样就基本解决了。而且从中看到,manifest中的版本号可能比dll的实际版本号要低,但是没关系,反而如果自己强行把manifest中的版本号改了,程序反而不能正常运行,反正照着redist目录里的那样填就行了。

2008-06-18

升级到Firefox3

  话说本来6月17日就是FF3发布的日子,不过由于时差等因素,昨天一直没等到它的发布,于是只好等到今天。回到家迫不及待地下载安装,然后把需要的扩展也跟着升级,对于一些没有对应版本的扩展,只好再上mozilla的网站找替代器,忙乎了一阵子。
  媒体传闻得沸沸扬扬,说得悬乎神技地,但我用了一个多小时后,感觉也没多少值得表扬的。比较明显的改进是,内存占用确实比以前小了,可能只有原来的2/3或1/2吧。另外一个比较明显的修改是所谓的Awesome bar,就那花里糊哨的地址栏,也许是我还没用出来吧,反正觉得原来FF2里的也没有不好用到哪里去,这个也没有方便到哪里去,所以这个特性算不算得上是改进,我保留意见。再有,就是启动速度似乎是比FF2快了一点,不过对于我这样已经习惯于龟速电脑的人来说,吸引力也不是特别大。
  倒是一些原本在FF2里用得好好的扩展,到FF3里不能用了,这让我觉得很郁闷,比如Tab Mix,还有能将网页保存成mht格式的Mozilla Archive Format,都找不到够格的替代品。还有,号称的15000项改进在哪里,仅仅是我这一个半小时的使用,就崩溃了2、3次,这个品质不行啊!
  好了,牢骚发完了,要不是因为不想用IE,要不是看中它扩展多,升级方便,我才不这么啰嗦哩。

2008-06-17

专心做一体化平台了

  看了他们整理了有十几条新的需求,另外bug也确实不少,跑去请示了一下老大的意见,是要认真到这个东西做下去喽。既然这样,就暂时放下编辑器和扩展框架的事了,计划一下如何把这个东东做好点。原来的有些设计是不合理的,在时间充裕的条件下,是肯定有更好的解决方案可以替代的。
  如果真要专心做这个东西,有两点是可以很大优化的。一个是图形库,整出一个像edraw样效果出来,让该死的Excel见鬼去吧。另一个是分布式文件共享,看了Kademlia的一些介绍,不禁有点蠢蠢欲动,如果自己能实现一个通用性好的,后续的价值太大了。
  这两块是相对较大的改动,其中还会涉及到数据库的设计等小细节,想起来居然隐隐有点儿兴奋。

2008-06-16

考倒桩

  考倒桩去了,有两次机会,第一次在最后倒车时,右边的观后镜刮到桩了,第二次就提前打方向盘了,有惊无险,呼呼,困死我了。

2008-06-14

音频播放器小比拼

  如果在goolge(不是“谷歌”)中搜索关键字“音乐播放器”,排在第一位的,赫然是千千静听,第二位提QQ音乐,第四位是Kugoo,如果搜索关键字“音频播放器”,则出现的是foobar2000,而前3位则连影都没有。这一方面似乎可以看出,中国大陆用户对此类软件的偏好和定位。
  因为前些天看到Kademlia的介绍,想到可以结合着做一个不需要服务器的P2P音频共享播放软件,于是偶然关注了一下现在国内流行的此类翘楚。就个人感觉,最专业的还是foobar2000,虽然它的默认界面非常简陋,没有歌词显示,没有文件搜索等诸多目前国内用户用得最多的功能,但是它做为一个音频播放软件,在纯粹的音频播放功能上可是一点儿都不马虎,尤其是它的插件机制,从效果上看,远远强于其它的竞争对手。目前最新版本0.9.x的频谱显示功能,比起前几位,也是强得不行,就比较流行的狭小范围看来,大概只有WMP能跟它匹敌吧。不过由此带来的负作用是,新手上路困难,难以获得菜鸟用户的青睐。另外随便看了一个曾经的老大Winamp,现在是5.5.x版本了,不过在我的机器上极不稳定,立马就卸载掉了,而且似乎没有做好市场调查啊,亦或是老外的使用习惯上就是那样的?
  中国市场的大半江山应该是被千千、QQ、Kugoo三巨头控制了,这三个软件互相之间做得很相似,唯一大点的区别是Kugoo是以文件共享起家的,经过几年的经营,可以极其方便地以P2P的形式直接下载歌曲文件,而服务器上只需要保存些索引即可,负载压力顿时少了。千千则是以纯粹的音频播放器出身的,注重音质音效等是它早些年发展的重点,然而国内用户似乎并不特别在乎这点,当年的在线搜索歌词功能为它短时间内赢得了大量忠实用户。
  其中一个重要的现象是,音乐网络化。三个软件都可以打开一个小窗口,显示一个网页,通过该网页可以查看当前的音乐流行趋势,在线试听,甚至下载(中国不像美国那么注重音乐版权,中国人真幸福)。其它的功能特点,就都很普通了,无非是换下皮肤啦(这皮肤机制也都很土,就是换一下窗口边框,这点WMP就强太多了),有个播放列表啦,搜索显示歌词啦(foobar/WMP/winamp默认的都不行,至少得装插件才能支持),支持插件啦(似乎都没公开的SDK,foobar/WMP/winamp都有,这似乎又说明了两地用户的使用习惯和素质上的差别)等等。就这些明显的特点看来,中国用户跟欧美用户的使用习惯上应该有不少的差别,本土三巨头也算是依仗本地优势,因地制宜,殊途同归啊!

2008-06-12

似乎中毒了

  唉,回到家照往常一样打开电脑,发现explorer.exe是起来了,但界面没出来,倒是弹出个出错消息框,说是哪个进程不正常,看这名字就感觉不是正常的。等了老半天,没耐心了,重启系统,倒是能像平常一样进来了。偶然发现system32目录下有好几个奇怪的文件名诸如oooooo.dll、ffffff.dll之类的文件,而且会自动注入到其他进程中去。windows目录下也有几个文件名很怪的.exe文件,还都放到了系统启动项中了!
  似乎中毒了!真烦人啊,编译个wxWidgets也是没完没了了,以前可要快得多啊!唉,得下下决心,整台好点的台式机来,装Linux来,就用来平常看网页和写程序吧。

2008-06-11

软件该升级时还得升啊

  为了用上比较新版本的flex和bison,又不想额外装个啥Linux,于是只好走旁门左道了,在Windows上装个cygwin暂解燃眉之急。这个cygwin也是个小气的东西,只提供一个大小只有几百KB的在线安装程序,这个程序从远程服务器上下载了文件列表,根据用户选择,下载需要的文件到本地再进行安装。无奈的是我贪心了一点,想把所有的软件包都下载下来,结果昨天晚上开了一晚上,卡在一个包上,后面的都没动静了。
  今天回来看了一下这个软件包列表,提取出所有软件包的远程地址,导入到FlashGet中进行批量下载,可是这个1.9.x版本的FlashGet有不小的问题,平常还看不出来,在下载项很多时,总是不时地卡住下载不下来,而要暂停一下再开始,才能继续下载。当时用它来下载那几千个sogou的皮肤,也把我弄烦死了。今天又是这个状况,偶然兴起,上网看了一下最新的版本,已经到了2.0了,于是索性装一个来试试,哈哈,似乎没有这个问题了哦,而且界面上也改得面目全非了呢!软件该升级的时候还得升啊,呵呵!
  再扯些其它的,这东东放了一堆的广告上去,这也是没办法的,谁叫它是个免费软件呢,人家也要吃饭的。好久之前就听说它是能下BT的东西,不过我已经久不用BT了,改用eMule了。另外又看到它也用到了DHT技术,大概是为了下BT下载才用的吧。前些天看到一篇blog,讲了eMule的Kademlia相关内容,让我有点热血沸腾,这个技术再搭上一个音频播放器,只要用户足够多,就不用什么Kugoo了嘛!

2008-06-10

开源的东西要用还得多用用

  几天无聊中,又拿起TeX来玩,这东东用来做PDF真不错,可用来写软件的user guide或manual,也不用做htm或chm了。
  编译器用gcc,界面库用wxWidgets,多语言和国际化用gettext和iconv……
  今天偶然发现cygwin中的flex已经是2.5.35版本了,而gnuwin32中的才是2.5.4,bison在cygwin中是2.3,而gnuwin32的是2.1,差了不少了啊,看来得装个简装版的cygwin才行。
  也不单是为了不用盗版,而是这些开源产品确实质量已经足够了,尤其是在开发方面。

2008-06-06

为了无界面运行Redmine

  项目组把mantis换成了redmine,相比之下,redmine似乎提供了更多功能,也更符合我们目前的需要。redmine是一个ROR(Ruby On Rails)应用,于是简单起见,我们使用了InstantRails这个傻瓜包,但是,有一个问题是,我们总是在InstantRails的界面上使用Mongrel启动Redmine,于是会出现一个Ruby运行的黑窗口,一直到运行结束。
  从网上找了一些资料,发现至少有两种办法可以解决这个问题。一种使用Apache之类的专业Web服务器,然后安装FastCGI,把ROR在后台运行,所有外部请求由Apache来转发。另一种是使用Mongrel_service,把mongrel注册成Windows服务,这样就可以在后台运行了。于是我想试一下第二种方案。
  本来gem install mongrel_service这样一条命令似乎就可以把这个gem包安装到本地,但实际上我发现我根本不能安装任何一个远程服务器上的gem包,可能跟网络环境有关。于是我只好到它的官方网站下一个gem文件下来,用gem install mongrel_service -l命令进行本地安装。这时会提示需要win32-service包,于是到Rubyforge上去找到官方发布,也下载到本地安装,然后又提示说要windows-pr,下来安装以提示说要windows-api、继续下来安装,继续提示说要win32-api,再下来安装,然后反向这个顺序依次安装,到了后来,提示win32-service的版本要是≥0.5.2或<0.6.0的,而我装的是0.6.1的,于是只好反安装,rubyforge上又找不到0.5.2的,从其他地方搜了一个源代码包,解开后,执行命令ruby win32-service.gemspec,会生成gem包文件,再来安装,又提示要VC,而且经过试验,如果是用的InstantRails 2.0中的Ruby,则要用6.0版本的VC才能正常编译。终于mongrel_service也安装好了,可以注册一个Windows服务器,启动这个服务,则用ruby运行一个rails应用,我这里就是redmine了,当然redmine需要MySQL支持,不想直接使用Instantrails了,把MySQL也添加到服务中,Apache是不需要了,启动这2个服务,就能无界面运行redmine了,哈,开源的东西,还真是有点麻烦呢!

2008-06-05

这个世界有点疯

  偶然看到一则消息,遨游将自主开发浏览器内核,真是让我觉得有点不可理喻。当今世界,IE、Firefox、Opera、Safari几大流行浏览器正拼了个你死我活,遨游从MyIE开始,多少年来一直使用IE内核的外壳程序突然从中插一脚,在我看来,实在是前途困难重重,希望渺茫啊!
  先不说遨游是否有这个技术实力,就算有了水平堪与一流产品比肩的成品,最后的宣传推广,以及后续维护发展,也是前景相当不乐观的!

2008-06-01

困了累了不想动了

  总觉得心事重重,走在路上焦躁不安,忍不住安慰自己“熬过这个六月就好了”,心里刚刚默念完,突然觉得这句话很熟悉,似乎以前自己说过。不过要说真的说过的,那肯定得是一年前才可能的事了,去年的六月我又在烦些什么呢!确实好像这一年多来,一直过得很不顺心,每次都劝自己说“熬过这段时间就好了”,结果这样的时间一段接着一段。
  计划有点宏伟,但对于我这么一个懒散的人来说,着实有点困难:
WallpaperHelper——VC/MFC;
SourceCoding——MinGW/wxWidgets;
DCoding——MinGW/wxWidgets;
CppCoding——MinGW/wxWidgets;
PHPCoding——MinGW/wxWidgets;
RubyCoding——MinGW/wxWidgets;
PyCoding——MinGW/wxWidgets;
LuaCoding——MinGW/wxWidgets;
TclCoding——MinGW/wxWidgets;
PerlCoding——MinGW/wxWidgets;
TeXCoding——MinGW/wxWidgets;
XMLCoding——MinGW/wxWidgets;
Flowchart——MinGW/wxWidgets;
SoftwareDiagram——MinGW/wxWidgets;
NetworkDiagram——MinGW/wxWidgets;
Go——MinGW/wxWidgets;
Chess——MinGW/wxWidgets。

2008-05-30

可以不用商业化的开发工具啦

  鉴于编辑器模块的重构任务已完成大部分,从两个View中提取出了一个基类View,这样总的说来大概减少了近2000行代码吧,中途也遇到些小麻烦,不过最后都没花什么大力气解决了。
  今天就又看了一天的lex和yacc的资料,真是犯贱呀,在学校的时候这么大把的时间不好好学习,现在却要临时抱佛脚。回来看了几篇blog,难道最近流行学习编译原理?从理论到实践,都有人在搞。以前还是很不在乎的,因为再怎么样,也很少有可能需要自己去写一个编译器出来。其实现在若不是要整编辑器,也很可能再也不会去碰这玩意儿了。
  昨天看到网上提到一个软件CodeLite,于是好奇心起,装了一个来试试,使用wxWidgets开发,所以横跨Windows、Linux、Mac三大桌面系统。它只是一个编辑环境,编译器还是使用其他的解决方案,比如MinGW,不过除开编译器因素不谈,它是个自消费系统,跟Code::Blocks一样,在自己的环境下开发自己,如果下载了它的源代码想自己编译一把的话,除了要装必要的编译器和程序库外,还得先装一个它的Release安装包,这个过程很明显又给自己打了一把广告。
  突然我有个大胆的想法,这似乎是给我一个完全抛弃盗版软件的机会。在Windows平台上软件的丰富程序,确实很大程度上影响了我们的日常生活。记得还在大学的时候,就很雄心壮志地想所有的软件都不用盗版的,如果遇到找不到开源免费的,就自己写一个。但很严重的一个问题是,我当时只会用C++ Builder,所以开发工具只能用盗版的。现在也没好过到哪里去,只不过从C++ Builder换成了VC而已。可目前,就似乎有另外一种选择,使用MinGW+wxWidgets,从CodeLite和Code::Blocks的表现看来,完全可以满足我目前绝大多数的需求,而且还带来另外一个意外的好处,就是跨平台!虽然都没怎么想过在其他平台发展,但现在有这样的低成本扩张机会,何不放手一试呢!从此可以不用商业化的开发工具啦,哇哈哈哈哈!

2008-05-28

IDE的编辑器就要这样做

  又看到José León新发的blog,再结合吃晚饭时,同事的抱怨,不禁羞愧难当,伟大的Borland,伟大的Delphi,哪怕是几经更名,哪怕是几经易主,曾经的IDE霸主,编辑器就是应该这样的做的。
  今天花了点时间重构编辑器的auto completion、call tips模块,框架早已完成,剩下的是只让整个流程运作起来。中途发现几处笔误和遗漏,都不是大问题。清理了原来的代码,从原来的几百行的规模,拆分成现在几十个文件和类,本意是让设计更容易理解和维护,也尽量往容易进行单元测试的方向靠拢。不过等都完成后,回想起来,这样的设计仍然觉得不是很爽。类与类之前的关系略显得混乱,有些依赖关系感觉不是很符合OO的那些基本原则,但具体怎么做能更好,我却没什么头绪,大概也是因为理论理论和实践经验的两重不足引起的吧,只能靠不断修炼,逐步提升自己的exp了。
  同事抱怨说自动提示功能很少能正常工作,我觉得很惭愧,当时刚做出个样子来时,心里还是比较自豪和骄傲的,不过现在事实摆在眼前,离真正可用,好用还差得很远。幸好现在已经有了思路,用lex和yacc来做,再好好设计一下,争取让这功能真正好用起来,计划花一周的时间完成。再花两天,把编辑器View的基类提取出来,以后所有需要代码编辑功能的View,只要从这个类继承,就可以得到功能基本完善的编辑特性集合。最后,花两周时间,把外部脚本扩展的框架实现。

2008-05-27

丰富Scintilla的AutoCompletion

  今天又读了一点Scintilla的源代码,因为要达到现在比较流行的AutoCompletion的下拉列表,旁边还能显示一个tooltip描述选中项,那种效果,所以要先熟悉一下代码流程。
  总结一下思路,要至少增加2个消息,用于显示或隐藏描述选中项的tooltip用。增加1个回送通知,用于告诉用户有机会对选中项进行额外操作,这里也就是显示这tooltip。修改listbox的显示方式,主要有效内容要加粗,其他的不加粗。修改选中项上屏函数,用于过滤出确实要上屏的内容。
  总的说来,工作量似乎并不大,但实际上我却很懒得动手,而且为了以后发展的需要,最好这部分功能能合入官方源代码中,而确实Scintilla的原作者Neil Hudgson曾经说过,自己不会去做这个功能,并且并没有说,即使别人贡献了这样的代码,他一定会合入。
  今天顺便看了一会儿notepad++的源代码,有几个小功能还值得学习,不过我个人认为这代码写得并不好,至少不如Scintilla的代码,但有些设计确实不错,而且它还能支持简单的插件。但我认为它最不好的是,似乎它使用自己修改的Scintilla,这样它的通用性就不好了。

2008-05-26

Code Insight in Delphi for PHP

  偶然看到这篇文章,Delphi for PHP已经升级到2.0了,不愧为曾经最强大的IDE生产商,把PHP的开发工具都做得这么神!
  Code insight,也就是auto completion、call tips等功能的集合,想当年,第一次用Borland C++ Builder 5.0的时候,就很诧异它的auto completion,不过那个版本并不稳定,后来没多久就出了6.0,发现稳定好多,不过以现在的眼光看来,它的速度就慢了点,还看到国内有个牛人自己写了个增强插件CodeFast,速度,内容上都有很大提升,但极其不稳定,几乎处于不可用状态。当时用得多开心的,而且以VCL出色的设计,开发GUI程序,尤其对于初学者,有极大的鼓励作用。由此,我也就以为,Borland出的IDE是世界上最好的IDE,这个原因,也一定程度上让我不再愿意去费力气转向其他工具,包括VC。
  后来用上了装了Visual Assist.X的VC,发现VAX的能力太过惊人,再后来就是工作中,直接使用VC作为开发工具,就已经离不开VAX了,VAX的智能提示功能实在是太好用了。
  工作中,负责的也是一个IDE的编辑模块,其中的auto completion和call tips则是重头戏,前段时间计划着增强该功能,但一直没有动手。曾经考察过几种当前甚为流行的IDE的这个功能,包括VC(其实是VAX)、C++Builder/Delphi、Netbeans、Eclipse、Visual SlickEdit,当时的比较结果看来,C++ Builder/Delphi的似乎是其中最弱的,Netbeans的则看起来比较炫,太显得啰嗦,VAX的比较适中(可能也是因为看习惯了)。但有一条明显的需求是,当光标在下拉候选列表项中移动时,旁边应该可以弹出一个tooltip来详细描述当前被选中的项。但是项目中使用的Scintilla控件似乎并不直接提供此类支持,因此需要修改控件的源代码,而这是我最不愿意做的事情,我希望这个支持应该由官方来做。
  而今看到这篇blog,则提供了一个可以学习的范例,同样是脚本语言开发环境,别个是当前业界最先进的,当然应该取其所长,补我所短了。

2008-05-25

关于打谱程序突然想到的

  今天突然有个想法,关于前段时间的用WTL写个围棋打谱程序的念头,是否可以把棋盘、棋子绘画动作也抽象出来,棋子的位置、走法规则都提取出来,有一组严谨的约束,而且这组约束可以通过配置文件,或者脚本来描述,最后,C/C++代码则只用来完成具体的绘画操作,对这些约束完全一无所知,比如它只知道在哪个坐标画一个什么样的图形,而为什么要画这个图形,这个图形有什么其他的含义,都不是它需要知道的。
  如果确实能高度抽象地完成这个描述,那么带来的灵活性则是非常有用的。对于单纯是一个围棋打谱程序来说,也许带来的好处并不明显。但再换个角度考虑,在这一套架构下,很容易通过写少量脚本或配置文件,而不需要修改一行C++代码,一个围棋打谱程序立马摇身一变,成了一个象棋打谱程序,或者五子棋打谱程序了。这样的诱惑,对目前的我来说,实在是巨大呀!
  这个想法的灵感,源于Eclipse的编辑器,《Contributing to Eclipse》中有一小段描述可以贡献一个编辑器,当时看到这段描述,甚是激动,差点想把那个IDE项目中的编辑器模块也这样做了。这次又联想到打谱程序,同样是画棋盘棋子的,只要合理设计,理应也可以达到类似的效果。
  不过随便想想,以在世界范围最流行的4种棋类(围棋、中国象棋、国际象棋、五子棋)为目标,要想尽可能简单且灵活地实现,还有点困难。如何表示棋子的类型、如何表示行棋规则、如何定义精确的棋子位置以便程序绘制等等,都是摆在眼前最大的障碍。五子棋最容易表示,只有2种棋子,直接落子,虽也有像五手两打,三手交换之类的奇怪规则,但这些似乎都是在棋谱解析部分的工作。围棋则略为复杂,一个明显的问题是,要能计算出死子,并提出棋盘,这个工作如果纯粹交给外部脚本做,怕是会有心无力,但照现在的设计思想又不能让C/C++代码来做。两种象棋就更复杂了,棋子的类型就相比多了很多,每种棋子的合理行棋方式又都不一样,虽然从纯粹打谱的角度讲,比围棋、五子棋也复杂不了多少,但是在棋谱录入时,则很让我头痛了,如何表示一个棋子从一个位置移动到另一个位置,是否可以移动,移动后是否棋子的属性有变化(中国象棋中兵过河可横行,国际象棋中兵到底线可变身),移动后是否影响了其他棋子(吃掉了)等等,关键是一套界面和逻辑的交互协议,不能设计得太偏向于是为某种任务而特意为之,但又得有足够的信息在两者之间传递!

2008-05-24

初学lex

  其实学的是flex,从公司网上找的,大概也是gnuwin32中的某个版本。顺便在公司网上又找了些资料来学,纯粹只是看的话,是跨不过那道坎的,所以要自己写几行来玩。生成的C代码倒是能直接用MinGW中的gcc编译,这让人觉得很舒心。开始的时候不明白,为什么写的正则表达式好像不起作用,总是把该扫描分析的文本全都打印出来了,而我明明只是想让它打印被匹配上的那些内容就行了啊,经过仔细观察,最后发现,其实是flex生成的C代码中,自动把不匹配任何自定义正则表达的内容也输出到控制台上去了。所以有两个办法可以解决此问题,一是把匹配内容输出到文件中,另一是修改下flex生成的C代码,把默认输出的那个ECHO修改了。
  让它分析一个3万行的rb文件,匹配几种常见的token,如常量、变量、数字等等,速度奇快无比,可能不到1秒吧,想想我原来用Greta写的全文匹配5种模式,不知道要多久,不过幸好在不是很晚的时候发现了这个解决方案。从中已经可以看到曙光,原来我的猜想、直觉应该是正确的。flex可以解析出token,因为我需要的是其中的子模式,所以光是flex还不够,需要借助yacc(现在用bison的比较正常吧)进行语法分析。我猜即使加上了bison生成的语法分析过程,扫描那个3万行的rb文件,得到需要的结果,应该也不会超过3秒钟吧。不过另外有个问题需要注意,flex和bison生成的代码里都有一些全局变量,如果在多线程环境中使用,需要非常小心地进行同步,不过也许,自己也是可以对生成的代码略作修改的吧,尽管这些代码的可读性在我看来真的十分糟糕。

2008-05-22

有必要系统地学习一下编译原理

  因为我是一个半路出家的coder,除了会写几行C/C++代码外,所有其他计算机科班出身的人会做的事我都不会,这也是我的一大劣势。
  其实前段时间就想过,要学一下lex和yacc的用法。有这个想法,主要还在于看到不少开源项目,比如doxygensource highlightswig等等,全都用到了相关的东西,而正是因为我对这方面一无所知,所以即使能获取到它们的源代码,我也不知道如何自己编译。
  这两天在公司里,遇到一个问题。编辑器里需要auto completion,为了尽可能实现地进行联想,于是以project方式组织时,需要扫描单独文件的上级文件内容,把符合要求的几种模式都识别出来,其实也只有5种。于是我就用了一个比较简单,可以说是笨的方法,用正则表达式去全文匹配一下,5种模式就匹配了5次,当文件内容少的时候,问题不明显,可说是没有问题。当文件有几万行时,就不行了,CPU占用率一下就99%以上了,而且匹配一次就会持续十来秒,5次就可能要1分钟去了。而且这个动作是在打开文件的时候进行,所以如果连续打开多个文件,机器就假死了。这个问题一直在存在,存在大半年了,只不过没人提出来,我也没意识到其严重性。这次跟同事讨论起来,我才觉得不改不行了,但我又想不出好的办法,缺少必要的理论支持,绞尽脑汁也是无济于事的。我的直觉告诉我,用编译原理方面的知识可以解决这个问题,所以学习编译原理也将提上议程。
  编译原理一直以来是我最怕学的东西之一,记得很久以前,高中时的某个假期吧,但毫无进展,不了了之。后来大学时考高程,其中有一部分就是编译原理的内容,全靠考前死记硬背,考时胡乱蒙猜。可能其他还欠缺些理论知识的支撑,也是一部分原因吧。
  因为想做好编辑器,所以对代码编辑的支持是必不可少的,因此从现在开始,订个计划,学编译原理,lex、yacc使用。

2008-05-21

书送到了

  今天上午连续接了两个奇怪的电话。已经有几次了,打到什么布吉五金商行的,结果打到我们这个座机上来了,不过有趣的是,这次这个家伙没有直接挂掉,而是跟我扯起来,说什么交个朋友,有没有兴趣出来干,呵呵,感觉像是个人贩子似的。好不容易挂掉电话,马上就有另外一个人打进来,听背景声音跟前面一个是同一处,但听口音,明显是两个不同的人。这次这个也比较有趣,问我们公司现在招不招人,有什么岗位,待遇如何等等,还说是不是研发的都是高学历的,水平很高的,呵呵。又是好不容易挂上电话,手机又响了,这次是当当网送货的了。蹭蹭跑出去,发现居然是在岗亭门口的一个小角落里,而且看货有好几箱,而送货的只是一辆小自行车,真不知道他怎么把这么多书载过来的,混口饭吃也不容易啊。
  打开看了看,建筑类的几本书的纸张质量还真是不敢恭维。《Head First Design Pattern》外面有一张塑料纸包着,好厚一本,拿回家翻了翻,有点后悔,价格定那么高,里面的篇幅实在没多少,很多的插图,很多的空白,浪费啊,看来我还是习惯那种适合苦读的典型的中国教科书啊。《建筑模式语言》有上下两册,精装的外壳,很厚很厚,但里面的纸张远不如《Head First DP》,《建筑的永恒之道》不是很厚,而且不是很大开本,不过奇怪的是,想不到建筑类的书居然也定价那么高。

2008-05-20

继续学习设计模式

  还是没干什么事,看了一阵书,话说昨天把《设计模式解析》第二版还掉了,其实旁边的同事又马上借回来了,于是乎我就拿来看看,看得囫囵吞枣的,不过也比直接看GoF的要省力得多。其实一直以来我都很少会认真仔细地从头到尾看完一本技术类书籍,很多书甚至是只看了前言、序,或者目录就直接丢到一边了。虽是这样,就算没完整看完一本书,像那种武侠小说中描述的那样,像我这样的小虾,向大师学习时,能领悟到个一招半式也是受用无穷的了。
  到今天为止,大致了解了Adapter、Facade、Bridge、Strategy、Abstract Factory这几种模式。简单地说来,Adapter是为了转换接口,Facade则是为了封装并简化接口,Bridge说是把抽象和实现解耦,在我看来,实际是把几种不同类的概念分类,避免组合爆炸,Strategy是为了封装算法,Abstract Factory则是封装一系列相关的类的实例化过程。在阅读《设计模式解析》的过程中,我还发现一个比较明显的现象,有些模式,或者说有些解决问题的方案,其实都是通过将问题细化,将较细粒度的变化进行封装来实现的。比如书中讲述Strategy模式时,一开始例举的是直接继承,在论述了该例的缺点后,才抛出新的方法,其实就是把更小更精确粒度的变化提取出来并进行封装。在讲述Bridge模式时,也有类似的倾向和做法。再回想《重构》一书中,作者Martin Fowler则是更激进的做法,如果要给一段代码添加注释,则把这段代码提取出来,用有意义的函数名来阐述代码的作用。这从另一角度促使了小粒度代码段的生成。
  《设计模式解析》一书的写作风格也是让人比较舒服的。作者会花一些章节进行理论或实际例子的讲述,再用一些章节描述模式,再讲述一些通用的理论,如此穿插的作法,反正我书看得少,正是第一次看到,感觉比较容易让人接受并领悟。

2008-05-19

静不下心来

  我就是缺乏定力,就是忍不住去做些无聊的打发时间的事情,就是不愿意去做些有实际意义的事情。早上起来就觉得很烦躁,也不知道是哪里出问题了,仔细想想好像也没有什么重要的事情,但总是静不下心来。
  白天在公司里糊里糊涂地过了一天,看了一点书,《设计模式解析》,书写得还是比较合我的口味的,不过下午的时候去图书馆,把这书还了,因为快到期了,以前没怎么看,后来觉得有用的时候,却是借期快满了。虽然只看了前半本,但也觉得略有斩获。前半本有不少内容是通用性的概念,有些概念我一看就觉得就是这么回事,不过自己却肯定总结不出这么精辟的来。

2008-05-16

XUL,也不错的一种选择

  今天在公司网上看到一人发了个Komodo IDE,装来看了看,猛然发现它是基于Mozilla XUL技术实现的,有点诧异,居然还真有用XUL技术开发的商业软件。然后就跟公司里的另外一个人讨论了一下,那人比较了解XUL,在去年还做过技术选型工作。
  从中我了解到,有一种叫Remote XUL的技术,可以使得通过Firefox浏览某个页面,界面效果跟通用的桌面软件差不多,但实际上却真真实实是部署在远程服务器上的。其他能达到类似的效果的有JAVA Applet,或者MS的ActiveX,好像Adobe现在在搞的AIR也差不多,有种让人惊艳的感觉。看来该是有必要学一点这方面的新技术了,一直以来觉得跟Web相关的,都不是很感冒,但现在看来,它混淆了B/S和C/S,即桌面和浏览器的概念,很有意思啊,比如,假设有一种能适应各种浏览器的这类技术,那么做一个Web版的IDE什么的也不是问题了。
  除了这种远程部署的界面技术,还有其灵活的可扩展框架也是让我感兴趣的。那人的胶片中对Eclipse RCP和Mozilla XUL进行了简单的比较,结论是更看好XUL的,不过我个人的观点看来,两者单纯从可扩展性上讲,各有优缺点,不相上下吧。XUL体系使用C/C++实现具体的界面控件,然后用XML描述界面布局和事件响应,用JavaScript完成实际的业务逻辑,响应XML中定义的事件,调用C++代码作出具体的动作。XUL要创建出新的界面控件比较困难,只能用已有的控件组合成新控件,所以像Firefox就实际上提供了扩展和插件两种不同的机制,扩展就完成只使用XML和JavaScript实现,而插件就可以实现比较高级的像内嵌Flash播放器之类的功能。总之,简单看来,相比Eclipse的实现方案,XUL并没有哪里特别不如,或哪点特别突出,只能说也是一种不错的机制。倒是让我多了解了一种扩展方式,自己设计可扩展的软件架构时,倒是要好好考虑一下了。

2008-05-15

再次开始学习设计模式

  虽说好久好久以前就认识到设计模式的重要性,也好几次都决心要认真系统地学习一下,但是每次都没能坚持下来,每次看到GoF的书,立马一个头变成两个大,实在是枯燥乏味啊。倒是总能看到那么多人,学这么枯燥的东西津津有味的样子,然后头头是道是品头论足,心中不免有一丝的羡慕,什么时候自己也能那么熟悉并熟练地应用这些设计模式该有多好啊!
  当兴趣渐渐从纯粹的编程语言技巧转移到架构设计、软件工程方面上来时,就有意无意地拿起《重构》《敏捷软件开发》《重构与模式》等书看。这些书有一个比较有趣的特点,就是互相引用,于是,我发现不懂设计模式已成为我前进道路上最大的障碍。我要进步,就必须要清除所有的阻碍,所以我要再次开始学习设计模式。
  仔细考虑一下,为什么之前我每次都会放弃,是因为GoF那书太枯燥抽象了。所以要去找几本通俗易懂的书来先补充一下这方面的不足。《设计模式解析》第二版似乎还算入门级的,从公司图书馆中借到一本,抽空要快速看一遍。看网上的评论,《Head First Design Pattern》更加适合初学和进阶,所以要看看。另外,看到这些书中都提到了Christopher Alexander写的书, 有中文版《建筑的永恒之道》《建筑模式语言》,这是关于建筑学的书,但是软件架构设计就跟建筑学有类似的地方,而且设计模式的起源据说就是从Alexander的研究中开始的,就当开阔眼界也好,也买来看看。
  我并不是想做一个软件架构师,我只是想能轻松地写出结构优美,弹性十足,易于维护的程序来。

2008-05-13

居然还有人想试用这东西

  今天有个项目部的主管来找我,问我那流程平台工程做得怎么样了,他们部门目前新员工多,觉得这个工具或许可以解决当前的问题。我比较诧异啊,居然还有人想试用这东西,说实话现在这边的状况是,尽量快点甩手,从此解脱。我早就不胜其烦,厌倦了没完没了在上面投入。那位主管说得很有理,说这东西做好了很有价值。这个我当然也知道,如果做好了,当然有价值,关键是上头的决心有多大,愿意投入的成本有多少。一直就是我一个人在折腾,一个人折腾么,给我足够的权力和资源也好,偏偏也没有,要指手划脚地作些不合适的决定。
  今天我突然想到,要是早知道会拖到5月底这么久,早期的设计就可以做得好一点,2个月有2个月的做法,3个季度有3个季度的做法,唉,这应该可以算是一个失败的案例了。
  回顾检讨一下失败的原因:
1、前期的规划没做好,开始以为时间不足,就迫使强制采取了些不良设计;
2、用户需求一直不明确,以及用户需求实现比较困难;
3、我做为唯一的开发人员,心理上有所抵制,积极性不高;
4、开发编码工作没有计划和任务跟踪;
5、缺少测试支持等额外资源的投入;
6、现在看来,因为其他因素的影响,似乎开发投入人力也不够。
  暂时只想到这几点,不过也很难过了,唉!

2008-05-12

第一次摸车

  晚上去练车了,这是我第一次摸车,比较不习惯,总是记得一头忘记另一头。比如想着踩离合器和刹车的时候,就会忘了摆方向盘,或者又不记得挂档了。
  据说天黑是不能练车的,因为看不到桩。确实,如果没有灯的话,我连边线都看不清,有双夜视的眼睛该多好呀!
  一般说来,习惯成自然,只是平时没有碰车的机会。要流畅熟练地手脚并用,还需要多多练习。
  因为是第一次,所以只是教了下怎么挂档,怎么用离合器控制速度,怎么摆方向盘,怎么前进倒退。除了我,还有另外一个人一起,两个人轮换着控车,大概总共搞了1个小时多一点点吧,不过瘾啊,要攒钱自己买台车才行,呵呵!

2008-05-11

在家烫火锅

  嗯,这个活动在上个月的时候就筹划过了,不过我并没怎么投入,呵呵,都是bobo在那里捣鼓说五一3天假期里可以抽一天出来,然而,bobo组织不力,3号那天上午我迷迷糊糊发了个短信给bobo,最后结果是cancel掉了。
  这次好像是猫猫牵头联系了其他人的,在公司里是一点风声都没有,只是有一天晚上在QQ群里猫猫跟我提了一下,要到我家里来烫火锅,其他时候则是只字不提,联系都没有。
  直到今天上午10点多了,我发了个短信喊猫猫起床,她才给我打电话,说11点在我们小区对面的超市门口见,叫了某某和某某。等我11点10分跑去,也才看到舒蕊一个人在那里等着,这个猫猫越来越不像话了,都没有时间观念啦。又过了一会儿,才见大部队浩浩荡荡从天桥那边走过来,猫猫、江江、bobo、大牛和他媳妇。一共7个人,到超市里买菜,这种感觉还不错。买了盒装的肥牛和羊肉,贡丸、虾丸,还有很多素菜。又买了些碗筷,本来家里是有一些的,不过这次人多了,不够用,所以要再添点。
  买了回家,我就没怎么动手了,只是找出椅子等必需用品,收拾一下东西。这次买得多了一点,后来刘献文也来了,9个人把肉类都吃掉了,素菜却剩下不少。总的说来,我对火锅的味道要求很低,我几乎感觉不出什么好差来,呵呵,所以这次也吃得比较满足,关键是一群同事一起玩,有一份惬意。
  可惜,相机没电了,不然也可以留下点什么留念,一大遗憾啊~

2008-05-09

使用SWIG扩展EXE内嵌入的脚本解释器

  虽然几年前就知道SWIG了,但一直以来都没真正用过,又是一次叶公好龙。
  今天在公司里跟同事偶然谈起项目里嵌入的Ruby解释器的问题,于是回来兴致高涨,决定研究继续研究一下CryptTool遗留下来的问题。
  首先介绍一下CryptTool。这是一个可以使用多种算法计算文本或文件内容的hash值的小工具,最早的原型是几年前还在大学时写的一个计算文件md5的小程序,去年做一体化平台时,有一项内容是要用一个单向散列值来近似唯一地标识一个文件,所以顺便找了一个几种常用的hash算法源代码,包括md2/4/5、SHA1/224/256/384/512、haval3/4/5、CRC、GHash、Gost3/5、RMD128/160/256/320、Adler32、FCS等。回家用MFC写了一个,完成了多种算法计算的功能,当时突然兴起,觉得可以嵌入脚本解释器,实现外部插件扩展。结果只是实现了搜索指定目录下的脚本文件,并添加相应的项到主菜单中,通过菜单项激活脚本执行。连脚本执行都没实现,因为当时贪心,又觉得好玩,打算把Python、Ruby、Lua都嵌入进来,确实都链接进来了,却没有实际的功能。
  再简单介绍一下SWIG。早先,我只知道它是用于嵌入和扩展脚本解释器的,但具体详细的作用却并不清楚。现在,我有了新的认识,SWIG主要作的是扩展脚本解释器时,将C++代码做一层封装,实现自动向脚本解释器注册相关的信息(如函数、变量、模块等等)。说起脚本解释器的扩展,大多数的资料,甚至连SWIG的帮助文档里,都是说的将C++代码编译生成动态链接库,然后官方的脚本解释器会载入该动态链接库,并在解释执行脚本时使用动态链接库中的内容。而我现在的需求,前面已经略有提及,是把我自己的exe程序里嵌入的脚本解释器扩展了,并且我要的是实现该扩展功能的代码是exe的一部分,而不是独立的动态链接库。两年前,用C++ Builder写过一个用于数据处理的小程序,其中就花了不少精力实现了嵌入Python、TCL、Lua,并扩展了几个函数,当时全部都是通过手工编写代码,按照标准的官方推荐通用作法实现,以至于连续近2个月几乎每天都是后半夜2点才睡,到后来精疲力竭,连上WC掀马桶盖都觉得异常吃力。
  现在用VC实现嵌入和扩展理论上应该也不会有多少差别,只不过扩展部分是用SWIG完成的。先写一个后缀为.i的文件,定义扩展的模块名和扩展的函数原型,如果有变量也写上。然后在命令行中运行SWIG,用法行简单,命令行参数也很简单,因为是放在MFC工程中,所以理所当然地把输出限定为C++类型的代码。这里值得提一下的是,指定输出的文件名,用.h文件比较合适,它里面是一堆函数的实现,但并没有单独的原型声明,所以在实际工程中,只要直接include该文件就行,而不是当成源代码.cpp添加到工程,不然编译会比较麻烦。另外还有一点是,写在.i文件中的变量类型,不要用宏定义,而是用实际的标识法,开始我用LPCSTR和LPSTR分别表示const char *和char *,结果在脚本调用时,就会报类型不匹配,直接写成const char*和char *就没有问题了。再有一点,SWIG生成的代码中,会有一个初始化的函数,该函数完成各个扩展的登记注册功能,在EXE内嵌入脚本解释器后,需要自己调用这个函数。而且从该函数可以看出,Lua的就需要一个lua_State指针,说明Lua是能支持进程内嵌入多个解释器的,而Ruby和Python都是没有参数的,说明一般说来只提倡一个进程内嵌入一个解释器。
  曾经看到有人(似乎是SWIG的作者吧)说,SWIG生成的代码可读性很差,今天我看了看,觉得还可以,需要关心的部分还是能大概猜出一点意思的,而其他的都是辅助性的代码,也就是完成实际的接口转换工作的。除了这个问题,还看到网上有人说过,SWIG实现的粘合层,在效率上会不如直接手工写的那种,今天我看这些生成的代码,觉得此种言论是立不住脚的,因为完成实际接口转换工作的代码都是固定的,应该也是SWIG的开发人员先手工写好的,在效率问题上并不是值得纠缠的。
  用SWIG扩展exe内嵌入的脚本解释器,可以大大减少工作量,降低出错的机率,实在是一种值得推广的工具。比如最近在考虑的,在C++程序中实现一套仿Eclipse的插件机制,使用外部脚本实现程序的业务逻辑,这时用SWIG就可以直接将大量内部核心接口转换成内嵌的脚本解释器可接受的形式,极大地提高工作效率,对于使用COM接口的方案,真的是不太感冒!

2008-05-08

去见疯丫头

  中午离12点还差10分的时候,突然接到疯丫头的电话,叫我拿100块钱去给她。翻出钱包才发现,空空如也,急忙问旁边的同事借了100块钱,又急忙坐电梯到1楼,还以为这样会比走楼梯快一点,再急忙坐穿梭巴士,巴士开得慢悠悠的,我急不可耐地让司机可不可以开快点,不得地看时间,好不容易在6分钟内赶到A10,进了大门看到一着正装的MM站那儿,本还打算上去问一下她101房在哪里,走近一看才发现,这正装MM居然就是疯丫头,哈哈,她也会有穿得这么正式的时候啊!
  差不多有一个月没见过她了吧,跟着她领完东西,刚好就是吃饭时间了,于是去A8吃饭。路上偶然发现,她左边下巴上的那些东西还没抹散,呵呵,这个丫头这一上午走来走去,不知让多少人偷偷笑过了。
  A8的饭菜感觉就是比F2的要好吃,我还是打了两个素菜。一边吃,她还一边给我讲她新岗位上要做的事,现在在客工部实习,下午就要去接待客户。像以前一样,我很快吃完了,看着她吃,互相讲些自己最近的情况。
  吃完饭,慢慢走回来,她就回G1去了。她还说,如果干几个月,觉得不好干,就辞职。我猜,可能还有其他原因吧。唉,人就这样一个一个都走了,我的心就是这样一点一点被敲碎的。

2008-05-07

打算用WTL写个围棋打谱程序

  写个围棋打谱程序,这个想法好多好多年前就有了,上高中的时候就有了。大概是因为当时对围棋有点点感兴趣,纯粹的叶公好龙型的,虽说感兴趣,却没有认真学过,只是知道大致的规则而已。这些年,看StoneBase的发展,觉得挺有趣的,不过它的实现不是我喜欢的方式,所以我突然又决定自己写一个,而且想了想打算用WTL来写。
  开始是有点犹豫用MFC还是WTL的,因为MFC相对较熟悉一点,而且有Xtreme Toolkit Pro可以用,做炫酷的界面确实方便。但是后来想想用WTL就看中它生成的可执行文件体积小巧的优点,看看StoneBase当前最新的4.6.1版本,exe文件也就只有8.24MB,而假如用XTP的话,当是它的dll就有5.5MB,还要加上MFC的dll,大概是3.6MB,这样附属的文件体积就已经超过StoneBase主程序文件大小了。还有一个想法是,希望能借此机会好好学习一下WTL的使用。
  至于要做得什么样的,从特性外部行为上看,可以模仿StoneBaseMultiGo。比如首先要能支持几种国内常见的棋谱文件格式,还要支持棋谱库,MultiGo没有,StoneBase 用了一个叫Absolute Database的嵌入式数据库,我猜大概因为StoneBase是用Delphi开发的缘故吧。我可以用SQLite来替代的,不过StoneBase有一个很庞大的棋谱库,所以也需要能以某种方式读取它的数据库。需要有良好的打印支持功能,肯定很多情况下,需要把棋谱打印出来,对着纸自己敲棋子,那种感观享受不是电脑程序能比的。要有方便的棋谱输入编辑功能,要有格式转换功能等等。
  具体实现上,我想尝试一下纯插件框架,也即用C++实现一组核心的功能,其他高层的业务逻辑全都使用外部脚本扩展实现。这种框架有点像Eclipse,又有点像Mozilla的XUL方案,要扩展的地方包括主菜单、工具栏、弹出式右键菜单、棋谱格式读写等。

2008-05-05

有些问题是看不出来的

  有些问题是看不出来的。
  今天因为有人提了单,我才下决心去看了一下代码,经过比较仔细的排查,最后结论是,果然是被我改坏了,原来的那种实现方式确实是不会出这种问题的,不过那种实现方式是一定不能留的,一定要被改掉的,只能在现在的基础上进行修改,最后好像勉强可以了,哈哈。
  还有一个问题,好久好久了,是以前离职的一个人留下来的东西,交给其他部门人用的工具,现在发现有问题了,原来我看了一下,似乎问题不在工具本身,而在工具调用的底层通信模块上。今天又被人一说,仔细读了一下工具的源代码,再加上和那底层通信模块作者的讨论,最后结果是,确实好像是工具实现得不对。有几行代码一眼看就觉得写得有问题,且不说是否真有问题,首先代码就不应该是那样写的。
  另外是这大半年来我陷入其中的工程,今天写用户手册,当然需要演示截图,结果发现了好几个比较严重的问题。唉,我这大半年的投入产出比还真是低,心里有点难过。争取在剩下的3个星期里,把这些严重问题修正了,完善一下用户手册,就彻底交付了,唉,从开始计划的2个月,到现在都大半年了,真是没完没了,还拖累了绩效,不过似乎就算不搞这个,绩效也不会好到哪里去吧,郁闷!
  最后提件还算好的事吧,小思宇回深圳了,今天还给我打电话,挺高兴地跟我说“我回来了”,大概是因为彭彭回来了吧。不过她那高兴的劲也短暂地感染了我,让我如沐春风啊,哈哈。

2008-05-04

自动升级程序

  今天一时兴起,修改了一会儿自动升级程序。这个自动升级程序半年前就做了,当时用的boost::asio来实现http下载文件,可是问题就在于下载时,CPU占用99%,而且下载速度并不快,这让我很郁闷,在网上也没有找到确实可行的解决方法。后来觉得功能基本可用了,就一直丢在那里不管了。
  前些日子,另一个同事也开始为Impeller做了一个自动升级程序。那个程序的实现我不喜欢,它在升级时没有一个可见的需要升级的文件列表,进度条也只有一个总的,总之至少从界面上看,是个很土的程序。不过它除了能升级本地应用程序的必要文件外,还能进行Gems包的升级。另外,似乎它还可以在文件被替换的前后,执行一些额外的操作,比如一个COM组件可能需要注册,这时这个功能就很有价值了。不过,有时候我又觉得,有必要那么复杂吗,它还想内嵌一个Ruby解释器,能执行Ruby脚本,晕死!
  在我心中,一个比较理想的升级程序应该是这样的:
1、每次都是从一个指定的地方获取一个文件列表,文件列表中记录了可升级的文件的相关信息,如文件名、相对路径、大小、hash值、日期、版本号等,每次都是将本地的文件跟文件列表中的信息进行比较,才得出是否需要升级的决定;
2、一般下载文件都是通过http的方式(比较简单)实现,这样可以实现多线程及断点续传;
3、下载时,有针对当前下载文件的进度以及所有文件的总进度;
4、允许用户中断升级过程;
5、能自动替换文件,包括被打开的文件;
6、能最小化到托盘图标;
7、能通过配置就可以直接适应其他升级需求(配置可以放在文件中、注册表中,或直接通过命令行得到);
8、在替换文件前后,可以执行简单的命令行,不需要执行什么脚本程序那么复杂;
9、升级程序自身文件体积应该比较小;
10、有良好的出错保护机制;
11、可自动生成第一步需要的文件列表;
12、支持子目录中的文件升级。
  暂时就只想到这些,呵呵,抽空用WTL写一个。

2008-04-30

继续读《重构》

  《重构》中文版一直都放在公司电脑前,随时读上几页。有时不觉会为其中的精妙之处深深折服,大呼过瘾。看着一种一种的重构手法,该手法的使用场景,不时会有深有同感的感叹。
  有些情况下,自己写的代码,写着写着,自己都觉得很不爽,但不知道问题出在哪里,功能是可以实现,但总会觉得不舒服,又不知道如何改进。在读《重构》时,就很可能能遇到甚至一模一样的所谓bad smell。
  今天偶然跟同事谈起,我已经不再喜欢看跟语言相关的书了,同事就略带玩笑的语气说,这是架构师才会做的事。确实,我已经不再满足于那种与特定语言相关的奇技淫巧了,我更关心的是如何写出更少bug,更多弹性,更易理解,更好维护的代码。
  但是在读这些书的过程中,我还深深地体会到熟练掌握并运行设计模式的重要性。现在的我,对设计模式几乎一无所知,能产出的代码也是最简单的过程化结构,往往能在最早期的时候快速写出一些代码,但后续的维护和扩展却越来越困难。从读《重构》一书中,体会到,也许只有设计模式,才能解决我目前所遇到的这些问题。不然,即使能看出问题所在,但不能运用正确的解决方法,依然是毫无用处。

2008-04-29

对那东西很失望

  今天考评,结果还是不出我所料,有点麻木地失望。不过这失望不是本篇blog的主题,这里要谈的是目前项目组里的重头项目,那个已经历了超过一年半开发的IDE。
  这东西说要重构,我也已经开了个头,现在的情况是,老大说要在VSS上建分支。可是很明显的是,VSS根本就不支持这样的开发方式。这样就会引入一种新的问题,模拟分支,就有两份明显独立的拷贝,如果进行同步。修正问题在原有代码的基础上进行,重构则在新的一份拷贝上进行,以后合并代码对于现在的几个人来说,估计是个挑战,但我猜更多可能的直接是个灾难。
  其次是架构和代码实现。现有的架构方式已经寸步难行了,但还是要在那个基础上继续进行。现在我是切实地体会到,编码产量高的,一点都不稀奇,相对来说架构设计则真的重要得多。一个文件,一个类实现,用C++代码实现,居然有18000行,这样的实现,功能确实做出来了,但后续的工作却举步维艰。一点小的修改,一点小特性的增加,都会牵扯到很多地方,可能引发很多问题。模块间的交互耦合,都没有经过良好的设计,都是觉得怎么容易实现,就怎么写,结果一堆一堆的重复代码,一个个超大的文件超大的类。
  再次是加入特性没有经过认真评估,加入了一些完全不实用,花里胡哨的东西,而真正有用的功能并没有加入或增强、完善。比如about对话框,居然是一个视频文件,直接调用MCI接口播放实现。视频的周围则是一张背景图,背景图上的文字都是在图形处理程序中固定写死的,这样在以后每次显示信息修改的情况下,凭空增加了图片维护的工作量了。另一个是状态栏上的动态新闻,嵌入IE直接显示远程服务器上的内容,程序内部截获打开链接操作。大概是实现方式有问题,如果远程服务器宕掉了,则在程序启动时试图连接时,花费好几秒时间在那里阻塞等待。诸多问题,恕不一一列举。
  最后是没有好好利用持续集成。虽然装了个CruiseControl,却只是为了实现点个按钮进行编译,连“持续编译”都算不上。一方面,没有实现“持续”,都是在需要时,手动点击一个按钮,进行force building;另一方面,只有编译,没有其他行为,比如代码度量、单元测试、打包发布等等,完全是个空架子。
  其实回头看看这些问题,我觉得都是管理上的问题,单纯从管理层的角度出发,就能解决绝大多数。
  总之,我对那东西很失望,因为管理者如果没有意识到问题根源,将在以后的很长很长一段时间一直存在,并继续恶化。而我能做的,大概就是假如有机会,把编辑器部分做完善点,在我能顾及到的范围内,实现一个类似Eclipse的扩展机制,仅此而已。因为今天听说,有人对编辑器评价很高,有人甚至就因为这个功能,就想把这东西拿到家里去用,这是我唯一的动力了。

理论考pass了

  今天去理论考了,考前还是有点担心的,因为感觉准备不充分,本来打算上周日好好看看书的,结果经不住诱惑去看小说了,还看得天昏地暗的。昨天晚上看完一遍,今天早起又开始从头开始看,在公司里也看了一上午,一直到11点半,才跟江江一起出去。先去四季花城,吃了顿快餐,凉拌的牛肉做菜,味道还不错。吃完看时间还早,便又在花城里面的椅子上坐着看书,有点大学里的感觉,平时不努力学习,到考试前夕就着急抱佛脚。
  然后去花城门口等,等了一会儿接送车来了。在上面随着车的颠簸,有微微开始有点困意,确实本来这几天就因为看小说而睡得不多,加上一直来这个时候就是午睡时间,困是应该的。看江江也是眼睛一闭一闭的,呵呵。
  一觉醒来,发现已经到车管所了,醒得还真是时候。上楼,签名,验指纹,排队等候。这是一个exam pool,一个人考完出来,交了座位牌,外面等的一个人才能拿着座位牌进考场。江江进去没几分钟,我也进去了,不过我不知道江江坐哪里。我拿着1号的牌,略带紧张。
  每个座位左上方都有一个监控摄像头,座位之间都有挡板分隔。没有键盘,只有一个显示器和一个鼠标。我飞快地答完题,虽然还是有几题拿不准,不过我猜应该能pass吧,1分1题,最多允许错10题呢,拿不准的大概也是10题左右,再怎么也是有蒙对的吧。结果第1次交卷还太早,一定要开考后15分钟才能交,于是又把选择题看了一遍,再提交,有点紧张,94分,万幸,呵呵。
  拿了成绩单,走下楼,江江还没出来,于是等了一会儿。江江出来时看到我还有点奇怪,说没听到我的名字,呵呵,她考了96,果然比我好呀!
  到接送车的地方,开车的司机说要等到3点半,看看时间还2点半都不到,于是我和江江决定去外面自己找车走。刚走出,就遇到一帅哥问我们是否一路,于是又找了一美女,4人在路口等了好一会儿才拦到一辆红的,真的是,太少的士了。一直到公司,我拿了35块钱出来。
  爽啊,就等上车了。

2008-04-26

我也TDD了

  TDD,即所谓的测试驱动开发,哈哈,我也开始用了。项目负责人花了两天时间总算建起一个可以正常跑起来的CppUnit工程,经过另外一个同事的验证,确实也能加入测试用例来跑。于是我兴高采烈地加入几个正儿八经的测试用例,结果发现用例是跑起来了没错,可是当从VC中想直接check in源代码到VSS中去时,VC就不干了,说两个工程不在同一个起始目录下。因为正式的功能代码是直接从原来的工程那里引用过来的,而偏偏测试工程是放在平行的目录下,因此有了这样的问题。万般无奈之下,只好亲自动手,把测试工程也移入正式工程的目录下,修改一下路径包含,一切OK,check in也没问题了。
  几乎所有看得到的讲到TDD的书、资料上都说,在写功能代码前,要先写好测试用例。但是我发现直接这样做还是比较困难的,我现在的做法基本上是先想好,会有哪些功能类,然后就写好对应的测试类,再写好功能类中的成员函数声明,并用Visual Assist X生成一个空的函数实现,再跑到测试类中添加对应的测试函数,这样测试工程应该还是能跑起来。接着,我基本没按书上说的那样按部就班先写好测试函数内容再写功能函数内容,而是两边来回切换,一边写一点切换到另外一边再写一点,来回倒几次后,也基本都完成了。我不知道我这样做有没有什么不好的地方,反正用CppUnit这样做,进行单元测试确实方便,对于一些算法性的函数实现,直接在功能实现工程中往往不好测试,而放在CppUnit的测试工程里,则是再合适不过了。比如今天从别处抠来一段用WinINet进行Http下载的代码,略作修改,放在测试工程里测试,太方便了。
  另外还有点体会是,设计模式是一定要学的,但总觉得GoF的《设计模式》看得太乏味,太枯燥,太艰苦了。Bob大叔的《敏捷软件开发》,Martin Fowler的《重构》都是要认真看的,还有《重构与模式》、《修改代码的艺术》、《反模式》都要好好看一下。提升个人能力,这些是必经之路。

2008-04-25

从扩展编辑器开始

  重构auto completion和call tips模块,因为总体设计都被改得天翻地覆,而且决定开始使用TDD的方式进行,所以进度相对来说慢了些,更因为我自己一直静不下心来好好干活,真是令人烦恼啊!
  话说其他一些相对可独立分类的小特性大部分已被我清理出来,但剩下还有一些杂七杂八的功能,我却不想再动了,因为从很早的时候就考虑好了这部分功能不应该由C++代码完成,而应该由host提供的扩展机制使用外部extension实现。但是现在的情况看来,这扩展机制短期内是不会加入的,因为老大似乎不支持这样的做法。另外一点是,组内大概除了我,也再没有其他人有足够深厚的兴趣和迫切的需求实现这么一个框架。
  最早虽然想到了要用扩展,但并没有考虑很多,只是觉得只要能用内部嵌入的那个Ruby解释器执行一段脚本,而那个解释器同时也能访问到内部的一些数据结构和算法,应该就能处理目前的需求了。当时预见得到的需求也确实简单,比如点击一个菜单项,在当前光标位置插入一个字符串,该字符串可能是当前日期或时间等等。我当时想法相当单纯,甚至想的是菜单项还是依旧在资源管理器中画好,消息映射也还是添加好,最后实现的时候再调用Ruby解释器解释一个外部的脚本文件就可以了。即使这样简单,也比纯粹使用C++实现有一定的优势,至少如果需要修改实现逻辑,就只需要修改那个脚本文件,不再需要修改C++代码,不需要重新编译。
  但是自从前几天快速翻看了一遍《Contributing to Eclipse》之后,我就想,要做就做得灵活点,也许不要求完全跟Eclipse一样那么强大有弹性,但也至少要满足以下几个要求:
1、在主菜单、弹出式菜单、工具栏(、状态栏)上都可以扩展;
2、在扩展之上还可以预留扩展点继续扩展;
3、既然用脚本扩展,那么扩展加载应该也像Eclipse那样“懒加载”;
4、需要有一种打包策略,足以支持起复杂的多文件的扩展。
  暂时就只想到这些,嗯!重构完auto completion和call tips,就悄悄做这个。

2008-04-24

讨教Plugins设计

  下午去向人讨教了一下人家怎么设计实现Plugins机制的。据该人士讲述,当时他们的产品2.x版本面对各种千奇百怪的用户需求,以及进度压力(这与我们目前遭遇到的情况类似),经过研究COM相关技术和Eclipse(估计当时也是2.x版本)的Plugins机制,最后在3.0版本实现了目前(也是3.x吧)的Plugins机制。
  首先,该软件产品一般的插件都是通过vbs脚本实现,他们内嵌了vbs脚本解释器,使用的当然是最流行最正规的IActiveScript之道。可以扩展的地方包括主菜单、工具栏、弹出式菜单、状态栏等。像Eclipse及其他很多软件一样,基本的界面元素是用XML描述的,以弹出式菜单为例,在XML中首先会定义视图之类的信息,而弹出式菜单是作为视图信息的子节点出现的,说明这个弹出式菜单是在视图上点击右键才会弹出。这里好像是XML里就直接指定了菜单项的ID,对应Windows程序里的命令ID,而ID范围是程序中已固化规定好的,不能超出这个范围。然后指定一个脚本文件,可能还会具体到其中某个函数,每当菜单项触发时,便调用这段脚本。可能还会有触发前、触发后的选项,可以继续使用自定义脚本扩展实现。另外,菜单项有一个状态,如disabled、checked等等,这是在另外一个属性中设置的,该属性同样是指定一个脚本文件或函数,刚好对应MFC中的ON_UPDATE_COMMAND_UI。还有一点是,菜单可能是针对某种具体的选中项才有项的,所以在XML中描述菜单时,可能会包含一个属性,用于指定对其有效的选中项类型,只有在该类型的界面元素被选中并在上面点击鼠标右键时,才会弹出这个菜单。再有就是菜单等界面元素不可避免的一个问题是国际化,他们是把各种语言对应的字符串信息分别写到不同的配置文件中,描述菜单信息的XML里通过指定个别名或ID来动态查找装入相应的字符串。如果激活扩展插件函数时,需要一些固有信息,而是通过规定的格式书写函数参数。
  其次,除了支持脚本扩展,该软件还支持COM组件形式的Plugins,这种Plugins相比脚本Plugins肯定强大得多,也许就好比Firefox中的Plugins之于Extensions,不过在介绍时他们一带而过,似乎也不是很支持第三方的去使用这种机制。
  最后说一点,为了实现能让vbs脚本访问host程序中的一些信息或方法,他们把所有的东西都用COM接口还实现。似乎这是目前而言,我们能找到的最简单的一种处理方式,所有的状态、中间数据信息都可以保存在host程序中,脚本应该只是描述逻辑,而不保存状态。但这也是我最不屑的,我还是比较欣赏Eclipse(3.0以后用OSGi的不知道有多少变化)的机制,希望我有机会能设计并把它实现!

2008-04-23

继续整理代码

  今天又整理了一下代码,又把初始化部分移出来了,居然相关的代码超过1100行,也算是神奇了。现在主要是把相对独立的功能剥离出来,所以并没有仔细地考究里面的代码细节是否写得完美。而且,总感觉现在的结构还不是我理想中的那种样子,但到底做成什么样,我自己也不知道,我想不明白怎么做才能做好。
  另外在看代码的过程中,发现其中有一些是重新发明轮子了,其实有直接简单的实现,却因为对系统的不了解,而自己实现了一把,如果不考虑性能等方面的因素,只是关心代码的整洁清晰的话,当然不要自己的实现了。
  还是要去整那一体化平台,心里总有种抵制的感觉。想去做图形编辑,想实现一个足够灵活的插件框架,唉!

2008-04-22

整理了一下思路

  今天又没动手,人越来越懒了啊!总是在想,既然功能基本正常,就不要去动它了。就像Martin Fowler在书中说的一样。感觉有心无力,唉,心中有那么一点畏惧和抵制。
  不过后来花了点时间,在纸上乱画,针对自动联想功能,清理了一下设计思路。现在的实现真的是很C风格化,所有的代码都是揉合在一个类中,所以相关的功能都在这个类里实现。重构时,希望尽量向OO的方向靠拢,那些设计准则,也要尽量地遵守。
  从现存的代码看,自动联想从表现上看,可以分为3类,分别是Auto Completion、Call Tips、Code Snippet。其中Auto Completion是通过已输入的几个字符,根据上下文环境,给出候选的可能匹配的完整token,Call Tips则是在当输入函数调用的实参时,以tooltip的形式给出函数原型以提示,而Code Snippet则是在用户触发了事先绑定的事件时,根据已输入的字符,或者也可称为命令符,自动以代码片段替换该代表命令的字符串。总之这3种特性都是为了减轻编码者记忆负担,减少键盘敲击次数,降低出错概率。
  当前的实现是当打开一个文件时,或者截获到换行操作时,进行扫描,记录当前文件及其相关包含的变量和常量的定义,除了名称,还需要类型。这样在输入变量时,可以根据名称进行提示,输入方法时,根据类型可以从数据库是查询到相关方法。所以扫描是为了Auto Completion和Call Tips作准备,Code Snippet不需要这些。
  当初实现这些特性时,只考虑到了Ruby语言,所以紧紧围绕着Ruby这个主题开展,代码几乎没留下任何一丝空间以供后续扩展。不过既然这次要重构,无论从设计角度,对象职责上看,或是以后要添加扩展新语言支持,都需要把这块代码剥离出来。一个重要的原则是,剥离出来部分不能再跟界面有耦合了,不然单元测试几乎不能做了。
  界面部分还是全都放在控件类中,控件类调用Auto Completion、Call Tips实现类获取待显示的内容,实现类应该从统一从一个抽象类继承,每个实现类可以对应一种(或一类)语法。这里需要引入一个工厂类。原来的助手类应该拆分成两部分,即代码扫描分析部分和信息存储查询部分。其中代码扫描部分也有一个抽象基类,从它派生出对应各种语法的具体实现类,把扫描分析的结果存储到信息存储部分,同时,信息查询部分从信息存储部分获取内容,信息存储部分的数据一部分来自于扫描分析部分,另一部分来自于固有持久化层,可能是一个数据库,可能是一个文件文件,可能是一种外部输入数据结构。这样,任何一部分的变化,都会尽可能少地影响其他部分的实现,而且这些实现除了界面相关部分,其他的应该都比较容易做单元测试,自我感觉设计得不错,只是可能工作量大了不少,很容易让人产生放弃的念头,呵呵!