青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

大龍的博客

常用鏈接

統計

最新評論

mfc 傳統控件

6.1 傳統控件

在上一課的表5.1已經列出了Windows的傳統控件及其對應的控件類。在這些控件中,讀者應該重點掌握命令按鈕、選擇框、單選按鈕、編輯框、列表框和組合框。

.1.1 傳統控件的控件通知消息

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

利用ClassWizard可以很容易地為控件通知消息加入消息映射和消息處理函數,這在上一章中已經演示過了.傳統控件的消息映射宏是ON_XXXX,其中XXXX表示通知消息碼,如BN_CLICKEDON_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對話框模板中找到,在該模板中有一個圖片控件用來顯示圖標。

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

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

參數lpszText指定了控件顯示的正文。dwStyle指定了靜態控件的風格,表6.1顯示了靜態控件的各種風格,dwStyle可將這些風格組合起來。rect是一個對RECTCRect結構的引用,用來說明控件的位置和尺寸。pParentWnd指向父窗口,該參數不能為NULLnID則說明了控件的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_CHILDWS_VISIBLE窗口風格。一個典型的靜態正文控件的風格為WS_CHILD|WS_VISIBLE|SS_LEFT

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

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

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

用戶在按鈕上雙擊了鼠標。

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

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

參數lpszCaption指定了按鈕顯示的正文。dwStyle指定了按鈕的風格,如表6.4所示,dwStyle可以是這些風格的組合。rect說明了按鈕的位置和尺寸。pParentWnd指向父窗口,該參數不能為NULLnID是按鈕的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_CHILDWS_VISIBLEWS_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_TABSTOPWS_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指定了按鈕的風格。bRedrawTRUE則重繪按鈕,否則就不重繪。

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指定了按鈕的IDnCheck的值0表示按鈕未被選擇,1表示按鈕被選擇,2表示按鈕處于不確定狀態。

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

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

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

 

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

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_AUTOHSCROLLES_AUTOVSCROLL的編輯框中,當正文超出了編輯框的邊框時也會發出該消息。

EN_SETFOCUS

編輯框獲得輸入焦點。

EN_UPDATE

在編輯框準備顯示改變了的正文時發送該消息。

EN_VSCROLL

用戶在垂直滾動條上單擊鼠標。

 

 

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

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

 

參數dwStyle指定了編輯框控件風格,如表6.6所示,dwStyle可以是這些風格的組合。rect指定了編輯框的位置和尺寸。pParentWnd指定了父窗口,不能為NULL。編輯框的IDnID指定。如果創建成功,該函數返回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_CHILDWS_VISIBLEWS_TABSTOPWS_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

 

 

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

 

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)

 

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

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,則滾動插入符并使之可見,否則就不滾動.參數nStartCharnEndChar的含義與參數dwSelection的低位字和高位字相同.

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

 

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

abcd

efg

ij

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

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

調用CWnd的成員函數GetWindowTextSetWindowText可以查詢和設置編輯框的整個正文,在上一章的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; //加字符串結束符

. . . . . .

}

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

對于選擇正文的查詢和設置,應該利用函數GetSelSetSelReplaceSel

可以利用GetSelSetSel來查詢和設置插入符的位置.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_HSCROLLWS_VSCROLL風格指定的,它不是一個實際的窗口,而是窗口的一個組成部分(例如列表框中的滾動條),只能位于窗口的右側(垂直滾動條)或底端(水平滾動條).標準滾動條是在窗口的非客戶區中創建的.與之相反,滾動條控件并不是窗口的一個零件,而是一個實際的窗口,可以放置在窗口客戶區的任意地方,它既可以獨立存在,也可以與某一個窗口組合,行使滾動窗口的職能.由于滾動條控件是一個獨立窗口,因此可以擁有輸入焦點,可以響應光標控制鍵,如PgUpPgDownHomeEnd

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

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

參數dwStyle指定了控件的風格.rect說明了控件的位置和尺寸.pParentWnd指向父窗口,該參數不能為NULLnID則說明了控件的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;
該函數對滾動條的滾動范圍進行查詢.參數lpMinPoslpMaxPos分別指向滾動范圍的最小最大值.

void SetScrollRange( int nMinPos, int nMaxPos, BOOL bRedraw = TRUE );
該函數用于指定滾動條的滾動范圍.參數nMinPosnMaxPos分別指定了滾動范圍的最小最大值.由這兩者指定的滾動范圍不得超過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_HSCROLLWM_VSCROLL消息發送出去的.對這兩個消息的確省處理函數是CWnd::OnHScrollCWnd::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是滾動框的位置,只有在nSBCodeSB_THUMBPOSITIONSB_THUMBTRACK時,該參數才有意義.如果通知消息是滾動條控件發來的,那么pScrollBar是指向該控件的指針,如果是標準滾動條發來的,則pScrollBarNULL

 

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風格的列表框才會發送該消息.

 

 

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

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

 

參數dwStyle指定了列表框控件的風格,如表6.10所示,dwStyle可以是這些風格的組合.rect說明了控件的位置和尺寸.pParentWnd指向父窗口,該參數不能為NULLnID則說明了控件的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_VKEYTOITEMWM_CHARTOITEM消息,以響應鍵盤輸入.

LBS_DISABLENOSCROLL

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

 

 

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

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

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

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

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

int InsertString( int nIndex, LPCTSTR lpszItem );
該函數用來在列表框中的指定位置插入字符串.參數nIndex給出了插入位置(索引),如果值為-1,則字符串將被添加到列表的末尾.參數lpszItem指定了要插入的字符串.函數返回實際的插入位置,若發生錯誤,會返回LB_ERRLB_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_ERRFindString函數先從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刪除該項,然后再用InsertStringAddString將更新后的內容插入到原來的位置.

下列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,則相當于指定了所有的項.參數bSelectTRUE時選中列表項,否則使之落選.若出錯則返回LB_ERR

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

int SelItemRange( BOOL bSelect, int nFirstItem, int nLastItem );
該函數僅用于多重選擇列表框,用來使指定范圍內的列表項選中或落選.參數nFirstItemnLastItem指定了列表項索引的范圍.如果參數bSelectTRUE,那么就選擇這些列表項,否則就使它們落選.若出錯函數返回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

組合框獲得了輸入焦點.

 

 

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

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

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

 

參數dwStyle指定了組合框控件的風格,如表6.10所示,dwStyle可以是這些風格的組合.rect說明的是列表框組件下拉后組合框的位置和尺寸.pParentWnd指向父窗口,該參數不能為NULLnID則說明了控件的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_SIMPLECBS_DROPDOWNCBS_DROPDOWNLIST分別用來將組合框指定為簡易式、下拉式和下拉列表式.一般還要為組合框指定WS_CHILDWS_VISIBLEWS_TABSTOPWS_VSCROLLCBS_AUTOHSCROLL風格.如果要求自動排序,還應指定CBS_SORT風格.

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

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

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

<

