行者无疆 始于足下 - 行走,思考,在路上

稀里糊涂的数模比赛

原来数模和acm本不是一个级别的。

数模,三人一队,十天一题。

原本我是学计算机的,谁曾想到那两人matlab倒也丝毫不落下风,因此我只能回到了自己的老本行——LaTeX写文档了。写文档当然要涉及到图表、公式、参考文献等等。因此我顺便进一步熟悉了下Linux环境下绘图工具的使用。

简单的说,绘图工具分为两类,一类是CLI的,另一类是GUI的。两种工具也大体代表了不同的理念,前者是WYTIWYG(What You Think Is What You Get),所思即所得,后者是WYSIWYG(What You See Is What You Get),所见即所得。具体到应用上,前者以\TeX派系为代表,后者以MS Word派系为代表。

我们先说第一类。和\TeX配合的绘图工具,我了解的有四个:

  1. metapost
  2. asymptote
  3. pgf\tikz
  4. pstriks

前两者属于离线做图工具;后两者属于在线做图工具。可能你又会问,什么叫离线做图工具?什么又叫在线做图工具?

简单来说,离线做图就是单独建立文件,然后生成eps等独立的图形文件,通过\includegraphics等类似的命令将图形文件嵌入到latex文件中(这样说也许不妥,因为latex文件经过不同处理可以生成多种类型的文件如dvi、ps、pdf等等,嵌入到latex中意思是“图形”嵌入到生成的文件中)。metapost和asymptote属于这种。

在线做图就是直接在TeX文件中敲相应宏包的绘图命令,经过处理后直接生成图形。pgf\tikz和pstricks属于此类。两种方式并没有优劣之别。离线做图更灵活,在线做图则更加方便。

从历史上来说,metapost和pstricks历史更长久一点,而asymptote和pgf\tikz则相对年轻。

语法上,metapost比较怪异;asymptote的语法仿照c++(可见c++确实是王道^_^);pgf\tikz我用过一段时间,感觉比较乱,毫无章法;pstricks基于postscript,据说比较强大,但是我没用过,不好评价。

能力上,各有所长,metapost可以解方程;asymptote的3d不错;pgf\tikz生成一些特殊的图如自动机、MindMap等效果非常好;pstricks,不知道了。其实我觉得四者精通其一即可“纵横天下”。

这里附上一些Gallery,做图能力强弱,大家自己分明:

  1. metapost: gallery1
  2. asymptote: gallery1
  3. pgf\tikz: gallery1, gallery2
  4. pstrikcs: gallery1, gallery2

上两张图,来猜猜是用什么画出来的。不要告诉我是photoshop、inkscape哦。

 

以上是基于CLI派基于\TeX的绘图工具。除此之外,graphviz也是非常有用的一个小工具。与metapost等重量级的工具相比,graphviz的长处在于轻便灵活。短短几句话可以生成多种格式的文件。他自创了一种dot language,并且自动提供了几种layout算法。graphviz尤其适合画流程图和类图,可以看看它的gallery。著名的源码文档工具doxygen生成类图时调用的就是graphviz。而且graphviz还提供了python语言的调用接口pygraphviz

提到这里,也就不能不提到emacs了。说emacs是神的编辑器,此言一点也不为过。gentoo:

sudo emerge -av graphviz-dot-mode

dot语言的语法非常简练,看看我简单探索的成果:

graphviz-dot-mode,快捷键:

  • C-c c: compile, 根据你想要的layout,输入相应的编译命令
  • C-c p: preview, 预览图片效果(期间遇到了一个问题,用dot生成嵌入中文的ps或eps文件时,在emacs中预览是正常的,但是嵌入到latex文件中就会出现乱码,这可能是文字编码之前。

还有两个工具:

可以将graphviz的dot文件转换为tex兼容的格式,直接嵌入tex文件中,具体我就没有用过了。

最后一个推荐的CLI派的绘图干将就是gnuplot了。gnuplot主要擅长数学数据的可视化,结合maximaoctave等等可以形成一套完备的CAS系统。而且据我所知,gnuplot本身也是支持metapost接口导出的。这是gnuplot的gallery,看看什么叫数学之美。

说了这么多废话,第一类总算数的差不多了。接下来再简单数数第二类。基于GUI的画图工具,汗牛充栋,大块的如gimp、inkscape等,做尔等工作,牛刀杀鸡也。

还是一些小工具来得实惠。首先推荐的当然是大名鼎鼎的dia了。引用其官方主页上的介绍:

Dia is a gtk+ based diagram creation program released under the GPL license.

Dia is inspired by the commercial Windows program 'Visio', though more geared towards informal diagrams for casual use. It can be used to draw many different kinds of diagrams. It currently has special objects to help draw entity relationship diagrams, UML diagrams, flowcharts, network diagrams, and many other diagrams. It is also possible to add support for new shapes by writing simple XML files, using a subset of SVG to draw the shape.

It can load and save diagrams to a custom XML format (gzipped by default, to save space), can export diagrams to a number of formats, including EPS, SVG, XFIG, WMF and PNG, and can print diagrams (including ones that span multiple pages).

有趣的是,dia还支持pgf/tikz、metapost、pstricks文件格式的导出。所以把dia当成信手涂鸦工具,导入tex文件中,倒会给一向严谨的tex添点趣味。

最后一个小工具,类似于windows下的几何画板,顺手画一些几何图形还是非常赞的,这就是Geogebra。我非常赞赏的两点是:

  • 像autocad一样,具有命令行模式,既能精确控制,又能随手泼墨;
  • 也支持多种格式的export,如metapost和pgf格式。

好了,这么晚了,说了这么多废话,但愿说者无意、听者有心。安。

Windows mobile开发总结--资源工具篇

俗话说:磨刀不误砍柴工。得心应手的工具,对于长时间的软件开发,能够起到事半功倍的效果。VS本身已经是一个非常强大的开发平台,只是在这个巨无霸的开发平台上,某些小功能还是不尽如人意。这个时候就需要插件来帮忙了。但是由于VS本省的原因,VS的插件并不像Eclipse那样丰富,我用到的有:

1、Visual Assist X:简单的说就是编辑器增强。安装后会增加VAssistX的菜单,里面主要有一些代码的snippet(比yasnippet差远了),一些查找引用等贴心的功能。VA Outline的功能比VS自身的要好很多。其余的主要是代码补全方面的增强。比如你写一个类,重命名其中一个成员的时候,会出现以下的窗口:

这是一个很方便的功能。免除了手工修改反复编译的错误和潜在的危险。另一方面,这也说明事先的设计是非常重要的。当你敲了几万行代码后却发现其中一个英语单词拼写错误的时候,再想去修改时一件非常尴尬的事情。不改吧,显得自己没水平;改吧,很麻烦。在我们的代码中,我就发现了类似的错误,关于汉字拼音输入法的命名,chinese写成了chiese,结果一直就这么用下来了……还有,我们新开发的控件,由于要仿照IPhone的效果,所以新的一套控件啊类啥的统一加上前缀'I'。可是毕竟大家习惯不同,有的是大写的'I',有的是小写的'i';还有最开始的控件都是只能支持bmp图片的载入,过了一段时间,底层引擎改进,支持png图片的载入了。可是类的成员函数很多却没有跟上。SetBitmap里面有很多载入的却是png图片,也一直这么用下来了。

2、ViEmu:简单的说就是给VS的编辑器加上vim的key bindings。官网的ViEmu还支持word和outlook,不过我用的不多。令我非常惊喜的是这个小插件竟然还支持vim键盘宏的功能。

	iLogoLabel		* m_pJnyTrnLabel;	// logol label

	ILabel			* m_pJnyTrnStaticTrain;
	ILabel			* m_pJnyTrnStaticSeat;
	ILabel			* m_pJnyTrnStaticStartStation;
	ILabel			* m_pJnyTrnStaticStartTime;	
	ILabel			* m_pJnyTrnStaticDestStation;
	ILabel			* m_pJnyTrnStaticDestTime;
	ILabel			* m_pJnyTrnStaticBookInfo;
	ILabel			* m_pJnyTrnStaticNote;
	
	// 动态框架可变信息
	ILabel			* m_pJnyTrnTitle;	// title of this window	
	ILabel			* m_pJnyTrnTrain;
	ILabel			* m_pJnyTrnSeat;
	ILabel			* m_pJnyTrnStartStation;
	ILabel			* m_pJnyTrnStartTime;	
	ILabel			* m_pJnyTrnDestStation;
	ILabel			* m_pJnyTrnDestTime;
	ITextArea		* m_pJnyTrnBookInfo;
	ILabel			* m_pJnyTrnNote;
	
	//buttons
	iIdxButton		* m_pJnyTrnDelete;			//删除按钮
	iIdxButton		* m_pJnyTrnServicePhone;	//客服电话按钮
	iIdxButton		* m_pJnyTrnShare;			//共享按钮
	iIdxButton		* m_pJnyTrnStartMap;		//出发站地图按钮
	iIdxButton		* m_pJnyTrnDestMap;		//终点站地图按钮

以上代码是一个窗口的.h文件里面的一部分,是这个窗口类的成员函数。一般来说,在构造函数里面将这么多成员初始化为NULL。没有键盘宏,我们只能动用自己的四肢,一会end,一会又点点鼠标,折腾3-5分钟,终于把这些成员都“初始化为NULL"了。有了键盘宏,这种工作只是十几秒钟的事情。进入命令模式:

  • qa开始记录宏
  • q结束宏的录制
  • @a执行宏。可以加数字参数,比如10@a表示执行键盘宏10次。

 其余的具体细节,看vim manual吧。

3、.vssettings文件:多数用VS的人可能不知道,长时间对着白底黑字对眼睛是非常有害的。找一个深色调的主题,一来延长显示屏寿命,二来有效保护眼睛。在这方面vim和emacs是榜样,他们都有非常多的color-theme。vim本身是内置color-theme的,emacs的color-theme需要插件支持,我偏好于黑底白字的color-theme——bash终端就是这个颜色,比较cool,呵呵。在word2003里面也有设定默认背景色和字体颜色的选项,较好的方案是蓝底白字,对眼睛比较好;但是到了word2007里面这个功能却不见了,不知道MS是怎么想的呢。好在WPS有这个功能,所以我现在用WPS。废话说了这么多,在VS里面,也是可以设置字体和颜色的。工具-选项-环境-字体和颜色:

但是一项一项的设置不仅非常麻烦,而且由于80%的程序员都没有与其编码能力相称的美工配色能力,所以这个方案基本是不可行的。剩下的,就是前人栽树,后人乘凉。Google: filetype:vssettings,找到自己喜欢的配色文件,直接导入即可。

 4、git-extentions:我对版本控制并不是特别了解,主要是自己经验不足,没有多少实际的开发经历。只是在去年的java课上,自己像模像样的用了一下git。对版本控制的印象也只停留在了“好像是个时光机”这个层次上。目前主流的版本控制应该是cvs、svn和git吧。cvs廉颇老矣,逐渐被svn取代,git是Linus几个星期内写的,却很快风靡了开源世界,还曾引发了一场c和c++的论战。svn的各种插件比较成熟,项目组最开始的引擎也是用svn做版本控制,用的插件是tortoisesvn。VS相关的集成插件是AnkhSVN,我也安装了。但是老实说,我不太喜欢。最不喜欢的是svn在项目目录的每个目录下都创建一个.svn目录,让我十分不爽。而且还有自己架设svn服务器,apache啥的,我看着就头大了。哪如git,一条git init语句就可以投入使用了。

就这么多,Visual Assist X和ViEmu是共享软件,需要发挥中国人的聪明才智破解一下。后面的免费的。

刀已经磨好了,怎样砍柴又是一个问题。因此对嵌入式尤其是wince和windows mobile平台上相关知识的了解是至关重要的。网上有一些非常不错的博客和资源如下:

  • 克伟的博客:里面的一篇《如何开发绚丽、高效率的界面(Windows嵌入式系统)》,讲的非常透彻,深入浅出,非常适合向我一样的新手入门。
  • LinuxGraphics:难得的介绍各种GUI体系结构原理的网站。是我见过的所有讲GUI体系的网站中最好的一个。
  • cexer:这个博客的作者对gui框架体系有相当的研究,里面有一些GUI实现机制的源码,值得学习。
  • The linux mobile development:这个博客有个ftk项目,想学习开发嵌入式GUI的同志们可以研读一下代码。别的开源代码如gtk、qt、minigui等都太庞大了。这个项目刚开始起步,整体来讲研读起来比较容易一些。

当然,“纸上得来终觉浅,绝知此事要躬行”,自己动手实践才是最重要的。 

Windows mobile开发总结--文本控件篇

 这个项目是在自己已有的代码基础上,在windows mobile 6.x平台下开发出一套商旅个人助理软件,软件主要内容是世博相关的机票、酒店、火车票、行程安排等,界面要求是仿照Iphone风格。因为客户公司有了Iphone和Android平台上的成品,但是可能时间紧急,又缺乏mobile平台上的控件代码基础,所以找到了我们这边。

原来的代码基础是一套GUI的控件引擎。利用GAPI,从最底层写起,包括最基本的画点画线函数、显存操作函数、窗口管理函数、控件类继承体系等等。这套体系的第一个产品是宁波公安的移动警务系统。去年的时候我也曾经有所了解,但是终究因为自己课业繁忙没有真正参与进来。这次是个机会。

开始的时候我对这套东西很是抵触。一来是我本身不太欣赏windows的哲学。在进入实验室之前的半年都在linux下生活;二是我觉得重新写这么一套东西是"reinvent the wheels"的愚蠢做法。我还像导师建议Qt。坦白的说,虽然我从来没有用Qt写过一个像样的东西,但是Qt的信号与槽机制,感觉要优雅的多;三是除了Qt,MiniGUI据说也不错,为什么要自己大费周章地写这么一个东西呢?而且我虽然很菜,但是写这么一坨代码,我还是能看出很多问题的——虽然让我去写我肯定写不出特别好的东西。

事实上:

  • 我很讨厌某些宏。大量的宏让程序显得莫名其妙。Win32 API中有大量的宏,什么handle, hwnd, COLORREF等等,虽然这些宏归根到底不过是个int,但是我觉得很多时候还是KISS原则最重要。直接用int好了。干嘛这么麻烦。
  • 我很讨厌某些typedef。明明有了标准的true和false,为什么还要自己去定义个GTrue、GFalse和GOK呢?还有GRESULT?这大概是受windows编程风格的影响吧。
  • 我很讨厌注释不全、命名风格糟糕的代码。

当然,GUI框架的设计是一件很复杂的事情。具体来说可以分为三层:

  • 底层引擎层:包括基本的显存操作,画点画线,alpha渲染,图片压缩载入,图形学算法、消息事件处理、字体引擎、布局管理器、窗口管理器等等。
  • 控件层:控件继承体系、文本类控件(标签,单行文本编辑,多行文本编辑域),按钮类(button、list等)、滚动条类、光标类、复杂控件类(菜单、表格等等)
  • 应用层:这个算最简单的了。只要前两层足够稳定,应用层是手到擒来的事情。其余的事情如数据库连接、xml解析、网络连接等等,属于额外附加功能。

这里有份GUI系统需求描述,可以参考一下。嵌入式的GUI框架还是要简单一些。当然,这也与嵌入式系统的硬件条件是息息相关的。

实验室的这套框架主要是仿照Windows消息机制写的。很多东西保留了Win32 API的痕迹。事实上底层引擎是不可能脱离具体的操作系统而存在的。跨平台的原理就是在统一的接口下面提供不同的内部系统实现。

最开始接触这个项目的时候我心中很是没底。一来我从来没有接触过4W+行代码的项目,二来我对windows消息机制那一套也不是很了解。所以我就花了将近200大洋买了经典的《windows程序设计》,自己在那里面吭哧吭哧啃了好几天,看了200多页。终于算对windows消息循环机制有了初步的了解。

3月28号开会,3月29号熟悉整个系统体系。开始做控件。我被安排的任务是做文本类的控件:

  • ILabel:静态文本标签。
  • ITextField:单行文本编辑框。
  • ITextArea:多行文本编辑框。

三个文本控件统一要求:

  • 支持png图片载入
  • 支持字体类型和大小,
  • 字体颜色,
  • 背景颜色,
  • 圆角透明。
  • 支持编辑锁定和光标定位。

说起来容易做起来难。底层控件的开发往往比上层应用的开发要难的多。写到现在,代码总量写了180k,估摸着6000行应该有的(虽然有很多框架性copy&paste的东西)。总共写了3个文本空间和8个窗口界面。3:8,由此可见一个小小的文本编辑框并不是我们想象中的那么容易。具体来讲,在画点画线画矩形这写仅有的GDI函数的基础上,你需要实现:

  • 如何支持不同的风格(字体颜色,大小,背景颜色,alpha渲染风格);
  • 如何支持png图片的载入(我设计的单行文本框支持一张mainPng和两张leftPng、rightPng的载入,并根据鼠标是否点击在leftPng和rightPng图片上进行不同的处理,如清空文本,确定查询等等,载入png事件简单的事情,但是由此引发的光标定位问题却让我无比头疼);
  • 如何支持光标定位(这是文本框设计中非常复杂的一个问题。可能你不相信,等宽字体(monospace)的发明就是因为早期的电脑画面显示、打字机,由于技术的局限,无法进行字母宽度的比例调整,因此将每个字元都制作成一样的宽度)。说到这里应该明白了吧。当你点击光标的时候,需要根据你的光标的坐标,判断在整个字符串中最合适的位置。总不能让光标在一个字体的中间闪烁吧……原理也是很简单的,无非就是建立个链表,每个node的结构如下: 
struct char_node
{
    wchar_t * ch;
    int ch_width;
    int ch_height;
}

        然后根据光标的位置从头开始遍历链表,最终确定光标位置。但是,当你面对一个1k行的代码基,里面按照原来的机器写死了各种可恶的绝对坐标的时候,你想对 它进行改进,就不是说说那么简单的事情了。

  • 如何支持字体的滚动(当文本输入到边缘时——拿单行编辑框为例,正常情况下文本应该向左滚动,光标始终在最右端的边缘闪烁)。老的平台控件是支持这个功能的,这让我很开心,但是开心了没多久,我发现了一个很严重的bug,就是在整个文本字符串在向左滚动的时候,文本字符会画到整个文本控件的左边……这显然是一个不可饶恕的bug,但是到现在我仍然没有搞定。因此现在我的ITextField,当你的文字字符串输到文本框右边的时候,光标仍然继续向右移动——于是就会消失不见了。
  • 如何支持不同的字体大小(我发现在原来的代码基础上改造而来的ITextField对光标的定位简直是一塌糊涂。经过我一番实验,发现当用29号字体的时候光标的定位效果是最好的,于是我统一把我的文本控件的字体改成了默认的29号大小。陈老师告诉我们说“软件软件,越软越好……”,我当然明白这个道理,但是,写“软”是需要时间的。某些时候,为了赶进度,我们不得不牺牲某些扩展性来追求暂时的能用性。所以我的东西到现在,光标定位依然是很大的问题)
  • 如何支持不同字体载入?据我所知,字体有点阵字体和矢量字体,矢量字体又有OpenType和TrueType等,这些字体的内在原理是什么?什么叫衬线字体?什么叫非衬线字体?为什么一般文章排版正文都要用宋体?等等,这是非常有研究的一个话题。
  • 如何支持文字选块?
  • 如何支持多行文本域的文字折行?
  • 进一步,如何支持标点压缩和头尾压缩(这是一般字处理软件的事情了……)。
  • 再进一步,我们只知道英语和汉语,陈老师说阿拉伯文的文字连着写和分着写也是不一样的,有特殊的规则,我们又该如何支持?

由此可以看出,文本编辑框虽然看似简单,实现起来却要涉及到很多很多的知识和细心斟酌。

当然,以我的水平是不可能在这么短的时间内写出一个完备的文本编辑框的。可取的方法就是模仿、修改。老的单行文本编辑框叫做GTextField,GTextField的邻居如下所示:

我呢,则丝毫没有客气,仿照主要的函数接口,框架代码,对GTextField做起了外科手术。一个好的医生应该是内外兼修。做这么一个东西自然需要对底层的东西有比较深入的了解。可是一来这一套东西是我们实验室自己yy出来的,很多尚达不到工业标准,也没有现成的教程指南,代码注释又不是特别完备,所以自己理解起来颇有些困难;二来很多东西急于求成,所以有非常多莫名其妙的1、2、3、4、5,只有通过自己的实验看效果,将这些12345变成const int default_xx_margin = 3……

经过我的改造,除了光标定位和字体大小,其余功能基本实现,只是代码写的比较恶心,自己都不忍去看了。

无怪乎,Knuth大人一个TeX系统写了十年时间,经过别人改造成LaTeX、ConTeXt、Omega、LuaTeX等等至今尚未完善;无怪乎求伯君大神当年十万行汇编代码的WPS1.0使他成为了全中国程序员的偶像。

当我们费了九牛二虎之力做出来一个可以用的东西时,却发现那个东东是如此的丑陋,以至于连自己都不敢去看它。有了这样的经历,再去使用Windows 7,Compiz Fusion,会多一份敬重之情。简洁优美的背后,隐藏着多少心思和功力。

这是我现在写出来的最终效果:

样式还不错,点击右边小按钮的时候还能清空文本。当然,更灵活的设计时发送个消息,让用户自己处理决定该做什么。

这是头文件,单行文本编辑框的类定义: 

/**************************************************
ITextField: 单行文本编辑框
功能描述:至此png图片载入。支持单行文本编辑。支持锁定操作。但是光标定位和字体大小还存在问题。
作者:Xiao Hanyu <xiaohanyu1988@gmail.com>
参考:GTextEdit
**************************************************/

#pragma once
#include "SimpleCtrl.h"
#include "TwoWayLinkList.h"
#include "DataTypeDef.h"  //-------------
#include "string"
#include "ThTimer.h"
#include "IStyle.h"
#include "TextArea.h"
#include "MCaret.h"
#include "WndContainer.h"
#include "GDIFactory.h"
#include "DrawDevice.h"
#include "GDIPen.h"
#include "GDIBrush.h"
#include "CombinedCtrl.h"
#include "AllCtrlManager.h"
#include "BaseWnd.h"

#define	ITF_TXT_CHANGED		(MD_USER_BEGIN + 1)			// 只要文字输入改变,就发送该消息
#define	ITF_LEFT_PNG_CLICKED	(MD_USER_BEGIN+2)		// 只要设置mainPng和leftPng,如果点击leftPng,就发送该消息
#define ITF_RIGHT_PNG_CLICKED	(MD_USER_BEGIN+3)		// 只要设置mainPng和rightPng,如果点击rightPng,就发送该消息

const int ITEXTFIELD_MAX_LEN = 300;
//设置边距,即绘制光标和文字时,距离边缘的最小值
const int ITF_EDGE_BORDER = 2;

class MCaret;

class ITextField : public SimpleCtrl
{
public:
	ITextField(GisHWND pBWnd, ControlID id);
	virtual ~ITextField();
	Boolean ShowCaret();
	Boolean HideCaret();

public:
	//父类继承需要重写函数
	virtual GRESULT Init(int cx, int cy, int nWidth, int nHeight);
	virtual GRESULT UnInit();
	virtual void Redraw();
	virtual Boolean setDisabled(Boolean b);
	//Mouse Msg Action
	virtual GRESULT OnMouseDown(MouseButtons mbtn,int x,int y);
	virtual GRESULT OnMouseUp(MouseButtons mbtn,int x,int y);
	virtual GRESULT OnMouseDBClick(MouseButtons mbtn,int x,int y);
	virtual void SetFocus(Boolean bFocus);//设置本文本框为鼠标焦点
	virtual void SetVisable(Boolean bVisable);		//重载 当不可见时,失去焦点
	//Msg proc
	virtual GRESULT ProcCharMsg(WPARAM wParam, LPARAM lParam);
	//控件文本内容操作
	//获得当前文本
	wchar_t* GetText();
	//设置文本内容
	void SetText(const wchar_t *content);
	//清空文本内容
	Boolean ResetText();
	static void CALLBACK DoTimer(UINT uTimerID,DWORD dwUser,DWORD dw);
public:
	bool getCharVisable();	//输出文本框字符是否可见
	bool setCharVisable(bool p);//设置文本框字符是否可见
	void SetAutoOpenSip(bool p);//设置是否自动打开键盘
protected:
	//根据传入的x,y判断在字符串中的具体位置
	//x,y,在控件中的相对坐标
	int GetPosInString(int x,int y);
	//通过字符序号活得光标偏移位置长度
	int GetCaretFromCharIndex(int nCharIndex);	
	//获取当前整个字符串的长度
	int GetStringLength();

	//pos:在m_szText中的位置
	Boolean InsertCharInString(wchar_t cdata,int pos);
	Boolean DeleteCharInString(int pos, wchar_t* pCharOut);
	ThTimer m_Timer;	//光标显示定时器

public:
	IStyle GetStyle();
	void SetStyle(wchar_t* fontType, COLORREF fontColor, int iMode, int fontSize, UINT textAlignment, COLORREF bgColor, int alpha, bool round);
	Boolean ResetStyle();
	
	virtual GRESULT SetPngImage(wchar_t* main_png, wchar_t* left_png = NULL, wchar_t * right_png=NULL);
	GRESULT SetEditable(bool editable);

private:
	bool isCharVisable;		//决定文本框字符是否可见的变量,值为true,则输入的字符都可见,
	//值为false,则输入的字符均显示为*号,一般用来输入密码使用
	MCaret* m_pCaret;
	
	//保存文本框字符内容的数组,容量有限,依据ITEXTFIELD_MAX_LEN的值来决定容量
	wchar_t m_szText[ITEXTFIELD_MAX_LEN];
	//根据输入的字符串长度来填充适量的*号,这个变量就是一串*号的首地址
	wchar_t s_szText[ITEXTFIELD_MAX_LEN];
	
	//字符串显示开始位置
	GRect m_rcText;
	
	//字符串链表,因为不仅要保存字符本身,还要保存字符的显示宽度等信息,因此需要用到链表存储
	TwoWayLinkList m_CharList;
	
	//当前光标对应的字符串中的字符位置
	int m_nCurCharPos;
	//当前字符串的字符总数
	int m_nCharNum;
	bool m_bAutoOpenSip;
	
	bool i_tfEditable;					// 是否可编辑
	
protected:
	IStyle i_tfStyle;					// 控制textfield的文字风格
	enum
	{
		i_mainPng = 0,
		i_leftPng,
		i_rightPng,
		StateCount
	};
	
	GImage	i_tfArrPng[StateCount];		        // textfield目前支持三张png图片
	Boolean i_tfSetMainImg;				// 是否设置mainPng?
	Boolean i_tfSetLeftImg;				// 是否设置leftPng?
	Boolean i_tfSetRightImg;			// 是否设置rightPng?
	//HFONT	i_tfFont;				// 保存控件的字体信息,用于光标定位和字体大小
};

多行文本域的设计还要复杂一点。所以这个控件至今有很多的bug,有非常多的改进之处。

除了控件层开发,到现在为止我还写了行程业务的8个窗口页面。在写的过程中思考了很久“如何把软件写软的问题”。但是由于没有系统了解过设计模式,对c++强大的继承用的又不熟,因此现在无法做出自我满意的总结。

还打算总结下这一个月来用VS2008及相关软件的一些小技巧。毕竟磨刀不误砍柴工。

水平有限、敬请批评指正。 

我说的这句话是假话

lox 说(23:49):
在某个城市中有一位理发师,他的广告词是这样写的:“本人的理发技艺十分高超,誉满全城。我将为本城所有不给自己刮脸的人刮脸,我也只给这些人刮脸。我对各位表示热诚欢迎!”
 

lox 说(23:49):
来找他刮脸的人络绎不绝,自然都是那些不给自己刮脸的人。可是,有一天,这位理发师从镜子里看见自己的胡子长了,他本能地抓起了剃刀,你们看他能不能给他自己刮脸呢?
如果他不给自己刮脸,他就属于“不给自己刮脸的人”,他就要给自己刮脸,而如果他给自己刮脸呢?他又属于“给自己刮脸的人”,他就不该给自己刮脸。
 

王敏 说(23:51):
算了,你要是那个理发师,我给你刮脸好了。莫觉了
 

lox 说(23:51):
嗯。我在看一些很高深理论的入门书。发现蛮有趣的。
 

王敏 说(23:53):
他要是个女的就不用刮脸了
 

lox 说(23:53):
“我说的这句话是假话”,你说引号里德这句话究竟是真话还是假话呢?
 

王敏 说(23:54):
因为我是个女的,我也不用纠结这些问题了,我觉了
 

lox 说(23:55):
good。
 

申请上LinuxApp版主了

看到88(ZJU,飘渺水云间论坛)pluskid大神在征LinuxApp的版主,于是我就毛遂自荐, 冒冒失失地去分区GM1_Studio发了申请版主的帖子。那个时候对于term软件还不是很熟练,帖子发错了信息,竟然不知道如何修改,闹了大笑话。后来熟悉了term软件,windows下的Fterm,和linux下的Qterm,发现term的许多操作都是仿vim和emacs。

过了几日,分区主管发来“慰问信”,我赶快又把88的站规浏览了一遍,糊弄份答卷回复。昨日,收到88的任命:

找这么个差事,主要是想有个交流的平台。一直以来,自己都是一个人在闭门造车。这几日的实验室生活,让我懂得,搞软件,人与人之间的交流还是非常重要的。可能人家已经做好的事情,你自己再费力气搞好几天也弄不好。所以软件业一个重要的原则就是复用,避免"Reinvent the Wheel”。

其实有时间也想把自己的linux环境配置好好写写。一来做个总结,以后也可以当参考;二来总结的过程就是重新学习的过程。只是这些天实验室的项目逼的太紧了。搞得自己连课都没得去上,甚至因此有些焦躁,担心再次挂科。算算编译原理的作业也该补补了。

周四客户那边来人检查。今天下午赶工赶到现在,就出来一个很鹾的页面:

而且动态文本的更改还有些问题。尚不支持消息响应。真是太没成就感了。

不过这么写一遭,倒也学到了很多书本上学不到的知识。VS2008的一些小技巧、静态库的生成与发布、多Project的部署和依赖、WM模拟器的有关设置、还有重要的Windows消息机制的理解。想想现在再去看那本经典的《Windows程序设计》,应该是轻车熟路了。顺便买了一本魏永明先生的《嵌入式软件开发及C语言实现:MiniGUI剖析》,感兴趣的是其中的设计模式部分和跨平台实现部分。等做完了这个实验室项目好好研读研读。

ZOJ这两天没有做题。太忙了。忙完这阵再刷吧。晚上回去补编译原理的作业。再不做要来不及了。

紧凑的生活。加油。
 




Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee