一直想做個QQ那樣的好友列表,即選中某項后可以放大顯示。如果用Windows的ListView,主要要解決一個動態(tài)設(shè)置列表項高度的問題,但我翻遍了MSDN也沒有找到解決方法,網(wǎng)上找的有3種方法設(shè)置listview列表項高度:
1.設(shè)置字體,把列表項撐起來。
2.設(shè)置圖片,也是把列表項撐起來。
3.響應(yīng)WM_MEASUREITEM,但這個消息只在列表被創(chuàng)建時發(fā)生一次。
以上方法都只能設(shè)置所有列表項的高度,不能為不同列表項單獨設(shè)置不同的高度。我查了各種資料,似乎只有一種方法:從CreateWindow開始重新做一個,研究了下QQ的實現(xiàn)方式,也是如此。
但是在我準(zhǔn)備從頭寫的時候還是想到了一個用ListView實現(xiàn)的辦法,那就是把兩行并為一行。幾經(jīng)周折,終于通過從CListCtrl派生一個類實現(xiàn)了大致的效果:

加入了頭像的好友列表:

原理就是在用戶單擊某行后,在此行下面插入一個新行,用自繪把這兩行畫成1行,當(dāng)選中其他行時再把此行刪除。具體方法為:
1.插入一個CListCtrl控件,把它的風(fēng)格設(shè)為Report,Single Selection,No Column Header,Owner Draw Fixed。
2.從CListCtrl派生一個類,響應(yīng)WM_MEASUREITEM或用一個圖片設(shè)置所有列表項的高度,本例中為22。
3.準(zhǔn)備3張圖片,分別為選中列表項的上半部、下半部和沒有選中的列表項背景。
4.響應(yīng)WM_LBUTTONDOWN,在消息處理函數(shù)中完成列表項的插入和刪除操作。需要注意的是改變選中項時在上次選中項的上面插入和下面插入的情況是不同的,要分別考慮。
5.重載DrawItem(不是OnDrawItem),根據(jù)當(dāng)前選中項的狀態(tài)進行繪制。這里比較麻煩的是DrawItem在WM_LBUTTONDOWN時就會觸發(fā),而列表選中項在鼠標(biāo)彈起時才會改變,所以在WM_LBUTTONDOWN消息處理函數(shù)中就要根據(jù)情況提前設(shè)置好選中的列表項。
至于QQ的好友分組,用TreeView應(yīng)該也能實現(xiàn)這種效果,可能比用ListView還簡單,直接把選中項跟他的子葉畫成一行就行了。
下面為VC6下的例程:
http://www.shnenglu.com/Files/getborn/ListExample.rar下面為列表類:
http://www.shnenglu.com/Files/getborn/class%20CFriendList.rar