这两天在用MFC的自绘列表框,先用SDK实现了一下,有点心得,与大家分享一下,其中有些细节就不详述了,亲们可以查看MSDN。
自绘列表框分为fixed和variable。
两者的共同点:
都会发送WM_DRAWITEM,WM_MEASUREITEM.
WM_MEARSUREITEM:可以修改你每个项目的尺寸,详情看MSDN。
WM_DRAWITEM:感觉就像是WM_PAINT,但是在列表框中是一个一个项目重绘的,在这里你可以插入位图,插入文字,详情看MSDN。
两者的不同点:
1:fixed在WM_INITIADIALOG之前就发送WM_MEASUREITEM。
2:variable在你每次LB_ADDSTRING或LB_INSERTSTRING就会发送WM_MEASUREITEM。除了以上两者属性以外,还有一个重要的一点就是列表框是否是Has Strings。
3:如果不是,你发送LB_ADDSTRING添加项目,相当于发送LB_SETITEMDATA,加入的是一个指向你自定义的结构指针,并且该结构体是你自己分配的,此时程序不会认为该项目是字符串,所以此时若你使用了LB_GETTEXT等类似的消息或函数获取文本,将会是乱码,这点很重要。
4:如果是,那么你发送LB_ADDSTRING添加项目,加入的是字符串,并且程序会帮你保存。而LB_SETITEMDATA则就是加入你自定义的结构体,此时类表框中有两类数据,一个字符串另一个就是你自定义的结构体指针。(请注意和上面的区别)
所以综合上面的知识,须知道若想在WM_MEASUREITEM中使用自己定义的数据:
如果你是fixed那么你要注意:由于条件1,也就是说在你加入任何项目之前发送的,所以WM_MEASUREITEM中千万别使用关于该项目的的任何数据(还记得上面说的自定义的结构指针吗)
如果是variable,那么是OK的,但是此时你必须要设定Has Strings为否。否则你想想看,由于4,程序认为你是字符串,和你自定义数据没有一毛钱关系,又由于2,你进入了WM_MEASUREITEM,当你想高兴地使用自己的结构体时,发现,这是啥玩意?(WM_MEASUREITEM中可以得到自定义的结构体)哈乎,写完了,写这篇文章的动力其实是我想问一个问题,但是有付出才有回报,所以呢才会写下这么多字。
我的问题有一个:
当我设置了列表框为variable时,我点空白的地方,列表框中的一个项目居然也会收到LBN_SELCHANGE消息,而如果设置了非自绘就不会有这个情况。这导致本来一个项目是在选择状态的,但是点了空白处后变为非选择状态了,这完全不合乎逻辑啊有木有。
如果哪位大大可以解答,在下感激不敬。

解决方案 »

  1.   

    可以再pretranslatemessage过滤掉的!
      

  2.   

    我记得ListCtrl有一个HitTest功能可以得到这个点击对象所在索引。看看这个功能在你自绘后还保留么?
      

  3.   

    各位大大的回复小的看了,我的问题其实是在C/SDK中出现的,在MFC中编码则是很完美的,就是不知道为什么C/SDK中为什么会出现这个问题(MSDN关于列表框的几个消息都看了好几遍),不过这也不重要了,用SDK编写完全是为了彻底了解自绘列表框的消息属性,否则谁知道CListBox的AddString除了添加字符串还能添加自定义结构体指针呢。
      

  4.   

    "CListBox的AddString除了添加字符串还能添加自定义结构体指针"
    MFC 也可以,关键是 “字符串,结构体,对象,都是指针”
      

  5.   

    楼上说的没错,但是从设计角度来说函数名就代表了一个函数的意义,addstring的函数名就是加入一个字符串,其参数更是确定了这一点,文档也没很明白说明,如果按照“可以存放任何指针”这个思路来看,那就设计为(void*)其实更好。毕竟MFC封装了太多,如果不把函数名设计的简单易懂,文档的注释也好些,那么用起来还真要费不少功夫。
    ま~~~,不吐槽MFC了,瑕不掩瑜,MFC还是很强力的,OK结贴收工。