在前进的路上,只有快慢,没有成功与失败

只要出发,就会到达

 

只要出发,就能到达。

孩子,不管遇到什么,不要停下脚步。

只要勇敢地迈出第一步,只要勇敢地再迈一步。

Tagged ,

皮肤中Draw的实现

皮肤重构的过程中,引入了IXDraw这样一个接口,用于提供图片、文字、颜色的绘制功能,IXDraw并不属于控件的行列。
IXDraw的子接口有IXImageDraw、IXColorDraw、IXIconDraw,IXTextDraw还没有实现。
现在最实在的可能只有IXImageDraw,因为屏蔽了对BitBlt、AlphaBlend、StretchBlg等方法的调用,还实现了对九宫图等特殊拉伸方法的支持。其他的Draw暂时只是对系统函数的调用而已。暂时看起来好像没有Draw没有什么意义,但其实不然,像这样将绘制同意起来以后,主要是后面做优化或者优化算法的时候,可以只修改Draw的实现即可。想ImageDraw的优化,由于AlphaBlend的拉伸算法不好,所以通常都是根据控件的大小,在内存中做好一张拉伸后的图片,这样在绘制的时候,就不需要做拉伸了,效率会更好很多。这种缓存如果让控件来做的话,功能就比较分散了。
另一个比较有用的Draw可应该是TextDraw,因为后期需要实现富文本,由于富文本是由很多的字符串及其格式绘制在一起的,如果每次需要绘制的时候,都是重新逐个绘制的话,效率会很差,这样最好的方法就是在内存位图中绘制好,在需要绘制到屏幕的时候,直接使用这张缓存位图即可。
还有一点,就是Draw可以组合,这样可以减少绘制的成本,相同ZOrder层的Draw可以在内存中直接绘制到一起即可。
但是有一个问题没有解决,现在控件支持使用Draw作为背景,但是经常的Draw需要非填充式绘制,这就需要引入布局;而且有些时候,需要组合N个Draw才能做到需要的效果。这样就需要Draw像控件一样支持父子关系、布局等。这个问题的解决办法,是将控件的父子关系、布局等功能抽象出更高级别的接口,然后Draw也去实现这些接口即可。但是这样Draw的成本就比较高了,还需要考虑一下。
还有一种办法,就是专门写一个Draw的容器,然后这个容器实现布局、缓存功能,这样也会更方便一些。然后这个容器也是从Draw继承,使用起来更简便。

C++静态库全局变量的问题

新的皮肤库中,所有的控件和接口使用了动态注册的方法,这样在写接口的时候,就不需要维护一张巨大的类表了。而只是在加载这个DLL的时候,会牺牲一点性能做动态注册。不过跟维护类表而言,这个性能损失完全可以接受。
这周在做在线安装的时候,由于最终只允许一个独立的Exe,皮肤只能以静态库的方式链接。随之而来了一个问题,原来的动态注册的机制,其实是在各实现类的CPP文件中,定义了一个全局变量,通过这个变量的初始化,来向类厂注册这个变量代表的接口信息。这种机制在DLL中是完全没有问题的,但在静态库则不行。
静态库在链接的时候,如果某个变量或者函数没有被使用到的话,那么他们将会被裁减掉。这也就意味着使用全局变量注册接口信息的方法失效了。暂时还没有找到好的方法,“我是程序员”同学给出的方案是要么是维护类表或者写初始化函数要么每个类的构造函数里写初始化方法。
这几个方法都不是很理想,刚好新皮肤库的文件系统,还没有实现从Exe资源中加载图片,因此仍然使用了旧的实控件的方法实现了在线安装程序。静态库的需求暂时没有了。
后续如果有新的方法的话,再在文章中更新吧。

附, 已经被认定无效的方法:
1. 在静态库中定义共享段。
2. CPP中,全局变量和一个全局函数互相引用。这两个都会被剪裁掉。

可能可以的方法:
ATL里的pragma定义可能可以完成,但是我不是很想使用VS的语言扩展功能实现。

Tagged , ,

非常激励的视频

橄榄球励志片《面对巨人》

这是一个非常激励人的视频,很多看似做不到的事情,其实都是非常简单的,只要努力,只要不断对自己说,我能行就可以。

Can I Count on You?

问自己这句话。

Tagged ,

起点

新建的博客,新的角落,mark下时间