Google
 
Showing posts with label Software. Show all posts
Showing posts with label Software. Show all posts

2009-10-19

ISTool区别大了

  今天在安装程序中添加了2个网页快捷方式,因为用的是ISTool编辑的,所以就直接用它来编译了,结果试了几次,都发现没正确添加上快捷方式,连原来应该有的其他的快捷方式都没有了,甚至发现我本来让它在所有文件复制完后,应该有个选项可以让用户选择是否运行程序的,连选项都没有了。
  真是奇怪的问题,于是在CruiseControl的历史记录中翻出最近的历史,发现还是正确的。想到这个安装脚本的区别基本没有,主要在于使用的是不同的编译工具。于是用命令行ISCC.exe编译了一下,居然是正确的!
  这ISTool原来还是自己做了一套编译功能的说?

2009-10-14

封得越来越死了

  前些天才知道,tor也是会被封的,要用tor bridge才行,至于bridge的ip从哪来,网上到处有说,也就是给某邮箱发个邮件索取来的。
  这两天发现,这些bridges也是时好时坏的,于是笨办法是不停地索取新的bridges来用,今天发现得到的ip有的是之前得到过的,也就是说可能是不好用的,只能试试之前没用过了。
  唉,封得越来越死了,无语!

2009-10-12

被LaTeX折腾了

  昨天一时好奇,从网上下载了CTeX 2.8 Beta1来,安装好后,尝试着编译原来的一个纯英文的文档和一个Beamer做的幻灯片,结果发现全都有问题。首先是编译速度非常非常慢,CPU占满。然后是原来用grphicx的地方,直接插入png的语句编译不过。最后是发现Beamer包的应用和bibtex联用的地方,最后一次pdflatex编译时,编译不过。
  速度慢倒暂时也忍了。至于插入png的语句编译不过,通过网上找到的资料,下载了个ImageMagick,里面有个convert.exe,可以将png转换成eps,而实际上这eps也只有在普通文档中是可用的,在Beamer中仍然要用png,这是让人很郁闷的地方,几方处理方式不一致,是让写程序的人很头疼的事。
  好吧,这些都是可以放一边的。最最关键的是,那个幻灯片编译不过呀!如果不编译最后一次,那参考文献就不行了。于是继续上网找办法,发现一会儿工夫有了CTeX 2.8 Beta2,嗯,实际上我是很有心理准备的,这么一个小Beta号的变更,是不会有大变动的,但仍然不死心地尝试了一下,果然不出所料还是不行的。于是在CTeX的网站上看到正式发布的2.7.1.42版本CTeX,仍然不行。期间还试过有个CTeXLive2008的集成包,呃,也是不行的!
  我相当的郁闷!于是上CTeX的论坛上发帖求助,直到今天有个管理员给了个2.4的CTeX下载路径,才算最终搞定!对于这种不了解的东西,不能随便升级了,要升级前也得对能正常工作的旧版本做好备份工作,以便及时回滚啊!
  昨天差不多搞了整整一天,幸亏现在网速快了,不然还得花更多的时间呢。被LaTeX折腾了,教训啊!

2009-09-22

图形程序设计续之自动调整连接点

  本来计划是明天才开始做这个功能的,不过因为着急着要尽快走流程办手续,只好把这最主要的任务尽早实现了。
  总的说来,基本算法是完成了,不过还是有些小bug。大体的算法是这样的:三类连接线,包括折线,样本曲线和贝塞尔曲线,其中两种曲线要都Flatten一下,最后变成一组前后相连的线段,然后将这组线段分别与矩形的4条边计算交点,把离交点最近的跟踪点作为新的连接线的一个端点。
  这里要注意的是计算交点的顺序问题。也就是说,如果是从连在矩形上的端点开始遍历那组线段来计算交点,那么应该以最后一次的交点作为最终结果。而如果是从另一个端点开始遍历计算交点,那么应该以第一次的交点作为最终结果。
  其次是中间点的调整。像折线,一个比较简单的做法,把交点与端点间的所有连接点都删掉就可以了。而样本曲线则应该调整中间的切点位置,贝塞尔曲线则是调整两个控制点的位置,以免新生成的曲线因为中间那些点的牵引而仍然横穿矩形。

2009-09-21

图形程序设计续之添加子对象

  今天大概花了两个小时吧,加了右键菜单添加子对象的功能。这个功能的实现,有几个部分需要关注。
  首先是图形绘制部分。这是需要修改最少的部分,因为之前的工作已经实现了子图,子对象就是在子图中添加的对象,只需要在相应的响应函数中实现添加子图,在对应的图中添加对象即可。
  其次是右键菜单动态生成。这部分也不是很麻烦,只要识别出当前点击位置是什么图形,该图形在业务意义上可以拥有哪些子对象,就可以拼装出一个完整的右键菜单。
  最后是花了不少精神的配置信息读取部分。本来配置信息都是从配置文件中读取的,因为并没有对配置文件与配置项的对应关系做严格的限制,所以原先的设计中,把配置项的信息基本上都是做成实时读取的,今天又要拿来用一次,就显得原来的设计似乎不是很方便。不过我还是没做更多的改进,仍然沿用原来的做法,实时读取某个对象可以拥有的子对象的类型信息和其他描述信息,以便于添加到右键菜单和后面的创建子对象 。
  今天的任务基本完成。数了一下代码量,这个项目总共才4.7Kloc,挺少的,很出乎我自己的意料之外。这么算来,假设我在这个项目中已经投入20天,那么有效产量大约是230行每天,比自己订的目的500行每天少了一半多啊!

2009-09-19

图形程序设计续之子图

  这次的需求中提到,能为一个图形关联一个子图,用该子图来描述该图形的内部结构信息。展现给用户的语意是,当双击一个图形时,则展示该图形关联的子图。
  今天投入去实现该特性,基本没有遇到什么阻碍,因为原来的架构设计可以满足这个需要。当初把用户界面视图绘画层,图形管理器,图形对象三部分独立开来实现,所有用户操作都从视图绘画层接受,将操作信息传递给图形管理器,再由图形管理器转发给各个图形对象进行响应。在那之后,我曾经考虑过,这么做是不是有点儿过度设计,这个图形管理器的操作响应转发功能是不是多余的。现在却发现,这样的实现才刚刚好,一个子图,对应一个图形管理器,视图绘画层要始终跟踪当前起作用的图形管理器对象,任何时刻都只跟一个图形管理器进行交互。这样,没花费多少力气,只是增加了创建图形管理器,维护图形对象与图形管理器的对应关系以及销毁图形对象和图形管理器的功能,就可以实现子图功能了。
  在实现这个功能时,有一个小心得,及早加入dump文件捕获功能很有用的,因为即使是开发阶段,也不是每次都在调试器中运行,所以当在自测试时偶然出现的崩溃现象,可以及早通过dump文件进行定位,而且因为是Debug版本,所以通过dump文件分析出的结果往往比较精准和明确。
  除此之外,还发现一个以前没想到的现象,原来MFC中,CDocument类的OnCloseDocument方法,居然会销毁自己,及其派生类对象,如果要做些扫尾功能,放在派生类的OnCloseDocument方法中时,一定要把调用CDocument的OnCloseDocument方法放在最后。

2009-08-29

Byebye,C++Builder!

  昨天熬到快后半夜,从Embarcadero官网上把Delphi/C++Builder 2010的ISO安装镜像下载了下来,并从网上找了个一年试用的license,装好了来体验一把。
  在4年的大学本科生活中,可算得上用了3年半的C++Builder,在毕业后从事测试工作的那近2年的时间里,也断断续续地用着,所以总以为自己对C++Builder的感情可能是不容易割舍的。但是经过昨天晚上和今天晚上短暂的试用后,嗯,只是把一个C++Builder2007的工程转换为C++Builder2010,编译有不少通不过的。我放弃了,我想说:Byebye,C++Builder!编译不过的地方,我看了一下,都是因为Unicode这个编译选项引起的,我粗略地找了一遍工程设置,似乎没有可以修改这个选项的。说实话,我感觉最好的版本是C++Builder6,后面跟Delphi合并使用一个IDE后的版本,差不多每个大版本都装过,但都没有让我继续用下去的念头。
  出2009时,我曾自己安慰自己,彻底放弃它了,这回有了2010,还是忍不住弄来装了装,真的彻底放弃了,没有一点亮点!一款C++开发工具,我关注的是三方面:IDE、编译器、类库(框架)。曾经在BCB6.0和VC6.0的年代,这三方面BCB都是占据优势的,可是这之后的7、8年来,VC在大幅进步,而BCB却是裹足不前,VC现在都已经精进到几乎没事可做的地步了!
  就让它,活在回忆中好了!

2009-08-28

图形程序设计续之零碎问题

  图形编辑功能已经做了两周了,到现在为止,也只能画出矩形框,在矩形框之间用白线、样本曲线,或贝塞尔曲线进行连接。又一次发现,只有在编码实现的时候,才会遇到很多之前没有想到的各种问题,而且有些问题要解决,也是要花费不少功夫的。
  要考虑图层的问题,如何定义每个图形所在的图层,在绘制时,才得比较方便快速,而且需要可以随时修改图形所在的图层。图层的影响是多方面的,例如在绘制整张画布及图形对象时,要从底层开始绘制,而对于在某个点上点击选中一个图形对象时,却要从上到下进行遍历查找。
  还考虑随时可以修改画布的大小,因为在添加图形,或修改图形位置时,是随时都可能把图形放在一个走出当前画布大小的位置上的,这时程序应该可以自动检测出需要扩大多少。对于向右、向下方向的扩大处理很方便,直接将画布大小重新定义即可。而对于向左、向上方向的扩展,则除了重新定义画布大小外,还得把超出部分归整到(0,0)这个坐标上,也就是说,要把所有已存在的图形对象的位置都调整一遍。
  再要考虑子图的问题。也就是说,一张完整的图片,在某一时刻,只是显示了其中一部分图形对象,这部分当前被显示的可以作为一个子图来对象,而没有被显示,则是属于其他的子图。每个子图之间应该没有多少强相关的关系,最多是一个图形,与一个子图可以有包含(从属)关系,一个子图用来解释一个图形。常见的一种应用场景就是,双击了某个图形,就展示另外一张图片。这就同样要求设计一种灵活高效的数据结构来保存这些信息。
  从当前的实现情况看,每个图形对象中,都有不少成员变量,保存了一些中间数据,这些中间数据不属于图形对象的本质属性,却对于图形在特定时刻进行动作起着重要作用,从代码美观角度讲,感觉很冗余,所以要考虑如何优化,减少这种成员变量。例如对于一些状态变量,或许可以用位域的标识。

2009-08-25

图形程序设计续之困扰

  开始做那个图形编辑程序1周多了,现在遇到了瓶颈,因为原来的设计考虑得太不全面,很多很明显的问题都没有有顾及到,结果到实际编码实现到一定程度时,发现原来的程序结构有点不行了,不够用了。
  主要的矛盾在于,原本我的设计上是,每种图形,都各自响应用户操作,互相不知道其他同类的存在。而实际上这是不对的,或者说不合适的,比如连接线,在端点确定前就是要知道那个位置是否贴到某个图形上了。另一方面,当某个图形上的连接点移动时,同样得通知所有跟这连接点连着的连接线,或者是某个图形被删除时,得同时删除连接在它上面的所有连接线。
  本来所有图形对象都在一个管理器进行任务分派,现在看来,至少有得有一个类,可能还是这个图形对象管理器,做更多的事情,可以查询它所管理的图形对象一些特殊的状态,还要维护图形对象间的关系,可以是一个邻接矩阵,或一个邻接链表,反正就是一个图的表示法。这些不是我现在的主要困扰,我的困扰在于,图形对象怎么来调用这些查询状态的操作。本来图形对象被那个管理器对象包含了,另一方面那些查询状态的操作得知道所有这些对象,这样的循环依赖,让我感觉不爽!

2009-08-23

有点必要学习SQL

  话说,我并不是计算机科班出身,因此很多基础的知识都是不知道的。这不,发现SQL真是有必要要好好学习一下了。最近在很多地方用到了数据库来存储东西,于是不可避免地需要写些SQL,最最基本的SELECT、INSERT、UPDATE还是会点的,不过也仅限于在单表中进行操作。
  前两天发现一个可以显著提高在Sqlite3中SELECT性能的方法,那就是建索引。因为IDE需要AutoCompletion和Calltip功能,而用于这两个功能的数据都是存在一个sqlite3数据库中,该数据库目前已经有不少数据了,光是一张记录了方法的表,就有1万多条记录,从中SELECT是经常要做的操作,所以能提高点性能是很有意义的事。自从给该表建了索引后,至少感觉上非常明显,AutoCompletion几乎没有任何停顿就提示出来了,而以前的话,有个明显的停顿,虽然这个停顿的时间并不长,但已经能让人感觉出来了。这只是一点,让我觉得学习一下SQL有好处的地方,就让我尝到了莫大的甜头。还有一点就是,有不少地方的SELECT的条件,是从这次其他的SELECT中取得的数据,而我全部都是分成一条SELECT一次操作来进行的,我想,如果能把这些SELECT合并成一条语句,应该还是能再提高点运行速度吧。

2009-08-10

原来一直都理解错了

  嗯,一直以来都以为UTF-8和Unicode是一类的,今天才明白过来,UTF-8确实明明是多字节一类的才对啊,我的理解能力实在是太差了,唉!
  不过今天倒是也知道了,如果只是要在ANSI、Unicode、UTF-8之间进行转换,使用两个Win32 API就可以全部搞定了,不需要用什么iconv和ICU了。总是觉得微软做的东西易用性真的很好,通用软件产品很适合普通用户使用,而那些开发工具、库、API对于开发者来说,也很好用啊!
  唉,我也就只用玩一下这些容易的东西了。

2009-07-27

发现一个问题

  看《Windows高级调试》猛然发现一个问题,书中的例子都是对exe进行调试的,而且几乎都是知道问题重现步骤的。这跟我现在的情况可差得很远了,我只有一个core dump文件,不知道问题出现时的操作。看书上都是一直操作,直到问题出现,然后在调试器中断下来,查看寄存器,堆栈,句柄等信息,再抽丝剥茧一点点推测出问题的根本原因。我不行啊,我在源代码中加入了一个自定义的UnhandledExceptionHandler,在问题出现后,就转到那里去执行了,连最后现场都被破坏了的!
  晕!

2009-07-18

看到Chrome的可执行代码差分算法

  无意中在一个讨论组中看到Chrome的新differential算法Courgette(http://dev.chromium.org/developers/design-documents/software-updates-courgette)的讨论,其中提到一个Develper Channel从190.1到190.4的升级例子:完整升级包:10,385,920字节,一般bsdiff算法:704,512字节,而Courgette算法:78,848字节,近十倍的空间效率提升啊!真是太恐怖了,直到今天我才知道,原来对于二进制补丁,也是有这种优化算法的,汗啊!http://neugierig.org/software/chromium/notes/2009/05/courgette.html 这篇文章也对这个算法进行了介绍。大体上,Courgette算法目前是基于x86体系的,适用于exe、dll等可执行文件补丁,它会将这些新旧版本二进制码进行反汇编,在反汇编的基础上进行比较,据说是将二进制文件中所有的internal pointer/reference的地址重新符号化, 然后再计算differential,得到补丁。
  另外一个博客中也有一篇讲优化二进制补丁算法的,http://blog.csdn.net/housisong/archive/2006/04/11/658863.aspx。
  由此我想到我们现在的自动升级程序,都是完整文件下载替换的,土了啊!

2009-06-03

史上最难用Win32 API

  啊,非SHFileOperation莫属!今天要实现个文件夹复制的特性,于是就想到这个API,可是很不幸,无论我怎么整,都报个1026错误!从网上找了一圈,发现代码根本一模一样的,人品问题啊!
  后来在花费了不知道多少时间后,也许是1小时,也许更多,等不及了,花了10分钟自己用递归写了个函数来实现文件夹复制,我吐血三升!

2009-05-30

提高软件生产力

  提高软件生产力,意味着可以在更短的时间内交付质量更好的软件产品。软件生命周期的各个环节都对此有着极大的影响,而从开发人员的角度讲,有几件事是力所能及的。
  一、提高代码产能。单纯的代码生产力,比如一个开发人员原本一天能写100行代码,经过一段时间的学习和锻炼,相同规模相同难度相同质量的代码,只需要半天就可以完成了。
  二、提高代码质量。这个质量指代狭义的稳定性、鲁棒性,代码bug少。这一方面也是通过学习、锻炼可以获得此类能力和经验,另一方向,引入合适的工程方法,比如TDD等良好的实践,也有一定的效果。
  三、发扬“拿来主义”。现在可以从各种渠道获得并使用的代码片段、函数库、类库、框架、组件、中间件、软件等等不计其数,并不是所有特性和功能都要自己着手开发实现。只要代码功能满足实际需要,质量在可承受的范围内,可维护性也过得去,以及license没问题,就拿来直接用吧。可重用的,不光是代码,还有架构、设计思想等。形式上,无论是源代码复用,还是二进制组件,都可接受,甚至可执行程序也可以。
  四、提高代码复用性。自己写过一遍的代码,尽量不要写第二遍,复用吧!代码重构一种使得代码得以提高复用性的不错的办法。
  五、提高架构可扩展性。为了更快更好地实现后续新增需求,高可扩展性的架构是一个良好的基础。可扩展性的对面是可裁减性,假如有一天突然要求去掉其中的一些特性,这种情况也是存在的。这点对经验的要求和依赖比较高。
  六、提高架构和代码的可修改性。需求发生了变更,或者原本对需求的理解就有问题,或者发现了bug,这些情况都需要对代码进行修改,别因为一个功能上的小改动而引发代码上的大改动。
  七、使用先进的工具、方法和流程。比如眼下流行的敏捷,使开发流程减少僵化。使用优秀的IDE,智能感知、重构、自动代码生成等等。使用版本管理工具,定期对一些代码进行指标度量。
  八、宽松、舒适的环境。环境好,对开发人员的身心都有好处,长期收益极大。
  九、快捷、方便的求助渠道。向人请教是一种很省事的方法,但很可能影响其中一方的状态。上网搜索则是另一条有效途径。
  当眼下软件生产力严重不足的情况下,这是仅剩的几件我能做的事了。

鼠标手势算法

  今天看到一篇文章,讲鼠标手势算法,觉得有点意思。现在不少软件都有了鼠标手势支持,尤其是浏览器,几乎成了高级用户的标准配置了。
  这算法分为4步。
  一、过滤鼠标移动动作。如下图所示,这步过程把一连串的鼠标移动动作中幅度过小的动作过滤掉。这跟系统配置也有点关系,不同的配置下,记录鼠标移动的速率等量纲有所不同。

  二、限制鼠标移动方向。如下图所示,对于简单的鼠标手势支持,只支持上下左右4个方向,就把其他方向的动作都归并到这4个方向中。一般就是比较一下上下方向和左右方向的差值,取大的那个作为最后的方向。

  三、简化移动方向序列。如下图所示,这步非常简单,原本是右右上上右上上的方向序列,简化后变成右上右上了。

  四、匹配和推演。这步是最困难的,表面是把夹杂在长距离移动动作中的短距离动作过滤掉。大概的做法是先把整个动作序列与一组预定义的序列匹配比较,如果匹配失败,就把这序列中最短幅度的动作过滤掉,再进行匹配,如此循环往复,直到最后匹配到为止。

2009-03-16

VC操作Excel生成统计图

  老雷说,画图功能可以让Excel来做,我曾经还抱着试试看的心理在网上找有没有免费的代码可以方便地生成各种柱状图、饼图的,没找到,也实现懒得自己去画了,于是硬着头皮去用Excel了。
  VC的程序操作Excel,而且不光是为了存取数据,所以用COM是最正规最有效最理想的方法。如果是用MFC,可以让IDE自动生成其中的某几个接口的封装类,这样的好处是封装得比较高层,使用起来更方便简单一点。如果直接导入类型库,会生成整个类型库内所有的接口和类型的封装,不过是底层一点,最多是用一下COM智能指针封装的接口,可以少处理一些引用计数的问题。
  先可以录一个宏,查看VBA代码,就基本知道要用哪些接口的哪些方法了,但实际上如果用VC通过COM来操作,会发现跟VBA的结果经常有些出入。这让我有点纳闷。不过今天整了一天,总算勉强完成任务了。

2009-03-12

可以用bjam做点事了

  今天把一个用了wxWidgets、Xerces-C++、luabind的工程用bjam写了个构建脚本,可以用MinGW来编译,也可以用VC来编译,这就是bjam的好处,很少需要关心不同编译器的命令行参数。
  经过这次实践,还发现alternative的选择原来是要跟它的属性完全对应上才行。比如一个目标,写了toolset和variant以及threading,则在命令行中要把这三个全都设置上,不然它就说找不到匹配的目标。这让我有点头痛,假如我只想在命令行上选择toolset,而让其他两个属性固定死,那怎么办。
  不过还算可以了,目前基本能满足实际需求了。

2009-03-11

继续bjam

  bjam编译Windows下的rc文件不用特别指定,就像其他C/C++代码文件一样,直接放个文件名就行了,它能自动认出来,并调用相应的资源编译器来,只不过生成的二进制文件后缀还是跟代码文件编译出来的一样,不过并不影响最后的链接过程。
  对于debug或release下使用不同配置的情况,需要至少每一种情况写一遍目标,同样如果是不同的toolset也这么处理。
  今天把一个使用WTL写的工程用bjam系统编译了一把,果然也不是很麻烦,不过需要写不少特定的参数,bjam的默认配置不够用了,所以这样的情况还是不适合用bjam的。简单地说来,适合用bjam的场合,至少是没有一个好用的IDE的情况下。
  想起直接在bjam里用wx-config来生成的编译选项,居然会出错,因为wx-config的输出后面多了个回车,用make就没影响,而链接选项在bjam中也没影响。没办法,去网上找到wx-config的源代码,只有一个文件,不过有几千行,稍微找了一下输出的代码,把末尾的回车换行去掉,再试了下,果然可以了。

2009-03-10

bjam使用点滴

  要在工程的根目录下放一个Jamroot文件,可以没有扩展名,也可以加.jam为扩展名,这样其他子目录下的可以命名为Jamfile了。
  基本上是个大小写敏感的系统。
  还没找到怎么让它来自己编译Windows的资源文件。
  用path.glob-tree可以指定目录来进行glob-tree,如果光用glob-tree,是只能从当前Jamfile所在目录开始全部搜索的。