MFC編程入門之二十四(常用控件:列表框控件ListBox)


  前面兩節講了比較常用的按鈕控件,並通過按鈕控件實例說明了具體用法。本文要講的是列表框控件(ListBox)及其使用實例。

  列表框控件簡介

  列表框給出了一個選項清單,允許用戶從中進行單項或多項選擇,被選中的項會高亮顯示。列表框可分為單選列表框和多選列表框,顧名思義,單選列表框中一次只能選擇一個列表項,而多選列表框可以同時選擇多個列表項。

  列表框也會向父窗口發送通知消息。這些通知消息含義如下:

  LBN_DBLCLK:用戶用鼠標雙擊了一列表項,只有具有LBS_NOTIFY的列表才能發送該消息。

  LBN_ERRSPACE:列表框不能申請足夠的動態內存來滿足需要。

  LBN_KILLFOCUS:列表框失去焦點。

  LBN_SELCANCEL:當前的選擇被取消,只有具有LBS_NOTIFY的列表框才能發送該消息。

  LBN_SETFOCUS:列表框獲得輸入焦點。

  WM_CHARTOITEM:當列表框收到WM_CHAR消息后,向父窗口發送該消息,只有具有LBS_WANTKEYBOARDINPUT風格的列表框才會發送該消息。

  WM_VKEYTOITEM:當列表框收到WM_KEYDOWN消息后,向父窗口發送該消息,只有具有LBS_WANTKEYBOARDINPUT風格的列表框才會發送該消息。

  列表框控件的創建

  MFC將列表框控件的所有操作都封裝到了CListBox類中。

  創建列表框控件時,可以在對話框模板中直接拖入列表框控件ListBox,然后添加控件變量使用。但如果需要動態創建列表框,就要用到CListBox類的Create成員函數了。Create成員函數的原型如下:

  virtual BOOL Create(

    DWORD dwStyle,

    const RECT& rect,

    CWnd* pParentWnd,

    UINT nID

  );

  參數rect指定了列表框控件的位置和尺寸,pParentWnd為父窗口的指針,nID用於指定列表框控件的ID。最后終點講講參數dwStyle,它指定了列表框的風格,以下是各種風格的說明:

  LBS_EXTENDEDSEL:支持多重選擇,在點擊列表框項時按住Shift鍵或Ctrl鍵即可選擇多個項。

  LBS_MULTICOLUMN:指定一個水平滾動的多列列表框,通過調用CListBox::SetColumnWidth來設置每列的寬度。

  LBS_MULTIPLESEL:支持多重選擇。列表項的選擇狀態隨着用戶對該項單機或雙擊鼠標而翻轉。

  LBS_NOINTEGRALHEIGHT:列表框的尺寸由應用程序而不是Windows指定。通常,Windows指定尺寸會使列表項的某些部分隱藏起來。

  LBS_NOREDRAW:當選擇發生變化時防止列表框被更新,可發送消息改變改變該風格。

  LBS_NOTIFY:當用戶單擊或雙擊鼠標時通知父窗口。

  LBS_OWNERDRAWFIXED:指定自繪式列表框,即由父窗口負責繪制列表框的內容,並且列表項具有相同的高度。

  LBS_SORT:使插入列表框中的項按升序排列。

  LBS_STANDARD:相當於指定了WS_BORDER|WS_VSCROLL|LBS_SORT。

  LBS_USETABSTOPS:使列表框在顯示列表項時識別並擴展制表符('\t'),默認的制表寬度是32個對話框單位。

  LBS_WANTKEYBOARDINPUT:允許列表框的父窗口接收WM_VKEYTOITEM和WM_CHARTOITEM消息,以響應鍵盤輸入。

  LBS_DISABLEENOSCROLL:使列表框在不需要滾動時顯示一個禁止的垂直滾動條。

  dwStyle可以是以上所列風格的組合。與其他控件一樣,除了這些風格一般還要為列表框控件設置WS_CHILD、WS_VISIBLE、WS_TABSTOP、WS_BORDER、WS_VSCROLL等風格。一般創建單選列表框時,風格要設置為:WS_CHILD|WS_VISIBLE|WS_TABSTOP|LBS_STANDARD,如果不希望列表框排序顯示則應去掉LBS_STANDARD。創建多選列表框時,只需要在單選列表框風風格后添加LBS_MULTIPLESEL或LBS_EXTENDEDSEL風格。

  對於對話框模板中直接添加的列表框控件,其屬性頁中的屬性也包含了以上風格,例如屬性Multicolumn對應的就是LBS_MULTICOLUMN風格。

  CListBox類的主要成員函數

  int GetCount() const;

  返回值:返回列表框中列表項的數目,如果發生錯誤則返回LB_ERR。

 

  int GetSel(int nIndex) const;

  參數:nIndex指定某個列表項的索引。

  返回值:返回nIndex制定的列表項的狀態。如果此列表項倍選擇了則返回一個正值,否則返回0,若發生錯誤則返回LB_ERR。

 

  int SetSel(int nIndex, BOOL bSelect = TRUE);

  此函數用於多選列表框,使用它可以選擇或取消選擇指定的列表項。

  參數:nIndex指定某個列表項的索引,若為-1則相當於指定了所有列表項。bSelect為TRUE時選擇制定列表項,否則取消選擇列表項。

  返回值:如果發生錯誤則返回LB_ERR。

 

  int AddString(LPCTSTR lpszItem);

  此函數用來向列表框中添加字符串。如果列表框指定了LBS_SORT風格,字符串就被以排序順序插入到列表框中,如果沒有指定LBS_SORT風格,字符串就被添加到列表框的結尾。

  參數:lpszItem指定了要添加的字符串。

  返回值:返回字符串在列表框中添加的位置。如果發生錯誤則返回LB_ERR,內存不夠則返回LB_ERRSPACE。

 

  int InsertString(int nIndex, LPCTSTR lpszItem);

  該函數用來在列表框中的指定位置插入字符串。與AddString函數不同的是,InsertString函數不會導致LBS_SORT風格列表框重新排序。不要在具有LBS_SORT風格的列表框中使用InsertString函數,以免破壞列表項的次序。

  參數:參數nIndex給出了插入位置(索引),如果值為-1,則字符串將被添加到列表的末尾。參數lpszItem指定了要插入的字符串。

  返回值:返回實際的插入位置,若發生錯誤,會返回LB_ERR或LB_ERRSPACE。

 

  int DeleteString(UINT nIndex);

  該函數用於刪除指定的列表項。

  參數:nIndex指定了要刪除項的索引。

  返回值:函數的返回值為剩下的列表項數目,如果nIndex超過了實際的列表項總數,則返回LB_ERR。

 

  void ResetContent();

  該函數用於清除所有列表項。

 

  int GetText(int nIndex, LPCTSTR lpszBuffer) const;

  void GetText(int nIndex, CString& rString) const;

  這兩個成員函數用於獲取指定列表項的字符串。參數nIndex指定了列表項的索引。參數lpszBuffer指向一個接收字符串的緩沖區。引用參數rString則指定了接收字符串的CString對象。第一個版本的函數會返回獲得的字符串的長度,若出錯,則返回LB_ERR;第二個版本的函數則不會。

 

  int GetTextLen(int nIndex) const;

  該函數返回指定列表項的字符串的字節長度。

  參數:nIndex指定了列表項的索引。

  返回值:若出錯則返回LB_ERR。

 

  int GetCurSel() const;

  該函數僅適用於單選列表框,用來返回當前被選擇項的索引,如果沒有列表項被選擇或有錯誤發生,則函數返回LB_ERR。

  

  int SetCurSel(int nSelect);

  該函數僅適用於單選列表框,用來選擇指定的列表項。該函數會滾動列表框以使選擇項可見。參數nIndex指定了列表項的索引,若為-1,那么將清除列表框中的選擇。若出錯函數返回LB_ERR。

 

  int GetSelCount() const;

  該函數僅用於多重選擇列表框,它返回選擇項的數目,若出錯函數返回LB_ERR。

 

  int FindString(int nStartAfter, LPCTSTR lpszItem) const;

  該函數用於對列表項進行與大小無關的搜索。參數nStartAfter指定了開始搜索的位置,合理指定nStartAfter可以加快搜索速度,若nStartAfter為-1,則從頭開始搜索整個列表。參數lpszItem指定了要搜索的字符串。函數返回與lpszItem指定的字符串相匹配的列表項的索引,若沒有找到匹配項或發生錯誤,則會返回LB_ERR。FindString函數想從nStartAfter指定的位置開始搜索,若沒有找到匹配項,則會從頭開始搜索列表。只有找到匹配項,或對整個列表搜索完一遍后,搜索過程才會停止,所以不必擔心會漏掉要搜索的列表項。

  

  int SelectString(int nStartAfter, LPCTSTR lpszItem);

  該函數僅適用於單選列表框,用來選擇與指定字符串相匹配的列表項。該函數會滾動列表框以使選擇項可見。參數的意義及搜索的方法與函數FindString類似。如果找到了匹配的項,函數返回該項的索引,如果沒有匹配的項,函數返回LB_ERR並且當前的選擇不被改變。

  

  CListBox類應用實例

  最后給大家寫一個簡單的實例,說明CListBox的幾個成員函數及通知消息等的使用方法。此實例實現的功能:在單選列表框中顯示一個網站列表,然后再用鼠標左鍵選擇某列表項時,將選中列表項的文本顯示到編輯框中。下面是具體實現步驟:

  1、創建一個基於對話框的MFC工程,名稱設置為”MFCListBoxDemo“。

  2、在自動生成的對話框模板IDD_MFCLISTBOXDEMO_DIALOG中,刪除"TODO:Place dialog controls here."靜態文本框、“確定”按鈕和“取消”按鈕。添加一個ListBox控件,ID設置為IDC_WEB_LIST,Sort屬性設為False,以取消排序顯示。再添加一個靜態文本控件和一個編輯框,靜態文本控件的Caption屬性設為“您選擇的站點:”,編輯框的ID設為IDC_SEL_WEB_EDIT,Read Only屬性設為True。此時的對話框模板如下圖:

  3、為列表框IDC_WEB_LIST添加CListBox類型的控件變量m_listBox。

  4、在對話框初始化時,我們將站點名加入到列表框,那么需要修改CMFCListBoxDemoDlg::OnInitDialog()函數為:

