一、 綜述
Mfc內建的 listctrl 雖然能夠完成一些常用的操作,但是如果對於某些特定的應用,則無能為力,這時候,就學要對空間進行擴充,以實現滿足特定需要的功能。
本文闡述了如何?具有自訂行高,而且能夠選擇和編輯的listctrl 控制項。
二、 實現
(1) 實現自訂行高。
我們都知道,mfc 內建的 listctrl 控制項的行高是固定的,不能夠自訂的進行改變。如果設定一個比較大位元影像,或者簡單的設定比較大號的字型,這些方法雖然能夠改變行高,但是沒有接觸到問題的實質。我們使用訊息反射機制來實現自訂行高。有關訊息反射機制,請參見msdn 。實現自訂行高的listctrl 基於以下事實:當我們給listctrl 發送WM_WINDOWPOSCHANGED訊息時,也就是告訴 listdctrl 控制項大小、位置等發生變化,這時候 listctrl 控制項就會觸發 WM_MEARSURITEM 訊息,當然這個是反射訊息。通過映射這個訊息,我們就可以改變 listctrl 控制項的行高。當然還要設定 listctrl 的 Owen Draw Fixed 風格, WM_MEARSURITEM 只有在 Owen Draw Fixed 風格才有效。
總結一下,如果要建立自訂行高的listctrl ,大概要以下步驟:
(1) 定義新類,繼承listctrl ,設定 Owen Draw Fixed 風格,並且手動映射ON_WM_MEASUREITEM_REFLECT訊息。
(2) 增加設定行高的介面,通過設定發送WM_WINDOWPOSCHANGED 訊息引發 ON_WM_MEASUREITEM_REFLECT 訊息,例如:
void CListEx::SetItemHeight(UINT nHeight)
{
m_nItemHeight = nHeight;
CRect rcWin;
GetWindowRect(&rcWin);
WINDOWPOS wp;
wp.hwnd = m_hWnd;
wp.cx = rcWin.Width();
wp.cy = rcWin.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE| SWP_NOOWNERZORDER | SWP_NOZORDER;
SendMessage(WM_WINDOWPOSCHANGED,0, (LPARAM)&wp);
}
(3) 映射ON_WM_MEASUREITEM_REFLECT 反射訊息,在反射訊息裡設定行高, 例如:
void CListEx ::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
lpMeasureItemStruct->itemHeight = m_nItemHeight;
}
(4) 完成控制項自繪函數,CListEx::DrawItem。自此,自訂設定行高功能已經實現。
三、 增加編輯功能
增加編輯功能一般的思路,就是在單擊或雙擊的時候,建立一個CEDIT 編輯框,然後把編輯框覆蓋當前的 subitem 上,並且使編輯框擷取焦點。當編輯框失去焦點時,把編輯框裡的文字,顯示到 listctrl 控制項上,就可以了。為了能夠使控制項知道何時顯示編輯框中的文字,所以還有重寫編輯框,當編輯框失去焦點時,通過訊息通知 listctrl 控制項。