第十二章 列表框和組合框
列表框是顯示一系列項供用戶選擇的控件,對選中的項可以進行後續的處理。用戶選擇可以是多項的,但本章的例程設計爲單選的。組合框是一個編輯框帶一個可以下拉的列表框,用戶在下拉框中選擇的項會進入編輯框中,再進行後續處理,選擇也可以用鍵盤的光標鍵。在編輯框中也可以直接輸入。
本章要點
1 列表框的設計、項的添加和刪除
2 組合框的設計和使用
12.1 ListCombo程序運行時的界面和功能
List1在初始化時加入了六項。點擊[<]按鈕就把選中的項移動到List2中去。點擊[>]按鈕則相反。點擊[<<]和[>>]按鈕則移動全部項。用[清除列表]按鈕可刪除List1的全部項。[加入到]按鈕把你選中的在編輯框中項添加到List1中,[加入全部]按鈕則把組合框設置的所有項添加到List1中。組合框預置了“中國”這一項,但沒有設計刪除功能。列表框和組合框都有一個從0開始的整數索引和一個用於顯示的文本。
12.2 對話框界面設計
按控件屬性表設計界面。
控件類型 | 標題 | ID and Genaral | Styles | Extended Styles |
listBox |
IDC_LIST1 顯示checked |
選擇Simple,Border Virteber scroll |
無 | |
listBox |
IDC_LIST2 顯示checked |
選擇Simple,Border Virteber scroll |
無 | |
ComboBox |
IDC_CONTRIES_COMBO 顯示checked |
類型:Drop list Virteber scroll |
Static edge | |
Button | < | IDC_MOVE_BUTTON | 無 | 無 |
Button | > | IDC_BACK_BUTTON | 無 | 無 |
Button | << | IDC_MOVEALL_BUTTON | 無 | 無 |
Button | >> | IDC_BACKALL_BUTTON | 無 | 無 |
Button | 清除列表 | IDC_CLEAR_BUTTON | 無 | Client edge |
Button | 加入到 | IDC_ADD_BUTTON | 無 | Client edge |
Button | 加入全部 | IDC_ADDALL_BUTTON | 無 | Client edge |
Button | 退出 | IDC_EXIT_BUTTON | 無 |
Client edge Static edge Modal Frame |
屬性表中列出的表示“選中”,TAB複選框都要選中,就省略了。組合框可以在DATA屬性頁中設置項的文本,本例採用這種方法。其數據是:
中國,美國,俄羅斯,英國,法國,德國,印度,巴基斯坦,
日本,加拿大,澳大利亞,韓國,伊朗,伊拉克
逗號處要改爲換行,換行用Ctrl+<回車鍵>。設計好的界面如圖chap12-02所示。
12.3 設計變量和編寫代碼
1 爲三個列表框和組合框引進變量
因爲我們要對列表框的項進行操作,所以要申明三個對象類型的變量
m_myList1
m_myList2
m_myCombo。
2 定義一個字符串數組
定義一個字符串數組m_myItems用來存放組合框的項的文本。在對話框的頭文件的類CListCombaDlg的構造函數中申明:
CString m_myItems[20];
3 給初始化函數編寫代碼
在OnInitDialog()中我們要從組合框控件獲取項目的文本,給字符串數組m_myItems賦值。再用它的前六項爲List1初始化。最後爲組合框設置項“中國”爲預選項。
從組合框控件獲取項用函數GetLBText(index, str),它把索引值爲index的項的文本拷貝給str。給列表框賦值用AddString(string)函數,它在列表的尾部增加一項。類似地還可以用插入函數InsearString(...)。在// TODO: Add extra initialization here 這行的後面,我們添加如下代碼:
int count = m_myCombo.GetCount(); //獲取組合框的項數
int i =0;
//從組合框控件獲取項的文本
for(i =0; i<count; i++)
m_myCombo.GetLBText(i, m_myItems[i]);
//List1初始化,六項
for(i =0; i<6 ; i++)
m_myList1.AddString(m_myItems[i]);
//設置組合框默認選擇項爲"中國"
m_myCombo.SetCurSel(0);
4 給4個移動按鈕寫代碼
MOVE按鈕[<]的功能是從List1中得到用戶選定頂的索引號,再從這索引號獲取選定頂的文本,然後刪除這一項,在List2中添加一項。當前項
獲取索引號函數 index=GetCurSel()返回整數。 獲取選定項的文本用函數GetText(index, item),它把指定項的文本拷貝到字符串item中。
OnMoveButton()函數的完整代碼如下:
void CListCombaDlg::OnMoveButton()
{
CString item;
int index = m_myList1.GetCurSel(); //獲取選定頂索引號
m_myList1.GetText(index, item); //獲取選定頂的文本
m_myList1.DeleteString(index); //刪除一項
m_myList2.AddString(item); //添加到List2中
m_myList1.SetCurSel(0); //設置首項爲當前項
}
MOVEALL按鈕的代碼與上面的類似,加上循環語句就行。
void CListCombaDlg::OnMoveallButton()
{
// TODO: Add your control notification handler code here
CString item;
int index =0 ;
while(m_myList1.GetCount() >0){
m_myList1.GetText(0, item);
m_myList1.DeleteString(0);
m_myList2.AddString(item);
};
}
BACK和BACKALL按鈕的代碼和上面的一樣,只要把m_myList1和m_myList2對調就行。
5 從組合框向列表框1加入當前項的代碼
這與列表框不同的是獲取文本的函數名不大一樣,用函數GetLBText,其餘都相同。在OnAddButton()中加入代碼:
void CListCombaDlg::OnBackallButton()
{
// TODO: Add your control notification handler code here
CString item;
int index =0 ;
while(m_myList2.GetCount() >0){
m_myList2.GetText(0, item);
m_myList2.DeleteString(0);
m_myList1.AddString(item);
};
}
從組合框向列表框1加入全部項的代碼如下:
void CListCombaDlg::OnAddallButton()
{
//Clear old items in Linst at first
CString item;
while(m_myList1.GetCount()>0)
m_myList1.DeleteString(0);
int n = m_myCombo.GetCount();
//Add all items
for(int i=0; i<n; i++){
m_myCombo.GetLBText(i, item);
m_myList1.AddString(item);
}
}
6 [清除列表]和[退出]按鈕的代碼
[清除列表]的按鈕的代碼:
while(m_myList1.GetCount()>0)
m_myList1.DeleteString(0);
[退出]按鈕的代碼: OnOK();
12.4 編譯和運行
至此,我們完成了界面設計和代碼編寫,可以編譯和Build了。編譯通過就可以在運行中測試程序,檢查是否滿足我們的設計要求。但是,代碼編寫常常會有許多錯誤,編譯器會報告一大堆錯誤。雖然指出了錯誤所在的行,但要明白是什麼錯誤還是很費勁的。如果我們在完成一部分工作後就編譯一次,錯誤就比較少,容易找到和糾正。所以我們分以下幾步來編譯。
1、界面完成後編譯一次,這時運行可以看到組合框有了信息和可以選擇了。
2、對話框初始化編寫後編譯和運行一次,這時可以看到列表框有了信息。
3、MOVE按鈕寫了代碼後編譯和運行一次,這時可以測試移動功能是否正確。如果成功,那這代碼可以放心地複製到其他三個按鈕去了。
4、全部完成後的編譯和運行。
12.5 小結
1 列表框和組合框屬性設置中有類型選擇
組合框有三種情況:Simple, Dropdown, Drop List。Simple類型的組合框的列表框部分是固定顯示的,不能下拉;而其餘兩種帶一個下拉手柄。設計中別忘記添加滾動條。Dropdown與Drop List的區別是後者的編輯框不能輸入。列表框也有三種情況:Simple, Multiple, Extended, 它們決定了用戶選取項的方法。Simple模式只能夠選取單項,Multiple模式可以按Ctrl鍵+鼠標左鍵選取多個項,而Extended則可以通過鼠標拖處矩形一次選取連續的項,也可以加按Ctrl鍵作多次選擇。
2 列表框在屬性頁不能設置項的文本(字符串),而組合框能。
3 列表框和組合框中的“項”都有索引號(0,1,2,...)和文本(在窗口顯示)。兩者都有成員函數來獲取和設置這些信息。得到文本的函數名稱不一樣,列表框是GetText(),組合框是GetLBText()。字母LB的意思是ListBox,GetLBText的意思是“從自身的列表框中獲取文本”。
4 列表框和組合框常用的幾個函數原型
列表框的取索引號和文本的函數原型
獲取文本:
void GetText( int nIndex, CString& rString ) const;
用於單選模式的獲取和設置索引號:
int GetCurSel( ) const;
int SetCurSel( int nSelect );
用於多選模式的:
int GetSel( int nIndex ) const;
上式如果nIndex項是被選中的,就返回它的索引號,否則返回0。
int SetSel( int nIndex, BOOL bSelect = TRUE );
bSelect = TRUE就選中索引爲nIndex的項,如是FALSE,則取消“選中”:如果nIndex=-1,就是全“選中”或全“不選中”。
組合框的獲取索引號和文本的函數原型
int GetCurSel( ) const;
int SetCurSel( int nSelect );
void GetLBText( int nIndex, CString& rString ) const;
添加、插入和刪除項的函數原型
int AddString( LPCTSTR lpszItem );
int InsertString( int nIndex, LPCTSTR lpszItem );
int DeleteString( UINT nIndex );
習題和思考
1 重新創建MListCombo,把兩個列表框設計爲多選項的。
2 重新創建EListCombo,把兩個列表框設計爲可擴展選項的。