C++代碼:

BOOL CMFCListBoxDemoDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 將“關於...”菜單項添加到系統菜單中。

	// IDM_ABOUTBOX 必須在系統命令范圍內。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 設置此對話框的圖標。  當應用程序主窗口不是對話框時,框架將自動
	//  執行此操作
	SetIcon(m_hIcon, TRUE);			// 設置大圖標
	SetIcon(m_hIcon, FALSE);		// 設置小圖標

	// TODO: 在此添加額外的初始化代碼
	m_listBox.AddString(_T("新浪"));	// 在列表框末尾添加字符串“新浪”
	m_listBox.AddString(_T("博客園"));	// 在列表框末尾添加字符串“博客園”
	m_listBox.AddString(_T("貓撲"));	// 在列表框結尾處添加字符串“貓撲”
	m_listBox.AddString(_T("網易"));	// 在列表框結尾處添加字符串“網易”
	m_listBox.InsertString(2, _T("百度"));	// 在列表框中索引為2的位置插入字符串“百度”

	return TRUE;  // 除非將焦點設置到控件,否則返回 TRUE
}

  5、我們希望在選中列表項改變時,將最新的選擇項實時顯示到編輯框中,那么這就要用到LBN_SELCHANGE通知消息。為列表框IDC_WEB_LIST的通知消息LBN_SELCHANGE添加消息處理函數CMFCListBoxDemoDlg::OnLbnSelchangeWebList(),並修改如下:

C++代碼:

void CMFCListBoxDemoDlg::OnLbnSelchangeWebList()
{
	// TODO: 在此添加控件通知處理程序代碼
	CString strText;
	int nCurSel;

	nCurSel = m_listBox.GetCurSel();	// 獲取當前選中列表項
	m_listBox.GetText(nCurSel, strText);	// 獲取選中列表項的字符串
	SetDlgItemText(IDC_SEL_WEB_EDIT, strText);	//將選中列表項的字符串顯示到編輯框中
}

  6、運行程序,彈出結果對話框,在對話框的列表中用鼠標改變選中項時,編輯框的顯示會相應改變。效果圖如下:

  關於列表框ListBox的講解就到此為止了。如果大家想試驗更多的列表框成員函數,可以在上面的小例子中加入更多的更能來體會。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM