vc++常用控件

傳統控件的用法:
.1.1 傳統控件的控件通知消息

 

  控件通過向父窗口發送控件通知消息來表明發生了某種事件.例如,當用戶在按鈕上單擊鼠標時,按鈕控件會向父窗口發送BN_CLICKED消息.傳統控件的通知消息實際上是通過WM_COMMAND消息發給父窗口的(滾動條除外),在該消息的wParam中含有通知消息碼(如BN_CLICKED)和控件的ID,在lParam中則包含了控件的句柄.

  利用ClassWizard可以很容易地爲控件通知消息加入消息映射和消息處理函數,這在上一章中已經演示過了.傳統控件的消息映射宏是ON_XXXX,其中XXXX表示通知消息碼,如BN_CLICKED.ON_XXXX消息映射如下所示,該宏有兩個參數,一個是控件的ID,一個是消息處理函數名.

ON_XXXX(nID, memberFxn)

消息處理函數的聲明應該有如下形式:

afx_msg void memberFxn( );

例如,某按鈕的BN_CLICKED消息的消息映射及其處理函數的聲明如下所示

ON_BN_CLICKED(IDC_ADD,OnAdd)

afx_msg void OnAdd( );

  有時,爲了處理方便,需要把多個ID連續的控件發出的相同消息映射到同一個處理函數上.這就要用到ON_CONTROL_RANGE宏.ON_CONTROL_RANGE消息映射宏的第一個參數是控件消息碼,第二和第三個參數分別指明瞭一組連續的控件ID中的頭一個和最後一個ID,最後一個參數是消息處理函數名。例如,要處理一組單選按鈕發出的BN_CLICKED消息,相應的消息映射如下所示:

ON_CONTROL_RANGE(BN_CLICKED, IDC_FIRST, IDC_LAST, OnRadioClicked)

函數OnRadioClicked的聲明如下,該函數比上面的OnAdd多了一個參數nID以說明發送通知消息的控件ID.

afx_msg void OnRadioClicked(UINT nID);

ClassWizard不支持ON_CONTROL_RANGE宏,所以需要手工建立消息映射和消息處理函數.

提示:事實上,在使用ClassWizard時只要運用一個小小的技巧,就可以把不同控件的通知消息映射到同一個處理函數上,也可以把一個控件的不同通知消息映射到同一個處理函數上.這個技巧就是在用ClassWizard創建消息處理函數時,指定相同的函數名即可.此方法的優點在於控件的ID不必是連續的,缺點是處理函數沒有nID參數,因而不能確定是哪一個控件發送的消息. 

6.1.2 靜態控件

  靜態控件包括靜態正文(Static Text)和圖片控件(Picture)。靜態正文控件用來顯示正文。圖片控件可以顯示位圖、圖標、方框和圖元文件,在圖片控件中顯示圖片的好處是不必操心圖片的重繪問題。靜態控件不能接收用戶的輸入。在上一章中,讀者已經用過靜態正文和組框控件。圖片控件的例子可以在AppWizard創建的IDD_ABOUTBOX對話框模板中找到,在該模板中有一個圖片控件用來顯示圖標。

  靜態控件的主要起說明和裝飾作用。MFC的CStatic類封裝了靜態控件。CStatic類的成員函數Create負責創建靜態控件,該函數的聲明爲

BOOL Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff );

  參數lpszText指定了控件顯示的正文。dwStyle指定了靜態控件的風格,表6.1顯示了靜態控件的各種風格,dwStyle可將這些風格組合起來。rect是一個對RECT或CRect結構的引用,用來說明控件的位置和尺寸。pParentWnd指向父窗口,該參數不能爲NULL。nID則說明了控件的ID。如果創建成功,該函數返回TRUE,否則返回FALSE.

表6.1 靜態控件的風格

控件風格
 含義
 
SS_BLACKFRAME
 指定一個具有與窗口邊界同色的框(缺省爲黑色)。
 
SS_BLACKRECT
 指定一個具有與窗口邊界同色的實矩形(缺省爲黑色)。
 
SS_CENTER
 使顯示的正文居中對齊,正文可以迴繞。
 
SS_GRAYFRAME
 指定一個具有與屏幕背景同色的邊框。
 
SS_GRAYRECT
 指定一個具有與屏幕背景同色的實矩形。
 
SS_ICON
 使控件顯示一個在資源中定義的圖標,圖標的名字有Create函數的lpszText參數指定。
 
SS_LEFT
 左對齊正文,正文能迴繞。
 
SS_LEFTNOWORDWRAP
 左對齊正文,正文不能迴繞。
 
SS_NOPREFIX
 使靜態正文串中的&不是一個熱鍵提示符。
 
SS_NOTIFY
 使控件能向父窗口發送鼠標事件消息。
 
SS_RIGHT
 右對齊正文,可以迴繞。
 
SS_SIMPLE
 使靜態正文在運行時不能被改變並使正文顯示在單行中。
 
SS_USERITEM
 指定一個用戶定義項。
 
SS_WHITEFRAME
 指定一個具有與窗口背景同色的框(缺省爲白色)。
 
SS_WHITERECT
 指定一個具有與窗口背景同色的實心矩形(缺省爲白色)。
 

  除了上表中的風格外,一般還要爲控件指定WS_CHILD和WS_VISIBLE窗口風格。一個典型的靜態正文控件的風格爲WS_CHILD|WS_VISIBLE|SS_LEFT。

  對於用對話框模板編輯器創建的靜態控件,可以在控件的屬性對話框中指定表6.1中列出的控件風格。例如,可以在靜態正文控件的屬性對話框中選擇Simple,這相當於指定了SS_SIMPLE風格。

  Cstatic類主要的成員函數在表6.2中列出。可以利用CWnd類的成員函數GetWindowText,SetWindowText和GetWindowTextLength等函數來查詢和設置靜態控件中顯示的正文.

表6.2 CStatic類的主要成員函數

函數聲明
 用途
 
HBITMAP SetBitmap( HBITMAP hBitmap );
 指定要顯示的位圖。
 
HBITMAP GetBitmap( ) const;
 獲取由SetBitmap指定的位圖。
 
HICON SetIcon( HICON hIcon );
 指定要顯示的圖標。
 
HICON GetIcon( ) const;
 獲取由SetIcon指定的圖標。
 
HCURSOR SetCursor( HCURSOR hCursor );
 指定要顯示的光標圖片。
 
HCURSOR GetCursor( );
 獲取由SetCursor指定的光標。
 
HENHMETAFILE SetEnhMetaFile( HENHMETAFILE hMetaFile );
 指定要顯示的增強圖元文件。
 
HENHMETAFILE GetEnhMetaFile( ) const;
 獲取由SetEnhMetaFile指定的圖元文件。
 

  靜態控件較簡單,故這裏就不舉例說明了。

