代码改变世界

战IDeskband告一段落后的感想

2010-07-12 23:35  Nana's Lich  阅读(2273)  评论(0编辑  收藏  举报

用.NET做Deskband好像遭遇瓶颈了,所以今天用C++试了试。

装上SDK、打开sample,不管三七二十一地乱改了一气,总算是能用了……

改的过程中犯了一些低级错误,比方说没给DLL自身增加引用计数器(原来的sample里面就没有这种事情可真不怪我这C++新手!)、忘了静态链接CRT什么的。

运行起来的效果也够奇葩——用SDK7.1的sample改出来的效果和BandObject2.0、SDK7.0、还有某神人的L-Shield效果还全都不一样!既然能用了这种事就先别管了吧……

 

改的过程中大概知道了这样的几件事:

OpenThemeData按照MSDN和SDK中的说明来操作完全没读到任何有用的东西,不知道是操作方法错了还是怎么的。

DrawThemeTextEx的光晕大小可以自己指定,但是使用的字体和文字大小似乎是要从ThemeData里面弄出来的……仔细观察一下还发现其实直接设置的光晕和Aero Glass标题的效果还不完全一样!

如果实现了IDeskband2但不调用DrawThemeParentBackground的话背景会变得很奇怪……这个事前边就提了,几种Deskband的实现中透明化又没画好的部分表现出来的样子完全不一样,像是SDK7.0的sample就是完全投过去,BandObject2.0是透出背后的玻璃效果,而SDK7.1又变成了输出一个和任务栏有奇妙练习的buffer...

HKEY_CLASSES_ROOT其实是HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE之下的Software\Classes的聚合视图。

 

最让该注意的其实是GetBandInfo里面的实现:

sample里面没提到怎么设置Band对象的标题,实际上应该是在检查DBIM_TITLE标志的时候设置——就算DBIM_TITLE标志被消除,也不能省略设置标题,要不然在强制关闭的时候名字就变成空白了。

如果任务栏被从底部拖到了侧边,DESKBANDINFO中ptMinSize和ptActual的x和y成员的实际作用会被调换——呸,说起来真绕口!简单地说就是如果拖到了侧边,ptMinSize的x=200实际效果就变成了最小高度是200……这个好像跟rebar控件的实现有点关系吧,ptActual也是差不多。

ptMaxSize和ptIntegral这两个就比较神奇了,在sample中只设置了它们的y成员,为什么不设置x、设置y又有什么效果——字面上的意思虽然能看得懂,但是实际操作上却怎么也搞不懂实际效果。

也不能说完全不懂,在非常特殊的情况下——如果为dwModeFlags同时设置了DBIMF_FIXED和DBIMF_VARIABLEHEIGHT的话,ptMaxSize和ptIntegral就好像会发挥作用了——如果这么做了之后把任务栏拖到侧边,就会发现任务栏上的东西都消失啦!其实并不是消失了,如果这个时候再把任务栏调大一些,就会看到任务栏好像是“一个很大的东西有一半被屏幕边缘切掉了”那样……事实上也的确是这样,因为ptMaxSize的y是设置成0xFFFFFFFF(“-1”)的嘛……

如果再把任务栏拖到下边,像是输入法之类的Deskband就也像消失了一样,其实还是发生了一样的事情。如果把ptIntegral.y设置成0,就不会发生这种事情——但让人困惑的是,这个时候ptIntegral.y只要设置成非0效果就都和设置成1一样,而在其它的情况下不管设置成什么看起来都没影响……这个值到底是干嘛来的啊!?

如果把DBIMF_VARIABLEHEIGHT去掉、只留下DBIMF_FIXED的话,也不会变成上面那样。不过这样做的话还会发现另外一件奇怪的现象,那就是在刚开始启用这样设置标志的Deskband的时候,是能看到rebar的可拖动条带的,但却没有办法移动它!而如果任务栏的位置发生过变化,可拖动条带就消失了——那个条带倒是本来就不该有,至少开发文档是这样写的。

有意思的是尽管开发文档上写了使用DBIMF_FIXED之后不应该有可拖动条带,但如果在设置dwModeFlags的时候把DBIMF_FIXED和DBIMF_NOGRIPPER一起设置的话,条带就真的完全不出现了……可这毫无逻辑的现象到底是怎么回事啊!?