posted on 2007-10-19 14:38 大龍 閱讀(5791) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            一区二区三区日韩欧美| 欧美日韩一区二区视频在线| 欧美日本不卡视频| 国产精品第三页| 亚洲国产欧美国产综合一区| 久久精品国产成人| 在线中文字幕一区| 欧美日韩一区二区免费在线观看| 亚洲欧洲一区二区三区在线观看| 免费观看一区| 久久久蜜桃精品| 国内精品久久久久久影视8| 欧美在线视频日韩| 欧美一区二区在线观看| 国产揄拍国内精品对白| 久久久久免费观看| 久久人人97超碰国产公开结果| 一区二区三区在线免费播放| 免费成人性网站| 蜜臀av一级做a爰片久久| 亚洲三级观看| 99pao成人国产永久免费视频| 欧美三级在线| 亚洲欧美综合另类中字| 午夜激情综合网| 国产亚洲亚洲| 欧美成人黄色小视频| 欧美顶级少妇做爰| 亚洲视频免费| 欧美一级电影久久| 亚洲电影欧美电影有声小说| 亚洲国产一区二区在线| 免费不卡中文字幕视频| 一区二区三区国产| 亚洲直播在线一区| 在线欧美日韩| 一本久久综合亚洲鲁鲁| 国产欧美日韩激情| 欧美mv日韩mv国产网站| 欧美精品免费视频| 欧美在线国产| 久久久久久久久久久久久女国产乱| 91久久久久久国产精品| 宅男精品导航| 伊人夜夜躁av伊人久久| 亚洲精品欧洲精品| 国产精品色一区二区三区| 美女啪啪无遮挡免费久久网站| 欧美精品免费在线观看| 久久高清福利视频| 欧美激情1区2区3区| 欧美一区二区三区四区视频| 蜜臀av性久久久久蜜臀aⅴ四虎 | 欧美精品亚洲二区| 午夜视频久久久久久| 久久亚洲精品中文字幕冲田杏梨| 在线亚洲+欧美+日本专区| 久久国产精彩视频| 亚洲一区二区在线看| 久久久亚洲欧洲日产国码αv| 在线视频精品一区| 国产精品黄视频| 久久国产精品免费一区| 欧美国产欧美综合 | 亚洲国产另类久久久精品极度 | 国产午夜精品在线| 亚洲欧洲精品一区二区三区波多野1战4 | 欧美高清在线视频| 国产午夜精品全部视频播放| aa级大片欧美| 91久久久久久久久久久久久| 欧美一区=区| 亚洲综合色激情五月| 欧美.www| 欧美11—12娇小xxxx| 国产亚洲欧美一区二区三区| 亚洲天堂成人在线视频| 一区二区三区波多野结衣在线观看| 久久亚洲欧美国产精品乐播| 欧美综合激情网| 国产精品国产自产拍高清av王其| 亚洲国产日韩欧美在线99| 精品99视频| 久久av老司机精品网站导航| 欧美中文在线视频| 国产欧美日韩视频在线观看| 亚洲天堂av高清| 午夜伦理片一区| 国产精品成人国产乱一区| 日韩网站在线| 亚洲在线视频观看| 欧美偷拍另类| 一区二区三区国产盗摄| 亚洲视频一区在线观看| 欧美色欧美亚洲另类二区| 日韩一级黄色大片| 宅男噜噜噜66国产日韩在线观看| 欧美精品一区二区三| 亚洲精品中文字| 在线亚洲伦理| 国产精品麻豆成人av电影艾秋| 在线亚洲一区观看| 欧美一区二区在线免费观看| 国产一区二区av| 久久久久在线观看| 免费久久精品视频| 亚洲精品久久久久中文字幕欢迎你 | 欧美亚洲一区| 久久一二三四| 亚洲精品视频中文字幕| 欧美日韩不卡一区| 这里只有精品在线播放| 久久国产主播精品| 亚洲高清久久| 亚洲福利视频网站| 99这里只有精品| 国产精品免费区二区三区观看| 午夜精品久久久久久久99樱桃| 久久躁狠狠躁夜夜爽| 欧美jizz19性欧美| 国产一区视频观看| 毛片一区二区| 日韩亚洲欧美精品| 欧美一区二区三区在线| 一区免费视频| 欧美日韩在线亚洲一区蜜芽| 亚洲免费网站| 欧美激情精品久久久六区热门 | 亚洲国产另类精品专区| 亚洲一区中文字幕在线观看| 国模 一区 二区 三区| 欧美激情精品久久久久久变态| 亚洲一级免费视频| 欧美激情按摩| 久久国产黑丝| 一本色道久久99精品综合 | 亚洲福利在线视频| 亚洲欧美日韩一区二区在线 | 国产精品影视天天线| 免费日韩成人| 亚洲欧美日韩一区| 亚洲精品美女久久久久| 久久只精品国产| 亚洲综合欧美| 日韩亚洲欧美一区| 国外成人在线| 国产精品海角社区在线观看| 麻豆精品精华液| 亚洲欧美影音先锋| 日韩午夜免费视频| 亚洲春色另类小说| 红杏aⅴ成人免费视频| 欧美母乳在线| 老色鬼久久亚洲一区二区| 亚洲一区三区在线观看| 亚洲精品乱码视频| 亚洲承认在线| 欧美成人高清视频| 久久综合久久久| 久久国产精品72免费观看| 亚洲一区二区三区中文字幕在线| 亚洲激情在线激情| 在线观看亚洲视频啊啊啊啊| 国产精品一区免费观看| 欧美午夜精品久久久久久浪潮| 玖玖视频精品| 久久尤物视频| 久久久久www| 欧美影院成年免费版| 亚洲影院一区| 亚洲一区美女视频在线观看免费| 妖精视频成人观看www| 亚洲精品一区二区三| 91久久在线播放| 亚洲国产精品久久久久| 欧美华人在线视频| 亚洲风情在线资源站| 欧美激情一区二区三区高清视频 | 欧美电影免费网站| 男女视频一区二区| 老司机一区二区三区| 久久久久欧美精品| 久久亚洲综合| 男人天堂欧美日韩| 欧美国产日本在线| 亚洲夫妻自拍| 国产婷婷精品| 午夜在线一区| 欧美一区视频| 久久精品国产亚洲一区二区三区| 亚洲免费小视频| 欧美在线观看日本一区| 性欧美超级视频| 久久久久国产精品麻豆ai换脸| 久久蜜桃香蕉精品一区二区三区| 久久久久久久国产| 免费观看亚洲视频大全| 欧美日本不卡视频| 国产精品区一区二区三| 国内成人精品一区|