6.1.3 按鈕控件

  按鈕是指可以響應鼠標點擊的小矩形子窗口。按鈕控件包括命令按鈕(Pushbutton)、檢查框(Check Box)、單選按鈕(Radio Button)、組框(Group Box)和自繪式按鈕(Owner-draw Button)。命令按鈕的作用是對用戶的鼠標單擊作出反應並觸發相應的事件,在按鈕中既可以顯示正文,也可以顯示位圖。選擇框控件可作爲一種選擇標記,可以有選中、不選中和不確定三種狀態。單選按鈕控件一般都是成組出現的,具有互斥的性質,即同組單選按鈕中只能有一個是被選中的。組框用來將相關的一些控件聚成一組.自繪式按鈕是指由程序而不是系統負責重繪的按鈕。

  按鈕主要是指命令按鈕、選擇框和單選按鈕。後二者實際上是一種特殊的按鈕,它們有選擇和未選擇狀態。當一個選擇框處於選擇狀態時,在小方框內會出現一個“√”,當單選按鈕處於選擇狀態時,會在圓圈中顯示一個黑色實心圓。此外,檢查框還有一種不確定狀態,這時檢查框呈灰色顯示,不能接受用戶的輸入,以表明控件是無效的或無意義的。

  按鈕控件會向父窗口發出如表6.3所示的控件通知消息。

表6.3 按鈕控件的通知消息

消息
 含義
 
BN_CLICKED
 用戶在按鈕上單擊了鼠標。
 
BN_DOUBLECLICKED
 用戶在按鈕上雙擊了鼠標。
 

FC的CButton類封裝了按鈕控件。CButton類的成員函數Create負責創建按鈕控件,該函數的聲明爲

BOOL Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

  參數lpszCaption指定了按鈕顯示的正文。dwStyle指定了按鈕的風格,如表6.4所示,dwStyle可以是這些風格的組合。rect說明了按鈕的位置和尺寸。pParentWnd指向父窗口,該參數不能爲NULL。nID是按鈕的ID。如果創建成功,該函數返回TRUE,否則返回FALSE.

 

表6.4 按鈕的風格

控件風格
 含義
 
BS_AUTOCHECKBOX
 同BS_CHECKBOX,不過單擊鼠標時按鈕會自動反轉。
 
BS_AUTORADIOBUTTON
 同BS_RADIOBUTTON,不過單擊鼠標時按鈕會自動反轉。
 
BS_AUTO3STATE
 同BS_3STATE,不過單擊按鈕時會改變狀態。
 
BS_CHECKBOX
 指定在矩形按鈕右側帶有標題的選擇框。
 
BS_DEFPUSHBUTTON
 指定缺省的命令按鈕,這種按鈕的周圍有一個黑框,用戶可以按回車鍵來快速選擇該按鈕。
 
BS_GROUPBOX
 指定一個組框。
 
BS_LEFTTEXT
 使控件的標題顯示在按鈕的左邊。
 
BS_OWNERDRAW
 指定一個自繪式按鈕。
 
BS_PUSHBUTTON
 指定一個命令按鈕。
 
BS_RADIOBUTTON
 指定一個單選按鈕,在圓按鈕的右邊顯示正文。
 
BS_3STATE
 同BS_CHECKBOX,不過控件有三種狀態:選擇、未選擇和變灰。
 

 

 

除了上表中的風格外,一般還要爲控件指定WS_CHILD、WS_VISIBLE和WS_TABSTOP窗口風格,WS_TABSTOP使控件具有Tabstop屬性。創建一個普通按鈕應指定的風格爲WS_CHILD|WS_VISIBLE|WS_TABSTOP。創建一個普通檢查框應指定風格WS_CHILD|WS_VISIBLE|WS_TABSTOP| BS_AUTOCHECKBOX。創建組中第一個單選按鈕應指定風格WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_GROUP| BS_AUTORADIOBUTTON,組中其它單選按鈕應指定風格則不應該包括WS_TABSTOP和WS_GROUP。

對於用對話框模板編輯器創建的按鈕控件,可以在控件的屬性對話框中指定表6.4中列出的控件風格。例如,在命令按鈕的屬性對話框中選擇Default button,相當於指定了BS_DEFPUSHBUTTON。

CButton類的主要的成員函數有:

UINT GetState( ) const;
該函數返回按鈕控件的各種狀態。可以用下列屏蔽值與函數的返回值相與,以獲得各種信息。

0x0003。用來獲取檢查框或單選按鈕的狀態。0表示未選中,1表示被選中,2表示不確定狀態(僅用於檢查框)。

0x0004。用來判斷按鈕是否是高亮度顯示的。非零值意味着按鈕是高亮度顯示的。當用戶點擊了按鈕並按主鼠標左鍵時,按鈕會呈高亮度顯示。

0x0008。非零值表示按鈕擁有輸入焦點。

void SetState( BOOL bHighlight );
當參數bHeightlight值爲TRUE時,該函數將按鈕設置爲高亮度狀態,否則,去除按鈕的高亮度狀態。

int GetCheck( ) const;
返回檢查框或單選按鈕的選擇狀態。返回值0表示按鈕未被選擇,1表示按鈕被選擇,2表示按鈕處於不確定狀態(僅用於檢查框)。

void SetCheck( int nCheck );
設置檢查框或單選按鈕的選擇狀態。參數nCheck值的含義與GetCheck返回值相同。

UINT GetButtonStyle( ) const;
獲得按鈕控件的BS_XXXX風格。

void SetButtonStyle( UINT nStyle, BOOL bRedraw = TRUE );
設置按鈕的風格。參數nStyle指定了按鈕的風格。bRedraw爲TRUE則重繪按鈕,否則就不重繪。

HBITMAP SetBitmap( HBITMAP hBitmap );
設置按鈕顯示的位圖。參數hBitmap指定了位圖的句柄。該函數還會返回按鈕原來的位圖。

HBITMAP GetBitmap( ) const;
返回以前用SetBitmap設置的按鈕位圖。

HICON SetIcon( HICON hIcon );
設置按鈕顯示的圖標。參數hIcon指定了圖標的句柄。該函數還會返回按鈕原來的圖標。

HICON GetIcon( ) const;
返回以前用SetIcon設置的按鈕圖標。

HCURSOR SetCursor( HCURSOR hCursor );
設置按鈕顯示的光標圖。參數hCursor指定了光標的句柄。該函數還會返回按鈕原來的光標。

HCURSOR GetCursor( );
返回以前用GetCursor設置的光標。

 

另外,可以使用下列的一些與按鈕控件有關的CWnd成員函數來設置或查詢按鈕的狀態。用這些函數的好處在於不必構建按鈕控件對象,只要知道按鈕的ID,就可以直接設置或查詢按鈕。

void CheckDlgButton( int nIDButton, UINT nCheck );
用來設置按鈕的選擇狀態。參數nIDButton指定了按鈕的ID。nCheck的值0表示按鈕未被選擇,1表示按鈕被選擇,2表示按鈕處於不確定狀態。

void CheckRadioButton( int nIDFirstButton, int nIDLastButton, int nIDCheckButton );
用來選擇組中的一個單選按鈕。參數nIDFirstButton指定了組中第一個按鈕的ID,nIDLastButton指定了組中最後一個按鈕的ID,nIDCheckButton指定了要選擇的按鈕的ID。

int GetCheckedRadioButton( int nIDFirstButton, int nIDLastButton );
該函數用來獲得一組單選按鈕中被選中按鈕的ID。參數nIDFirstButton說明了組中第一個按鈕的ID,nIDLastButton說明了組中最後一個按鈕的ID。

