分享源码
界面截图:
是否带模块:
纯源码
备注说明:
-
本帖最后由 brucelee0720 于 2014-11-25 13:06 编辑
在百度搜索修改超级列表框(SysListView32)的行高的方法,可以得到很多结果。不过都是千篇一律的。无论是修改字体还是设置图片组,本质都是一样的,通过撑开的方法调整行的高度。
今天这里介绍的方法,与之上不同,是真正修改超列的行高度。
要想修改行高,需要考虑的第一个问题,就是超列中有没有行高这个属性,以及如何修改他。答案确实是有的,这个值通过WM_MEASUREITEM消息设置。从字面可以理解,这是一个测量项目的消息。消息的lParam参数是一个MEASUREITEMSTRUCT结构。这个结构中包含了控件的ID,项目的索引,项目的宽高等成员。对于超列,他的有效成员只有控件的ID和项目的高度成员。只要在子类化过程中修改这个成员的值就可以达到真正改变行高的目的。
typedef struct MEASUREITEMSTRUCT {
UINT CtlType;
UINT CtlID;
UINT itemID;
UINT itemWidth;
UINT itemHeight;
ULONG_PTR itemData;
} MEASUREITEMSTRUCT
有了上边这个消息的介绍,似乎一切都变的简单了,但是事实并非如此,如果直接SEND这个消息给窗口是木有什么效果的,事实上这个消息是超列控件通知给父窗口的。我们要考虑的第二个问题来了,如何让超列发送这个消息给他的父窗口呢?在MSDN关于WM_MEASUREITEM消息的说明中找到如下内容:
The system sends the WM_MEASUREITEM message to the owner window of combo boxes and list boxes created with the OWNERDRAWFIXED style before sending the WM_INITDIALOG message.
大概的意思就是:系统为使用OWNERDRAWFIXED 风格创建的组合框和列表框的父窗口发送WM_MEASUREITEM 消息,还有就是,这个消息是在WM_INITDLALOG消息之前发送的。
看来要处理WM_MEASUREITEM 消息,我们要做两件事:1、为超列增加OWNERDRAWFIXED 风格。2、在WM_INITDLALOG之前处理。
先来看看OWNERDRAWFIXED风格。他在超列中对应的常量名是LVS_OWNERDRAWFIXED。这个解决起来比较简单,我们只需要调用SetWindowLong这个API设置超列的GWL_STYLE,就可以为超列增加这个风格。
第二个问题就变的有些棘手,因为这个消息是在窗口创建后就触发的,所以除非我们自己创建一个超列控件,不然即便修改了超列,也还是得不到这个WM_MEASUREITEM 消息。到了这里似乎事情变的要无解了!不过办法总是会有的,既然WM_MEASUREITEM 是一个用来核算尺寸的消息,那么如果控件的字体或则尺寸被改变的话自然应该会触发这个消息。事实印证这个方法是可行的。我们可以通过修改一下超列的宽度属性,或者直接伪造一个WM_WINDOWPOSCHANGED消息,就可以在父窗口中收到WM_MEASUREITEM 消息了。
经过上边的一番折腾,终于得到了WM_MEASUREITEM 消息,修改了itemHeight成员的值后,超列的行高就被改变了。可是问题还没有完。这个时候,超列的行高虽然改变了,但是表项里的内容却不显示了。这个问题的原因是由于我们为超列增加了OWNERDRAWFIXED风格导致的。这个风格的作用是是否使用自绘,如果选择了这个风格,那么就表示你要自己把表项中的那些文本啊图标啊之类的内容自己画上去。单纯为了修改一个行高,这个代价太大了。先别怕,解决的办法很简单,反正这个时候,WM_MEASUREITEM 已经执行过了,超列中行高值已经被修改成功,如果不是需要再次修改行高的话,我们已经不在需要WM_MEASUREITEM 消息了,所以我们只要把LVS_OWNERDRAWFIXED风格从超列中移除就可以了。
执行完上面这些步骤后,超列的行高就被完美修改了。
最后的收尾工作:如果在调整窗口尺寸的时候,使用伪造WM_WINDOWPOSCHANGED消息的方法的话,这个时候滚动条的显示是没有变化的。需要在发送一个LVM_UPDATE消息给超列。这样整个的修改过程就全部完成了。
欢迎下载:
超列行高.zip
(49.27 KB, 下载次数: 2187)
评分
查看全部评分
本帖被以下淘专辑推荐:
· 鱼木 | 主题: 1560, 订阅: 152
· 老琛 | 主题: 36, 订阅: 1