● ON_EN_CHANGE 输入框中文字更新后产生 ● ON_EN_ERRSPACE 输入框无法分配内存时产生
● ON_EN_KILLFOCUS / ON_EN_SETFOCUS 在输入框失去/得到输入焦点时产生
使用以上几种消息映射的方法为定义原型如:afx_msg void memberFxn( );的函数,并且定义形式如ON_Notification( id, memberFxn )的消息映射。如果在对话框中使用输入框,Class Wizard会自动列出相关的消息,并能自动产生消息映射代码。
4.4 Scroll Bar
Scroll Bar一般不会单独使用,因为SpinCtrl可以取代滚动条的一部分作用,但是如果你需要自己生成派生窗口,滚动条还是会派上一些用场。创建一个滚动条可以使用成员函数: : BOOL CEdit::Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff );
其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD,WS_VISIBLE外,你可以针对滚动条指明专门的风格。
● SBS_VERT 风格将创建一个垂直的滚动条。 ● SBS_HORZ 风格将创建一个水平的滚动条。
在创建滚动条后需要调用void SetScrollRange( int nMinPos, int nMaxPos, BOOL bRedraw = TRUE )设置滚动范围,
int GetScrollPos( )/int SetScrollPos( )用来得到和设置当前滚动条的位置。
void ShowScrollBar( BOOL bShow = TRUE );用来显示/隐藏滚动条。
BOOL EnableScrollBar( UINT nArrowFlags = ESB_ENABLE_BOTH )用来设置滚动条上箭头是否为允许状态。nArrowFlags可取以下值:
● ESB_ENABLE_BOTH 两个箭头都为允许状态 ● ESB_DISABLE_LTUP 上/左箭头为禁止状态 ● ESB_DISABLE_RTDN 下/右箭头为禁止状态 ● ESB_DISABLE_BOTH 两个箭头都为禁止状态
如果需要在滚动条位置被改变时得到通知,需要在父窗口中定义对消息WM_VSCROLL/WM_HSCROLL的映射。方法为在父窗口类中重载
afx_msg void OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )/afx_msg void OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
所使用的消息映射宏为:ON_WM_VSCROLL( ),ON_WM_HSCROLL( ),在映射宏中不需要指明滚动条的ID,因为所有滚动条的滚动消息都由同样的函数处理。在OnHScroll/OnVScroll的第三个参数会指明当前滚动条的指针。第一个参数表示滚动条上发生的动作,可取以下值:
● SB_TOP/SB_BOTTOM 已滚动到顶/底部
● SB_LINEUP/SB_LINEDOWN 向上/下滚动一行
● SB_PAGEDOWN/SB_PAGEUP 向上/下滚动一页
● SB_THUMBPOSITION/SB_THUMBTRACK 滚动条拖动到某一位置,参数nPos指明当前位置(参数nPos在其它的情况下是无效的)
● SB_ENDSCROLL 滚动条拖动完成(用户松开鼠标)
4.5 List Box/Check List Box
ListBox窗口用来列出一系列的文本,每条文本占一行。创建一个列表窗口可以使用成员函数:
BOOL CListBox::Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff );
其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD,WS_VISIBLE外,你可以针对列表控件指明专门的风格。
● LBS_MULTIPLESEL 指明列表框可以同时选择多行 ● LBS_EXTENDEDSEL 可以通过按下Shift/Ctrl键选择多行 ● LBS_SORT 所有的行按照字母顺序进行排序
在列表框生成后需要向其中加入或是删除行,可以利用: int AddString( LPCTSTR lpszItem )添加行,
int DeleteString( UINT nIndex )删除指定行,
int InsertString( int nIndex, LPCTSTR lpszItem )将行插入到指定位置。 void ResetContent( )可以删除列表框中所有行。
通过调用int GetCount( )得到当前列表框中行的数量。
如果需要得到/设置当前被选中的行,可以调用int GetCurSel( )/int SetCurSel(int iIndex)。如果你指明了选择多行的风格,你就需要先调用int GetSelCount( )得到被选中的行的数量,然后int GetSelItems( int nMaxItems, LPINT rgIndex )得到所有选中的行,参数rgIndex为存放被选中行的数组。通过调用int GetLBText( int nIndex, LPTSTR lpszText )得到列表框内指定行的字符串。
此外通过调用int FindString( int nStartAfter, LPCTSTR lpszItem )可以在当前所有行中查找指定的字符传的位置,nStartAfter指明从那一行开始进行查找。
int SelectString( int nStartAfter, LPCTSTR lpszItem )可以选中包含指定字符串的行。
在MFC 4.2版本中添加了CCheckListBox类,该类是由CListBox派生并拥有CListBox的所有功能,不同的是可以在每行前加上一个检查框。必须注意的是在创建时必须指明LBS_OWNERDRAWFIXED或LBS_OWNERDRAWVARIABLE风格。
通过void SetCheckStyle( UINT nStyle )/UINT GetCheckStyle( )可以设置/得到检查框的风格,关于检查框风格可以参考4.1 Button中介绍。通过void SetCheck( int nIndex, int nCheck )/int GetCheck( int nIndex )可以设置和得到某行的检查状态,关于检查框状态可以参考4.1 Button中介绍。
最后介绍一下列表框几种常用的消息映射宏:
● ON_LBN_DBLCLK 鼠标双击
● ON_EN_ERRSPACE 输入框无法分配内存时产生
● ON_EN_KILLFOCUS / ON_EN_SETFOCUS 在输入框失去/得到输入焦点时产生 ● ON_LBN_SELCHANGE 选择的行发生改变
使用以上几种消息映射的方法为定义原型如:afx_msg void memberFxn( );的函数,并且定义形式如ON_Notification( id, memberFxn )的消息映射。如果在对话框中使用列表框,Class Wizard会自动列出相关的消息,并能自动产生消息映射代码。
4.6 Combo Box/Combo Box Ex
组合窗口是由一个输入框和一个列表框组成。创建一个组合窗口可以使用成员函数: BOOL CListBox::Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff );
其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD,WS_VISIBLE外,你可以针对列表控件指明专门的风格。
● CBS_DROPDOWN 下拉式组合框
● CBS_DROPDOWNLIST 下拉式组合框,但是输入框内不能进行输入 ● CBS_SIMPLE 输入框和列表框同时被显示 ● LBS_SORT 所有的行按照字母顺序进行排序
由于组合框内包含了列表框,所以列表框的功能都能够使用,如可以利用: int AddString( LPCTSTR lpszItem )添加行, int DeleteString( UINT nIndex )删除指定行,
int InsertString( int nIndex, LPCTSTR lpszItem )将行插入到指定位置。 void ResetContent( )可以删除列表框中所有行。
通过调用int GetCount( )得到当前列表框中行的数量。
如果需要得到/设置当前被选中的行的位置,可以调用int GetCurSel( )/int SetCurSel(int iIndex)。通过调用int GetLBText( int nIndex, LPTSTR lpszText )得到列表框内指定行的字符串。
此外通过调用int FindString( int nStartAfter, LPCTSTR lpszItem )可以在当前所有行中查找指定的字符传的位置,nStartAfter指明从那一行开始进行查找。
int SelectString( int nStartAfter, LPCTSTR lpszItem )可以选中包含指定字符串的行。
此外输入框的功能都能够使用,如可以利用:
DWORD GetEditSel( ) /BOOL SetEditSel( int nStartChar, int nEndChar )得到或设置输入框中被选中的字符位置。
BOOL LimitText( int nMaxChars )设置输入框中可输入的最大字符数。 输入框的剪贴板功能Copy,Clear,Cut,Paste动可以使用。
最后介绍一下列表框几种常用的消息映射宏:
● ON_CBN_DBLCLK 鼠标双击
● ON_CBN_DROPDOWN 列表框被弹出
● ON_CBN_KILLFOCUS / ON_CBN_SETFOCUS 在输入框失去/得到输入焦点时产生 ● ON_CBN_SELCHANGE 列表框中选择的行发生改变
● ON_CBN_EDITUPDATE 输入框中内容被更新
使用以上几种消息映射的方法为定义原型如:afx_msg void memberFxn( );的函数,并且定义形式如ON_Notification( id, memberFxn )的消息映射。如果在对话框中使用组合框,Class Wizard会自动列出相关的消息,并能自动产生消息映射代码。
在MFC 4.2中对组合框进行了增强,你可以在组合框中使用ImageList,有一个新的类CComboBoxEx(由CComboBox派生)来实现这一功能。在CComboBoxEx类中添加了一些新的成员函数来实现新的功能:首先你需要调用
CImageList* SetImageList( CImageList* pImageList );来设置ImageList,然后调用 int InsertItem( const COMBOBOXEXITEM* pCBItem );来添加行,其中COMBOBOXEXITEM定义如下:
typedef struct {
UINT mask; int iItem;
LPTSTR pszText; int cchTextMax; int iImage;
int iSelectedImage; int iOverlay; int iIndent;
LPARAM lParam;
} COMBOBOXEXITEM, *PCOMBOBOXEXITEM;
你需要设置mask=CBEIF_IMAGE|CBEIF_TEXT,并设置iItem为插入位置,设置pszText为显示字符串,设置iImage为显示的图标索引。下面的代码演示了如何进行插入: /*m_cbeWnd 为已经创建的CComboBox对象
m_list 为CImageList对象IDB_IMG 为16*(16*4)的位图,每个图片为16*16共4个图标*/ m_list.Create(IDB_IMG,16,4,RGB(0,0,0)); m_cbeWnd.SetImageList(&m_list);
COMBOBOXEXITEM insItem;
insItem.mask=CBEIF_IMAGE|CBEIF_TEXT; insItem.iItem=0; insItem.iImage=0;
insItem.pszText=\
m_cbeWnd.InsertItem(&insItem); insItem.iItem=1; insItem.iImage=1;
insItem.pszText=\
m_cbeWnd.InsertItem(&insItem);
通过调用int DeleteItem( int iIndex );来删除行,并指明行的位置。
通过调用BOOL GetItem( COMBOBOXEXITEM* pCBItem )/BOOL SetItem( const COMBOBOXEXITEM* pCBItem );来得到/设置行数据。
4.7 Tree Ctrl
树形控件TreeCtrl和下节要讲的列表控件 ListCtrl在系统中大量被使用,例如Windows资源管理器就是一个典型的例子。
树形控件可以用于树形的结构,其中有一个根接点(Root)然后下面有许多子结点,而每个子结点上有允许有一个或多个或没有子结点。MFC中使用CTreeCtrl类来封装树形控件的各种操作。通过调用BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );创建一个窗口,dwStyle中可以使用以下一些树形控件的专用风格:
● TVS_HASLINES 在父/子结点之间绘制连线
● TVS_LINESATROOT 在根/子结点之间绘制连线 ● ● ● ●
TVS_HASBUTTONS 在每一个结点前添加一个按钮,用于表示当前结点是否已被展开 TVS_EDITLABELS 结点的显示字符可以被编辑
TVS_SHOWSELALWAYS 在失去焦点时也显示当前选中的结点 TVS_DISABLEDRAGDROP 不允许Drag/Drop
● TVS_NOTOOLTIPS 不使用ToolTip显示结点的显示字符
在树形控件中每一个结点都有一个句柄(HTREEITEM),同时添加结点时必须提供的参数是该结点的父结点句柄,(其中根Root结点只有一个,既不可以添加也不可以删除)利用 HTREEITEM InsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST );可以添加一个结点,pszItem为显示的字符,hParent代表父结点的句柄,当前添加的结点会排在hInsertAfter表示的结点的后面,返回值为当前创建的结点的句柄。下面的代码会建立一个如下形式的树形结构: +--- Parent1
??+--- Child1_1 ??+--- Child1_2 ??+--- Child1_3 +--- Parent2
+--- Parent3
/*假设m_tree为一个CTreeCtrl对象,而且该窗口已经创建*/
HTREEITEM hItem,hSubItem;
hItem = m_tree.InsertItem(\在根结点上添加Parent1
hSubItem = m_tree.InsertItem(\在Parent1上添加一个子结点
hSubItem = m_tree.InsertItem(\在Parent1上添加一个子结点,排