UINT IsDlgButtonChecked( int nIDButton ) const;
返回檢查框或單選按鈕的選擇狀態。返回值0表示按鈕未被選擇,1表示按鈕被選擇,2表示按鈕處於不確定狀態(僅用於檢查框)。

 

可以調用CWnd成員函數GetWindowText,GetWindowTextLength和SetWindowText來查詢或設置按鈕中顯示的正文.

MFC還提供了CButton的派生類CBitmapButton。利用該類可以創建一個擁有四幅位圖的命令按鈕,按鈕在不同狀態時會顯示不同的位圖,這樣可以使界面顯得生動活潑。如果讀者對CBitmapButton感興趣,可以參看VC5.0隨盤提供的MFC例子CTRLTEST。

在上一章的Register例子中已演示了各種按鈕控件的使用,故這裏就不再舉例了。

 

 

6.1.4 編輯框控件

編輯框(Edit Box)控件實際上是一個簡易的正文編輯器,用戶可以在編輯框中輸入並編輯正文。編輯框既可以是單行的,也可以是多行的,多行編輯框是從零開始編行號的.在一個多行編輯框中,除了最後一行外,每一行的結尾處都有一對回車換行符(用"/r/n"表示).這對回車換行符是正文換行的標誌,在屏幕上是不可見的.

編輯框控件會向父窗口發出如表6.5所示的控件通知消息。

 

表6.5

消息
 含義
 
EN_CHANGE
 編輯框的內容被用戶改變了。與EN_UPDATE不同,該消息是在編輯框顯示的正文被刷新後才發出的。
 
EN_ERRSPACE
 編輯框控件無法申請足夠的動態內存來滿足需要。
 
EN_HSCROLL
 用戶在水平滾動條上單擊鼠標。
 
EN_KILLFOCUS
 編輯框失去輸入焦點。
 
EN_MAXTEXT
 輸入的字符超過了規定的最大字符數。在沒有ES_AUTOHSCROLL或ES_AUTOVSCROLL的編輯框中,當正文超出了編輯框的邊框時也會發出該消息。
 
EN_SETFOCUS
 編輯框獲得輸入焦點。
 
EN_UPDATE
 在編輯框準備顯示改變了的正文時發送該消息。
 
EN_VSCROLL
 用戶在垂直滾動條上單擊鼠標。
 

 

 

MFC的CEdit類封裝了編輯框控件。CEdit類的成員函數Create負責創建按鈕控件,該函數的聲明爲

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

 

參數dwStyle指定了編輯框控件風格,如表6.6所示,dwStyle可以是這些風格的組合。rect指定了編輯框的位置和尺寸。pParentWnd指定了父窗口,不能爲NULL。編輯框的ID由nID指定。如果創建成功,該函數返回TRUE,否則返回FALSE.

 

表6.6 編輯框控件的風格

控件風格
 含義
 
ES_AUTOHSCROLL
 當用戶在行尾鍵入一個字符時,正文將自動向右滾動10個字符,當用戶按回車鍵時,正文總是滾向左邊。
 
ES_AUTOVSCROLL
 當用戶在最後一個可見行按回車鍵時,正文向上滾動一頁。
 
ES_CENTER
 在多行編輯框中使正文居中。
 
ES_LEFT
 左對齊正文。
 
ES_LOWERCASE
 把用戶輸入的字母統統轉換成小寫字母。
 
ES_MULTILINE
 指定一個多行編輯器。若多行編輯器不指定ES_AUTOHSCROLL風格,則會自動換行,若不指定ES_AUTOVSCROLL,則多行編輯器會在窗口中正文裝滿時發出警告聲響。
 
ES_NOHIDESEL
 缺省時,當編輯框失去輸入焦點後會隱藏所選的正文,當獲得輸入焦點時又顯示出來。設置該風格可禁止這種缺省行爲。
 
ES_OEMCONVERT
 使編輯框中的正文可以在ANSI字符集和OEM字符集之間相互轉換。這在編輯框中包含文件名時是很有用的。
 
ES_PASSWORD
 使所有鍵入的字符都用“*”來顯示。
 
ES_RIGHT
 右對齊正文。
 
ES_UPPERCASE
 把用戶輸入的字母統統轉換成大寫字母。
 
ES_READONLY
 將編輯框設置成只讀的。
 
ES_WANTRETURN
 使多行編輯器接收回車鍵輸入並換行。如果不指定該風格,按回車鍵會選擇缺省的命令按鈕,這往往會導致對話框的關閉。
 

 

 

除了上表中的風格外,一般還要爲控件指定WS_CHILD、WS_VISIBLE、WS_TABSTOP和WS_BORDER窗口風格,WS_BORDER使控件帶邊框。創建一個普通的單行編輯框應指定風格爲WS_CHILD|WS_VISIBLE|WS_TABSTOP |WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,這將創建一個帶邊框、左對齊正文、可水平滾動的單行編輯器。要創建一個普通多行編輯框,還要附加ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL |WS_HSCROLL| WS_VSCROLL風格,這將創建一個可水平和垂直滾動的,帶有水平和垂直滾動條的多行編輯器。

對於用對話框模板編輯器創建的編輯框控件,可以在控件的屬性對話框中指定表6.6中列出的控件風格。例如,在屬性對話框中選擇Multi-line項,相當與指定了ES_MULTILINE風格。

編輯框支持剪貼板操作。CEdit類提供了一些與剪貼板有關的成員函數,如表6.7所示。

 

表6.7 與剪切板有關的CEdit成員函數

函數聲明
 用途
 
void Clear( )
 清除編輯框中被選擇的正文。
 
void Copy( )
 把在編輯框中選擇的正文拷貝到剪貼板中。
 
void Cut( )
 清除編輯框中被選擇的正文並把這些正文拷貝到剪貼板中。
 
void Paste( )
 將剪貼板中的正文插入到編輯框的當前插入符處。
 
BOOL Undo( )
 撤消上一次鍵入。對於單行編輯框,該函數總返回TRUE,對於多行編輯框,返回TRUE表明操作成功,否則返回FALSE。
 

 

 

可以用下列CEdit或CWnd類的成員函數來查詢編輯框。在學習下面的函數時,讀者會經常遇到術語字符索引.字符的字符索引是指從編輯框的開頭字符開始的字符編號,它是從零開始編號的.也就是說,字符索引實際上是指當把整個編輯正文看作一個字符串數組時,該字符所在的數組元素的下標.

 

int GetWindowText( LPTSTR lpszStringBuf, int nMaxCount ) const;
void GetWindowText( CString& rString ) const;
這兩個函數均是CWnd類的成員函數,可用來獲得窗口的標題或控件中的正文。第一個版本的函數用lpszStringBuf參數指向的字符串數組作爲拷貝正文的緩衝區,參數nMaxCount可以拷貝到緩衝區中的最大字符數,該函數返回以字節爲單位的實際拷貝字符數(不包括結尾的空字節)。第二個版本的函數用一個CString對象作爲緩衝區。

int GetWindowTextLength( ) const;
CWnd的成員函數,可用來獲得窗口的標題或控件中的正文的長度。

DWORD GetSel( ) const;
void GetSel( int& nStartChar, int& nEndChar ) const;
兩個函數都是CEdit的成員函數,用來獲得所選正文的位置。GetSel的第一個版本返回一個DWORD值,其中低位字說明了被選擇的正文開始處的字符索引,高位字說明了選擇的正文結束處的後面一個字符的字符索引,如果沒有正文被選擇,那麼返回的低位和高位字節都是當前插入符所在字符的字符索引。GetSel的第二個版本的兩個參數是兩個引用,其含義與第一個版本函數返回值的低位和高位字相同。

int LineFromChar( int nIndex = –1 ) const;
CEdit的成員函數,僅用於多行編輯框,用來返回指定字符索引所在行的行索引(從零開始編號)。參數nIndex指定了一個字符索引,如果nIndex是-1,那麼函數將返回選擇正文的第一個字符所在行的行號,若沒有正文被選擇,則該函數會返回當前的插入符所在行的行號。

int LineIndex( int nLine = –1 ) const;
CEdit的成員函數,僅用於多行編輯框,用來獲得指定行的開頭字符的字符索引,如果指定行超過了編輯框中的最大行數,該函數將返回-1。參數nLine是指定了從零開始的行索引,如果它的值爲-1,則函數返回當前的插入符所在行的字符索引。

int GetLineCount( ) const;
CEdit的成員函數,僅用於多行編輯框,用來獲得正文的行數。如果編輯框是空的,那麼該函數的返回值是1。

int LineLength( int nLine = –1 ) const;
CEdit的成員函數,用於獲取指定字符索引所在行的字節長度(行尾的回車和換行符不計算在內)。參數nLine說明了字符索引.如果nLine的值爲-1,則函數返回當前行的長度(假如沒有正文被選擇),或選擇正文佔據的行的字符總數減去選擇正文的字符數(假如有正文被選擇)。若用於單行編輯框,則函數返回整個正文的長度。

int GetLine( int nIndex, LPTSTR lpszBuffer ) const;
int GetLine( int nIndex, LPTSTR lpszBuffer, int nMaxLength ) const;
CEdit的成員函數,僅用於多行編輯框,用來獲得指定行的正文(不包括行尾的回車和換行符)。參數nIndex是行號,lpszBuffer指向存放正文的緩衝區,nMaxLength規定了拷貝的最大字節數,若。函數返回實際拷貝的字節數,若指定的行號大於編輯框的實際行數,則函數返回0。需要注意的是,GetLine函數不會在緩衝區中字符串的末尾加字符串結束符(NULL).

 

下列CWnd或CEdit類的成員函數可用來修改編輯框控件。

void SetWindowText( LPCTSTR lpszString );
CWnd的成員函數,可用來設置窗口的標題或控件中的正文。參數lpszString可以是一個CString對象,或是一個指向字符串的指針。

void SetSel( DWORD dwSelection, BOOL bNoScroll = FALSE );
void SetSel( int nStartChar, int nEndChar, BOOL bNoScroll = FALSE );
CEdit的成員函數,用來選擇編輯框中的正文。參數dwSelection的低位字說明了選擇開始處的字符索引,高位字說明了選擇結束處的字符索引。如果低位字爲0且高位字節爲-1,那麼就選擇所有的正文,如果低位字節爲-1,則取消所有的選擇.參數bNoScroll的值如果是FALSE,則滾動插入符並使之可見,否則就不滾動.參數nStartChar和nEndChar的含義與參數dwSelection的低位字和高位字相同.

void ReplaceSel( LPCTSTR lpszNewText, BOOL bCanUndo = FALSE );
CEdit的成員函數,用來將所選正文替換成指定的正文.參數lpszNewText指向用來替換的字符串.參數bCanUndo的值爲TRUE說明替換是否可以被撤消的.

 

在調用上述函數時,如果涉及的是一個多行編輯框,那麼除了LineLength和GetLine函數外,都要把回車和換行符考慮在內.例如,假設在編輯框中有如下幾行正文:

abcd

efg

ij

那麼字母"e"的字符索引是6而不是4,因爲"abcd"後面還有一對回車換行符.調用LineLength(7)會返回第二行的長度3.調用LineIndex(2)會得到11.調用LineFromChar(8)會返回1.如果沒有選擇任何正文,並且插入符在字母"e"上,那麼調用GetSel返回值的低位和高位字都是6.

通過分析上述函數,我們可以總結出一些查詢和設置編輯框的方法.

調用CWnd的成員函數GetWindowText和SetWindowText可以查詢和設置編輯框的整個正文,在上一章的Register程序中,我們就使用過這兩個函數.

如果想對多行編輯框逐行查詢,那麼應該先調用GetLineCount獲得總行數,然後再調用GetLine來獲取每一行的正文.下面一段代碼演示瞭如何對多行編輯框進行逐行查詢.

char buf[40];

int total=MyEdit.GetLineCount();

int i,length;

for(i=0;i<total;i++)

{

length=MyEdit.GetLine(i,buf,39);

buf[length]=0; //加字符串結束符

. . . . . .

}

可以利用LineIndex和LineFromChar來在字符索引和字符的行列座標之間相互轉換.下列代碼演示了在已知字符索引的情況下,如何獲得對應的行列座標:
int row,column;
row=MyEdit.LineFromChar(charIndex);
column=charIndex-MyEdit.LineIndex(row);
下列代碼演示了在已知字符的行列座標的情況下,如何獲得對應的字符索引:
int charIndex;
charIndex=MyEdit.LineIndex(row)+column;
不難看出字符索引與對應的行列座標的關係是:字符索引=LineIndex(行座標)+列座標.

對於選擇正文的查詢和設置,應該利用函數GetSel、SetSel和ReplaceSel.

可以利用GetSel和SetSel來查詢和設置插入符的位置.SetSel可以使編輯框滾動到插入符的新位置.
要獲取插入符的行列座標,可用下面的代碼實現:
MyEdit.SetSel(-1,0); //取消正文的選擇
int start,end,row,column;
MyEdit.GetSel(start,end); //start或end的值就是插入符的字符索引
row=MyEdit.LineFromChar(start); //獲取插入符的行座標
column=start-MyEdit.LineIndex(row); //獲取插入符的列座標
下面的代碼演示瞭如何把插入符移到指定的行和列:
MyEdit.SetSel(-1,0); //取消正文的選擇
int charIndex=MyEdit.LineIndex(row)+column;
MyEdit.SetSel(charIndex,charIndex);

可以利用ReplaceSel函數在 插入符處插入正文,典型的代碼如下所示:
MyEdit.SetSel(-1,0); //取消正文的選擇
MyEdit.ReplaceSel(“......”);

可以利用ReplaceSel清除編輯框中的正文,典型的代碼如下所示:
MyEdit.SetSel(0,-1); //選擇全部正文
MyEdit.ReplaceSel(“”);

在後面的小節中,讀者將會看到使用編輯框的例子.

.1.5 滾動條控件

滾動條(Scroll Bar)主要用來從某一預定義值範圍內快速有效地進行選擇.滾動條分垂直滾動條和水平滾動條兩種.在滾動條內有一個滾動框,用來表示當前的值.用鼠標單擊滾動條,可以使滾動框移動一頁或一行,也可以直接拖動滾動框.滾動條既可以作爲一個獨立控件存在,也可以作爲窗口、列表框和組合框的一部分.Windows 95的滾動條支持比例滾動框,即用滾動框的大小來反映頁相對於整個範圍的大小.Windows 3.x使用單獨的滾動條控件來調整調色板、鍵盤速度以及鼠標靈敏度,在Windows 95中,滾動條控件被軌道條取代(參見6.2.3)不提倡使用單獨的滾動條控件.

需要指出的是,從性質上劃分,滾動條可分爲標準滾動條和滾動條控件兩種.標準滾動條是由WS_HSCROLL或WS_VSCROLL風格指定的,它不是一個實際的窗口,而是窗口的一個組成部分(例如列表框中的滾動條),只能位於窗口的右側(垂直滾動條)或底端(水平滾動條).標準滾動條是在窗口的非客戶區中創建的.與之相反,滾動條控件並不是窗口的一個零件,而是一個實際的窗口,可以放置在窗口客戶區的任意地方,它既可以獨立存在,也可以與某一個窗口組合,行使滾動窗口的職能.由於滾動條控件是一個獨立窗口,因此可以擁有輸入焦點,可以響應光標控制鍵,如PgUp、PgDown、Home和End.

MFC的CScrollBar類封裝了滾動條控件.CScrollBar類的Create成員函數負責創建控件,該函數的聲明爲

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

參數dwStyle指定了控件的風格.rect說明了控件的位置和尺寸.pParentWnd指向父窗口,該參數不能爲NULL。nID則說明了控件的ID。如果創建成功,該函數返回TRUE,否則返回FALSE.

要創建一個普通的水平滾動條控件,應指定風格WS_CHILD|WS_VISIBLE|BS_HORZ.要創建一個普通的垂直滾動條控件,應指定風格WS_CHILD|WS_VISIBLE|BS_VERT.

主要的CScrollBar類成員函數如下所示:

int GetScrollPos( ) const;
該函數返回滾動框的當前位置.若操作失敗則返回0.

int SetScrollPos( int nPos, BOOL bRedraw = TRUE );
該函數將滾動框移動到指定位置.參數nPos指定了新的位置.參數bRedraw表示是否需要重繪滾動條,如果爲TRUE,則重繪之.函數返回滾動框原來的位置.若操作失敗則返回0.

void GetScrollRange( LPINT lpMinPos, LPINT lpMaxPos ) const;
該函數對滾動條的滾動範圍進行查詢.參數lpMinPos和lpMaxPos分別指向滾動範圍的最小最大值.

void SetScrollRange( int nMinPos, int nMaxPos, BOOL bRedraw = TRUE );
該函數用於指定滾動條的滾動範圍.參數nMinPos和nMaxPos分別指定了滾動範圍的最小最大值.由這兩者指定的滾動範圍不得超過32767.當兩者都爲0時,滾動條將被隱藏.參數bRedraw表示是否需要重繪滾動條,如果爲TRUE,則重繪之.

BOOL GetScrollInfo( LPSCROLLINFO lpScrollInfo, UINT nMask );
該函數用來獲取滾動條的各種狀態,包括滾動範圍、滾動框的位置和頁尺寸.參數lpScrollInfo指向一個SCROLLINFO結構,該結構如下所示:
typedef struct tagSCROLLINFO { 
UINT cbSize; //結構的尺寸(字節爲單位)
UINT fMask; /*說明結構中的哪些參數是有效的,可以是屏蔽值的組合, 如SIF_POS|SIF_PAGE,若爲SIF_ALL則整個結構都有效*/
int nMin; //滾動範圍最大值,當fMask中包含SIF_RANGE時有效
int nMax; //滾動範圍最小值,當fMask中包含SIF_RANGE時有效
UINT nPage; /*頁尺寸,用來確定比例滾動框的大小,當fMask中包含 SIF_PAGE時有效*/
int nPos; //滾動框的位置,當fMask中包含SIF_POS有效
int nTrackPos; /*拖動時滾動框的位置,當fMask中包含 SIF_TRACKPOS時有效,該參數只能查詢,不能設 置,最好不要用該參數來查詢拖動時滾動框的位置*/
} SCROLLINFO; 
typedef SCROLLINFO FAR *LPSCROLLINFO;
參數nMask的意義與SCROLLINFO結構中的fMask相同.函數在獲得有效值後返回TRUE,否則返回FALSE.

BOOL SetScrollInfo( LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE );
該函數用於設置滾動條的各種狀態,一個重要用途是設定頁尺寸從而實現比例滾動框.參數lpScrollInfo指向一個SCROLLINFO結構,參數bRedraw表示是否需要重繪滾動條,如果爲TRUE,則重繪之.若操作成功,該函數返回TRUE,否則返回FALSE.

 

CWnd類也提供了一些函數來查詢和設置所屬的標準滾動條.這些函數與CScrollBar類的函數同名,且功能相同,但每個函數都多了一個參數,用來選擇滾動條.例如,CWnd:: GetScrollPos 的聲明爲

int GetScrollPos( int nBar ) const;
參數nBar用來選擇滾動條,可以爲下列值:
SB_HORZ //指定水平滾動條
SB_VERT //指定垂直滾動條

 

無論是標準滾動條,還是滾動條控件,滾動條的通知消息都是用WM_HSCROLL和WM_VSCROLL消息發送出去的.對這兩個消息的確省處理函數是CWnd::OnHScroll和CWnd::OnVScroll,它們幾乎什麼也不做.一般需要在派生類中對這兩個函數從新設計,以實現滾動功能.這兩個函數的聲明爲

afx_msg void OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar );

afx_msg void OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar );
參數nSBCode是通知消息碼,如表6.8所示.nPos是滾動框的位置,只有在nSBCode爲SB_THUMBPOSITION或SB_THUMBTRACK時,該參數纔有意義.如果通知消息是滾動條控件發來的,那麼pScrollBar是指向該控件的指針,如果是標準滾動條發來的,則pScrollBar爲NULL.

 

表6.8 滾動條的通知消息碼

消息
 含義
 
SB_BOTTOM / SB_RIGHT(二者的消息碼是一樣的,因此可以混用,下同)
 滾動到底端(右端).
 
SB_TOP / SB_LEFT
 滾動到頂端(左端).
 
SB_LINEDOWN / SB_LINERIGHT
 向下(向右)滾動一行(列).
 
SB_LINEUP / SB_LINELEFT
 向上(向左)滾動一行(列).
 
SB_PAGEDOWN / SB_PAGERIGHT
 向下(向右)滾動一頁.
 
SB_PAGEUP / SB_PAGELEFT
 向上(向左)滾動一頁.
 
SB_THUMBPOSITION
 滾動到指定位置.
 
SB_THUMBTRACK
 滾動框被拖動.可利用該消息來跟蹤對滾動框的拖動.
 
SB_ENDSCROLL
 滾動結束.
 

6.1.8小節的例子中,讀者將學會如何使用滾動條以及如何編寫自己的OnHScroll函數.

6.1.6 列表框控件

列表框主要用於輸入,它允許用戶從所列出的表項中進行單項或多項選擇,被選擇的項呈高亮度顯示.列表框具有邊框,並且一般帶有一個垂直滾動條.列表框分單選列表框和多重選擇列表框兩種.單選列表框一次只能選擇一個列表項,而多重選擇列表框可以進行多重選擇.對於列表項的選擇,微軟公司有如下建議:

單擊鼠標選擇一個列表項,單擊一個按鈕來處理選擇的項.

雙擊鼠標選擇一個列表項是處理選擇項的快捷方法.

 

列表框會向父窗口發送如表6.9所示的通知消息.

 

表6.9 列表框控件的通知消息

消息
 含義
 
LBN_DBLCLK
 用戶用鼠標雙擊了一列表項.只有具有LBS_NOTIFY的列表框才能發送該消息.
 
LBN_ERRSPACE
 列表框不能申請足夠的動態內存來滿足需要.
 
LBN_KILLFOCUS
 列表框失去輸入焦點.
 
LBN_SELCANCEL
 當前的選擇被取消.只有具有LBS_NOTIFY的列表框才能發送該消息.
 
LBN_SELCHANGE
 單擊鼠標選擇了一列表項.只有具有LBS_NOTIFY的列表框才能發送該消息.
 
LBN_SETFOCUS
 列表框獲得輸入焦點.
 
WM_CHARTOITEM
 當列表框收到WM_CHAR消息後,向父窗口發送該消息.只有具有LBS_WANTKEYBOARDINPUT風格的列表框纔會發送該消息.
 
WM_VKEYTOITEM
 當列表框收到WM_KEYDOWN消息後,向父窗口發送該消息.只有具有LBS_WANTKEYBOARDINPUT風格的列表框纔會發送該消息.
 

 

 

MFC的CListBox類封裝了列表框.CListBox類的Create成員函數負責列表框的創建,該函數的聲明是

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

 

參數dwStyle指定了列表框控件的風格,如表6.10所示,dwStyle可以是這些風格的組合.rect說明了控件的位置和尺寸.pParentWnd指向父窗口,該參數不能爲NULL。nID則說明了控件的ID。如果創建成功,該函數返回TRUE,否則返回FALSE.

 

表6.10 列表框控件的風格

控件風格
 含義
 
LBS_EXTENDEDSEL
 支持多重選擇.在點擊列表項時按住Shift鍵或Ctrl鍵即可選擇多個 項.
 
LBS_HASSTRINGS
 指定一個含有字符串的自繪式列表框.
 
LBS_MULTICOLUMN
 指定一個水平滾動的多列列表框,通過調用CListBox::SetColumnWidth來設置每列的寬度.
 
LBS_MULTIPLESEL
 支持多重選擇.列表項的選擇狀態隨着用戶對該項單擊或雙擊鼠標而翻轉.
 
LBS_NOINTEGRALHEIGHT
 列表框的尺寸由應用程序而不是Windows指定.通常,Windows指定尺寸會使列表項的某些部分隱藏起來.
 
LBS_NOREDRAW
 當選擇發生變化時防止列表框被更新,可發送WM_SETREDRAW來改變該風格.
 
LBS_NOTIFY
 當用戶單擊或雙擊鼠標時通知父窗口.
 
LBS_OWNERDRAWFIXED
 指定自繪式列表框,即由父窗口負責繪製列表框的內容,並且列表項有相同的高度.
 
LBS_OWNERDRAWVARIABLE
 指定自繪式列表框,並且列表項有不同的高度.
 
LBS_SORT
 使插入列表框中的項按升序排列.
 
LBS_STANDARD
 相當於指定了WS_BORDER|WS_VSCROLL|LBS_SORT |LBS_NOTIFY.
 
LBS_USETABSTOPS
 使列表框在顯示列表項時識別並擴展製表符(‘/t’),缺省的製表寬度是32個對話框單位.
 
LBS_WANTKEYBOARDINPUT
 允許列表框的父窗口接收WM_VKEYTOITEM和WM_CHARTOITEM消息,以響應鍵盤輸入.
 
LBS_DISABLENOSCROLL
 使列表框在不需要滾動時顯示一個禁止的垂直滾動條.
 

 

 

除了上表中的風格外,一般還要爲列表框控件指定WS_CHILD、WS_VISIBLE、WS_TABSTOP、WS_BORDER和WS_VSCROLL風格.要創建一個普通的單選擇列表框,應指定的風格爲WS_CHILD|WS_VISIBLE|WS_TABSTOP|LBS_STANDARD.要創建一個多重選擇列表框,應該在單選擇列表框風格的基礎上再加上 LBS_MULTIPLESEL或LBS_ EXTENDEDSEL.如果不希望列表框排序,就不能使用LBS_STANDARD風格.

對於用對話框模板編輯器創建的列表框控件,可以在控件的屬性對話框中指定表6.10中列出的控件風格。例如,在屬性對話框中選擇Sort項,相當與指定了LBS_SORT風格。

CListBox類的成員函數有數十個之多.我們可以把一些常用的函數分爲三類,在下面列出.需要說明的是,可以用索引來指定列表項,索引是從零開始的.

首先,CListBox成員函數提供了下列函數用於插入和刪除列表項.

int AddString( LPCTSTR lpszItem );
該函數用來往列表框中加入字符串,其中參數lpszItem指定了要添加的字符串.函數的返回值是加入的字符串在列表框中的位置,如果發生錯誤,會返回LB_ERR或LB_ERRSPACE(內存不夠).如果列表框未設置LBS_SORT風格,那麼字符串將被添加到列表的末尾,如果設置了LBS_SORT風格,字符串會按排序規律插入到列表中.

int InsertString( int nIndex, LPCTSTR lpszItem );
該函數用來在列表框中的指定位置插入字符串.參數nIndex給出了插入位置(索引),如果值爲-1,則字符串將被添加到列表的末尾.參數lpszItem指定了要插入的字符串.函數返回實際的插入位置,若發生錯誤,會返回LB_ERR或LB_ERRSPACE.與AddString函數不同,InsertString函數不會導致LBS_SORT風格的列表框重新排序.不要在具有LBS_SORT風格的列表框中使用InsertString函數,以免破壞列表項的次序.

int DeleteString( UINT nIndex );
該函數用於刪除指定的列表項,其中參數nIndex指定了要刪除項的索引.函數的返回值爲剩下的表項數目,如果nIndex超過了實際的表項總數,則返回LB_ERR.

void ResetContent( );
該函數用於清除所有列表項.

int Dir( UINT attr, LPCTSTR lpszWildCard );
該函數用來向列表項中加入所有與指定通配符相匹配的文件名或驅動器名.參數attr爲文件類型的組合,如表6.11所示.參數lpszWildCard指定了通配符(如*.cpp,*.*等).

 

表6.11 Dir函數attr參數的含義


 含義
 
0x0000
 普通文件(可讀寫的文件).
 
0x0001
 只讀文件.
 
0x0002
 隱藏文件.
 
0x0004
 系統文件.
 
0x0010
 目錄.
 
0x0020
 文件的歸檔位已被設置.
 
0x4000
 包括了所有與通配符相匹配的驅動器.
 
0x8000
 排除標誌.若指定該標誌,則只列出指定類型的文件名,否則,先要列出普通文件,然後再列出指定的文件.
 

 

 

下列的CListBox成員函數用於搜索、查詢和設置列表框.

int GetCount( ) const;
該函數返回列表項的總數,若出錯則返回LB_ERR.

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

int GetText( int nIndex, LPTSTR lpszBuffer ) const;
void GetText( int nIndex, CString& rString ) const;
用於獲取指定列表項的字符串.參數nIndex指定了列表項的索引.參數lpszBuffer指向一個接收字符串的緩衝區.引用參數rString則指定了接收字符串的CString對象.第一個版本的函數會返回獲得的字符串的長度,若出錯,則返回LB_ERR.

int GetTextLen( int nIndex ) const;
該函數返回指定列表項的字符串的字節長度.參數nIndex指定了列表項的索引.若出錯則返回LB_ERR.

DWORD GetItemData( int nIndex ) const;
每個列表項都有一個32位的附加數據.該函數返回指定列表項的附加數據,參數nIndex指定了列表項的索引.若出錯則函數返回LB_ERR.

int SetItemData( int nIndex, DWORD dwItemData );
該函數用來指定某一列表項的32位附加數據.參數nIndex指定了列表項的索引.dwItemData是要設置的附加數據值.

提示:列表項的32位附加數據可用來存儲與列表項相關的數據,也可以放置指向相關數據的指針.這樣,當用戶選擇了一個列表項時,程序可以從附加數據中快速方便地獲得與列表項相關的數據. 

 

 

int GetTopIndex( ) const;
該函數返回列表框中第一個可見項的索引,若出錯則返回LB_ERR.

int SetTopIndex( int nIndex );
用來將指定的列表項設置爲列表框的第一個可見項,該函數會將列表框滾動到合適的位置.參數nIndex指定了列表項的索引.若操作成功,函數返回0值,否則返回LB_ERR.

提示:由於列表項的內容一般是不變的,故CListBox未提供更新列表項字符串的函數.如果要改變某列表項的內容,可以先調用DeleteString刪除該項,然後再用InsertString或AddString將更新後的內容插入到原來的位置. 

下列CListBox的成員函數與列表項的選擇有關.

int GetSel( int nIndex ) const;
該函數返回指定列表項的狀態.參數nIndex指定了列表項的索引.如果查詢的列表項被選擇了,函數返回一個正值,否則返回0,若出錯則返回LB_ERR.

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

int SetCurSel( int nSelect );
該函數僅適用於單選擇列表框,用來選擇指定的列表項.該函數會滾動列表框以使選擇項可見.參數nIndex指定了列表項的索引,若爲-1,那麼將清除列表框中的選擇.若出錯函數返回LB_ERR.

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

int GetSelCount( ) const;
該函數僅用於多重選擇列表框,它返回選擇項的數目,若出錯函數返回LB_ERR.

int SetSel( int nIndex, BOOL bSelect = TRUE );
該函數僅適用於多重選擇列表框,它使指定的列表項選中或落選.參數nIndex指定了列表項的索引,若爲-1,則相當於指定了所有的項.參數bSelect爲TRUE時選中列表項,否則使之落選.若出錯則返回LB_ERR.

int GetSelItems( int nMaxItems, LPINT rgIndex ) const;
該函數僅用於多重選擇列表框,用來獲得選中的項的數目及位置.參數nMaxItems說明了參數rgIndex指向的數組的大小.參數rgIndex指向一個緩衝區,該數組是一個整型數組,用來存放選中的列表項的索引.函數返回放在緩衝區中的選擇項的實際數目,若出錯函數返回LB_ERR.

int SelItemRange( BOOL bSelect, int nFirstItem, int nLastItem );
該函數僅用於多重選擇列表框,用來使指定範圍內的列表項選中或落選.參數nFirstItem和nLastItem指定了列表項索引的範圍.如果參數bSelect爲TRUE,那麼就選擇這些列表項,否則就使它們落選.若出錯函數返回LB_ERR.

在6.1.8小節的例子中,讀者將會看到對列表框的測試.

6.1.7 組合框控件

組合框把一個編輯框和一個單選擇列表框結合在了一起.用戶既可以在編輯框中輸入,也可以從列表框中選擇一個列表項來完成輸入.如上一章所提到的,組合框分爲簡易式(Simple)、下拉式(Dropdown)和下拉列表式(Drop List)三種.簡易式組合框包含一個編輯框和一個總是顯示的列表框。下拉式組合框同簡易式組合框類似,二者的區別在於僅當單擊下滾箭頭後列表框纔會彈出。下拉列表式組合框也有一個下拉的列表框,但它的編輯框是隻讀的,不能輸入字符。

Windows中比較常用的是下拉式和下拉列表式組合框,在Developer Studio中就大量使用了這兩種組合框.二者都具有佔地小的特點,這在界面日益複雜的今天是十分重要的.下拉列表式組合框的功能與列表框類似.下拉式組合框的典型應用是作爲記事列表框使用,既把用戶在編輯框中敲入的東西存儲到列表框組件中,這樣當用戶要重複同樣的輸入時,可以從列表框組件中選取而不必在編輯框組件中從新輸入.在Developer Studio中的Find對話框中就可以找到一個典型的下拉式組合框.

要設計一個記事列表框,應採取下列原則:

在創建組合框時指定CBS_DROPDOWNLIST風格.

要限制列表項的數目,以防止內存不夠.

如果在編輯框中輸入的字符串不能與列表框組件中的列表項匹配,那麼應該把該字符串插入到列表框中的0位置處.最老的項處於列表的末尾.如果列表項的數目超出了限制,則應把最老的項刪除.

如果在編輯框中輸入的字符串可以與列表框組件中的某一項完全匹配,則應該先把該項從列表的當前位置刪除,然後在將其插入道列表的0位置處.

 

組合框控件會向父窗口發送表6.12所示的通知消息.

 

表6.12 組合框控件的通知消息

消息
 含義
 
CBN_CLOSEUP
 組合框的列表框組件被關閉.簡易式組合框不會發出該消息.
 
CBN_DBLCLK
 用戶在某列表項上雙擊鼠標.只有簡易式組合框纔會發出該消息.
 
CBN_DROPDOWN
 組合框的列表框組件下拉.簡易式組合框不會發出該消息.
 
CBN_EDITCHANGE
 編輯框的內容被用戶改變了。與CBN_EDITUPDATE不同,該消息是在編輯框顯示的正文被刷新後才發出的。下拉列表式組合框不會發出該消息.
 
CBN_EDITUPDATE
 在編輯框準備顯示改變了的正文時發送該消息。下拉列表式組合框不會發出該消息.
 
CBN_ERRSPACE
 組合框無法申請足夠的內存來容納列表項.
 
CBN_SELENDCANCEL
 表明用戶的選擇應該取消.當用戶在列表框中選擇了一項,然後又在組合框控件外單擊鼠標時就會導致該消息的發送.
 
CBN_SELENDOK
 用戶選擇了一項,然後按了回車鍵或單擊了下滾箭頭.該消息表明用戶確認了自己所作的選擇.
 
CBN_KILLFOCUS
 組合框失去了輸入焦點.
 
CBN_SELCHANGE
 用戶通過點擊或移動箭頭鍵改變了列表的選擇.
 
CBN_SETFOCUS
 組合框獲得了輸入焦點.
 

 

 

MFC的CComboBox類封裝了組合框.需要指出的是,雖然組合框是編輯框和列表框的選擇,但是CComboBox類並不是CEdit類和CListBox類的派生類,而是CWnd類的派生類.

CComboBox的成員函數Create負責創建組合框,該函數的說明如下:

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

 

參數dwStyle指定了組合框控件的風格,如表6.10所示,dwStyle可以是這些風格的組合.rect說明的是列表框組件下拉後組合框的位置和尺寸.pParentWnd指向父窗口,該參數不能爲NULL。nID則說明了控件的ID。如果創建成功,該函數返回TRUE,否則返回FALSE.

提示:在用Create函數創建組合框時,參數rect說明的是包括列表框組件在內的組合框的位置和尺寸,而不是列表框組件隱藏時的編輯框組件尺寸.要設置編輯框組件的高度,可以調用成員函數SetItemHeight(-1,cyItemHeight),其中參數cyItemHeight指定了編輯框的高度(以像素爲單位). 

表6.13 組合框的風格

控件風格
 含義
 
CBS_AUTOHSCROLL
 使編輯框組件具有水平滾動的風格.
 
CBS_DROPDOWN
 指定一個下拉式組合框.
 
CBS_DROPDOWNLIST
 指定一個下拉列表式組合框.
 
CBS_HASSTRINGS
 指定一個含有字符串的自繪式組合框.
 
CBS_OEMCONVERT
 使編輯框組件中的正文可以在ANSI字符集和OEM字符集之間相互轉換。這在編輯框中包含文件名時是很有用的。
 
CBS_OWNERDRAWFIXED
 指定自繪式組合框,即由父窗口負責繪製列表框的內容,並且列表項有相同的高度.
 
CBS_OWNERDRAWVARIABLE
 指定自繪式組合框,並且列表項有不同的高度.
 
CBS_SIIMPLE
 指定一個簡易式組合框.
 
CBS_SORT
 自動對列表框組件中的項進行排序.
 
CBS_DISABLENOSCROLL
 使列表框在不需要滾動時顯示一個禁止的垂直滾動條.
 
CBS_NOINTEGRALHEIGHT
 組合框的尺寸由應用程序而不是Windows指定.通常,由Windows指定尺寸會使列表項的某些部分隱藏起來.
 

 

 

CBS_SIMPLE、CBS_DROPDOWN和CBS_DROPDOWNLIST分別用來將組合框指定爲簡易式、下拉式和下拉列表式.一般還要爲組合框指定WS_CHILD、WS_VISIBLE、WS_TABSTOP、WS_VSCROLL和CBS_AUTOHSCROLL風格.如果要求自動排序,還應指定CBS_SORT風格.

對於用對話框模板編輯器創建的組合框控件,可以在控件的屬性對話框中指定上表中列出的控件風格。例如,在屬性對話框中選擇Dropdown,相當於指定了CBS_DROPDOWN.

CComboBox類的成員函數較多.其中常用的函數可粗分爲兩類,分別針對編輯框組件和列表框組件.可以想象,這些函數與CEdit類和CListBox類的成員函數肯定有很多類似之處,但它們也會有一些不同的特點.如果讀者能從"組合框是由編輯框和列表框組成"這一概念出發,就能夠很快的掌握CComboBox的主要成員函數.

事實上,絕大部分CComboBox的成員函數都可以看成是CEdit或CListBox成員函數的翻版.函數的功能,函數名,甚至函數的參數都是類似的.爲了方便學習,在下面列出CComboBox類的成員函數時,採用了與對應的CEdit或CListBox成員函數相比較的做法.在成員函數的列表中,分別列出了成員函數名,對應的CEdit或CListBox成員函數,以及二者之間的不同之處.不同之處是指函數的功能、參數以及返回值有什麼差別.

針對編輯框組件的主要成員函數如表6.14所示.該表的前三個函數實際上是CWnd類的成員函數,可用來查詢和設置編輯框組件.

 

表6.14 針對編輯框組件的CComboBox成員函數

成員函數名
 對應的CEdit成員函數
 與CEdit成員函數的不同之處
 
CWnd::GetWindowText
 CWnd::GetWindowText
 無.
 
CWnd::SetWindowText
 CWnd::SetWindowText
 無.
 
CWnd::GetWindowTextLength
 CWnd::GetWindowTextLength
   
GetEditSel
 GetSel的第一個版本
 僅函數名不同.
 
SetEditSel
 SetSel的第二個版本
 函數名不同,且無bNoScroll參數.
 
Clear
 Clear
 無.
 
Copy
 Copy
 無.
 
Cut
 Cut
 無.
 
Paste
 Paste
 無.
 

 

 

與CListBox的成員函數類似,針對列表框組件的CComboBox成員函數也可以分爲三類.表6.15列出了用於插入和刪除列表項的成員函數,表6.16列出了用於搜索、查詢和設置列表框的成員函數,與列表項的選擇有關的成員函數在表6.17中列出.需要指出的是,如果這些函數出錯,則反回CB_ERR,而不是LB_ERR.另外,排序的組合框具有的是CBS_SORT風格,而不是LBS_SORT.

 

 

6.15 用於插入和刪除列表項的CComboBox成員函數

成員函數名
 對應的CListBox成員函數
 與CListBox成員函數的不同之處
 
AddString
 AddString
 無.
 
InsertString
 InsertString
 無.
 
DeleteString
 DeleteString
 無.
 
ResetContent
 ResetContent
 無.
 
Dir
 Dir
 無.
 

 

 

6.16 用於搜索、查詢和設置列表框的CComboBox成員函數

成員函數名
 對應的CListBox成員函數
 與CListBox成員函數的不同之處
 
GetCount
 GetCount
 無.
 
FindString
 FindString
 無.
 
GetLBText
 GetText
 僅函數名不同.
 
GetLBTextLen
 GetTextLen
 僅函數名不同.
 
GetItemData
 GetItemData
 無.
 
SetItemData
 SetItemData
 無.
 
GetTopIndex
 GetTopIndex
 無.
 
SetTopIndex
 SetTopIndex
 無.
 

 

 

表6.17 與列表項的選擇有關的CComboBox成員函數

成員函數名
 對應的CListBox成員函數
 與CListBox成員函數的不同之處
 
GetCurSel
 GetCurSel
 無.
 
SetCurSel
 SetCurSel
 新選的列表項的內容會被拷貝到編輯框組件中.
 
SelectString
 SelectString
 新選的列表項的內容會被拷貝到編輯框組件中.
 

 

 

另外,CComboBox的ShowDropDown成員函數專門負責顯示或隱藏列表框組件,該函數的聲明爲

void ShowDropDown( BOOL bShowIt = TRUE );

 

如果參數bShowIt的值爲TRUE,那麼將顯示列表框組件,否則,就隱藏之.該函數對簡易式組合框沒有作用.

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章