第6节 VC++6.0控件说明

Windows编程基础–第6节 VC++6.0控件说明

VC++6.0控件工具箱

这里写图片描述


控件说明

  • 2 图形控件(picture):常用于显示位图(Bitmap)和图标(Icon)
  • 3 静态文本(Static Text):用来在指定的位置显示特定的字符串,一般用来标识附近另一个控件的内容。显示在静态文本控件中的字符串一般不再改变,但是在需要的时候,也可以通过调用相应的函数来进行设置。MFC提供了CStatic类支持静态控件。
  • 4 编辑框(Edit Box):用来接收用户输入的字符串。通过选择编辑框的选项,编辑框可以接收字符串、数字、密码等;编辑框还可以设置成接收多行字符串的模式;可以自动进行大小写转换。编辑框可能向其父窗口发送多种控件通知,如果用户需要,可以对这些控件通知进行处理。MFC提供了CEdit类支持编辑框控件。
  • 5 组成框(Group Box):用来包围具有逻辑关系的一组控件,在这些控件的周围加上边界和标题。需注意的是,组成框仅仅是在视觉效果上对控件进行“成组”,真正的“成组”工作还需要另外一些工作。
  • 6 按钮(Button):用来接收用户的命令,应用程序在接收到用户命令后,通常需要进行一些后台工作。按钮可以响应单击或双击动作,在按钮接收到鼠标动作后,向其父窗口发送相应的控件通知,用户可以对这些控件通知进行消息映射,从而进行相应的处理。在一个对话框中,可以定义一个默认按钮,这只要选中按钮属性中的“Default”选项。如果在对话框活动的时候按下了Enter键,则等同于单击了默认按钮。MFC提供了CButton类支持按钮控件。
  • 7 复选框(Check Box):用来显示某种可能的选择,该项选择是独立的,用户可以选中或取消该选项。在选项被选中的时候核选标记出现,选项被取消时核选标记消失。MFC中由CButton类对核选框进行支持,用户可以通过SetCheck()函数和GetCheck()函数设置或获取核选框当前的状态。
  • 8 单选按钮(Radio Button):用来选择某种可能的选择,与核选框不同,该选项不是独立的。一般是几个单选按钮组成一组,同组中的单选按钮可以有也只能有一个按钮被选中。MFC同样使用CButton类对单选按钮控件进行支持,SetCheck()函数和GetCheck()函数对单选按钮也是适用的。
  • 9 组合框(Combo Box):列表框和编辑框的组合,用户除了可以在列表中对已经存在的选项进行选择外,还可以输入新的选择。MFC提供了CComboBox类对组合框控件进行支持。
  • 10 列表框(List Box):用来选择一系列的可能选择,用户通过滚动条可以在这些选择中浏览。在列表框中,可以进行单项选择,也可以进行多项选择,这取决于用户在控件属性对话框中的设置。MFC提供了CListBox类对列表框控件进行支持。
  • 11、12 滚动条(Scroll Bar):这包括水平滚动条和垂直滚动条,除了在视觉效果上的方向不同外,水平滚动条在被滚动时发生WM_HSCROLL消息,而垂直滚动条在被滚动时发送WM_VSCROLL消息。MFC提供了CScrollBar进行支持。
  • 13 微调按钮(Spin Button):包括一对紧靠在一起的上下箭头,使用微调按钮可以增大或者缩小某个特定的数值。微调按钮往往都需要一个“伙伴”控件,这通常都是一个编辑框。当微调按钮的向上箭头被单击时,编辑框中的数字就增大;反之则减小。MFC提供了CPinButtonCtrl类进行支持。
  • 14 进度条(Progress):在进行一项需要占有较长时间的操作时来反应当前的进度。当操作的进度不断前进时,进度条就用特色颜色填充进度条框。用户可以设定进度条的范围和当前位置。MFC提供了CProgressCtrl类进行支持。
  • 15 滑块控件(Slider):通常用来在程序中接受一系列离散的数值。用户可以设置滑块控件的取值范围,并可以为控件加上刻度标记以显示特定位置的含义。MFC提供了CSliderCtrl类进行支持。
  • 16 热键控制(Hot Key):热键控件看起来就像一个编辑框,但是在热键控件中能够立刻反应用户刚刚按下的键组合,这在设置程序的热键时特别有用。热键控件只是在“视觉”上显示了按键组合,设置热键的工作还需要用户添加代码完成。MFC提供了CHotKey类进行支持。
  • 17 列表控制(List Control):按一定的排列顺序显示一系列带图标的字符串,列表控件提供了四种显示模式:大图标、小图标、列表和详细信息。用户可以向列表控件中添加新的项,也可以控制列表控件的显示模式。MFC提供了CListCtrl类进行支持。
  • 18 树形控件(Tree Control):用来显示一系列项目的层次关系,最典型的例子是显示磁盘上的文件与文件夹。如果有子项目的话,单击树形控件中的项目可以展开或者收缩其子项目。MFC提供了CTreeCtrl类进行支持。
  • 19 属性表控件(Tab Control):用来包含大量的控件,可以满足用户显示或者获取大量数据的要求。每个属性表又分为好几个属性页,这些属性页由各自的标签进行区分,这些属性页中都可以包容其他控件。在显示属性表的时候,一次只能够显示一个属性页的全部内容,同时显示其他属性页的标签,用户通过单击标签打开相应的属性页。MFC提供了CTabCtrl类进行支持。
  • 20 动画控件(Animation):用来播放一段AVI格式的视频剪辑。用户可以控制视频剪辑的播放、停止和定位,但也仅限于这些功能。动画控件设置不能播放音频剪辑,如果用户需要更高层次的视频或者音频的支持,请选用MCIWnd控件。MFC提供了CAnimateCtrl类对动画控件进行支持。
  • 21 高级编辑框(Rich Edit):编辑控件功能的扩展。在高级编辑框中,除了简单的输入和编辑字符串外,用户还可以为字符或段落指定特定的格式,用户甚至还可以向高级编辑框中插入OLE项。高级编辑框基本上实现了一个带格式的文本编辑器功能,而只需要用户添加少量的接口。MFC提供了CRichEditCtrl类进行支持。
  • 22 日历控件(Month Calender):看似与真正的日历类似,操作也类似,直观的为用户提供了观察和显示当前日期的途径。MFC提供了CMonthCalCtrl类进行支持。
  • 23 日期/时间选择器(Date Time Picker):向用户提供了一种直观的选择日期和时间的方法、日期/时间选择器在外观上类似于一个组合框,但是当用户单击下拉箭头时就会展开一个日历控件供用户选择,而一旦用户做出了选择,日期/时间选择器会自动显示新的日期/时间。MFC提供了CDateTimeCtrl类进行支持。
  • 24 IP地址控件(IP Adress):IP地址控件用来输入和编辑IP地址。该控件外观类似于一个编辑框,但是可以自动对输入的字符按3个一组进行区分和加间隔圆点。IP地址控件为开发支持Internet技术的程序提供了方便。MFC提供了CIPAddressCtrl类进行支持。
  • 26 扩展组合框(Extended Combo Box):在普通组合框的基础上还支持图像列表。即,可以在组合框中显示特定的图标表示相应的选择,而不仅仅是显示文本。MFC提供了CComboBoxEx类进行支持。

所有控件的公共属性

ID:控件的资源标识。
Visiable:控件是否可见。
Disabled:控件是否被禁止、被禁止的控件无法接受键盘和鼠标输入。
Group:是否从这个空间开始一个新组。
Tab stop:在程序中是否可以用【Tab】键切换到这个控件。
Help ID:是否给控件分配一个帮助标识,帮助标识基于控件本身的资源标识。
Client edge:给控件增加一个凹陷的边界,使整个控件看起来像是凹下去的一样。
Static edge:给控件增加一个边界。
Modal frame:给控件增加一个3维的框架,与Client edge相反,它是凸出来的。
Transparent:拥有此属性的窗口是透明的,它下面的窗口不会被它遮掩住。
Accept files:拥有此属性的窗口可以接收拖放文件,如果一个文件被拖动到这个控件上面,控件会收到WM_DROPFILES消息。
No parent notify:表示控件不向其父窗口发送WM_PARENTNOTIFY消息。
Right aligned text:表示文本右对齐。

以上属性可通过控件的属性对话框进行设置,在属性对话框中按【F1】键可以查看属性的帮助信息。每一种控件都由一个MFC控件类来管理,当通过资源编辑器在对话框上添加一个控件时

,visualC++会自动为控件类生成一个实例,即对象,并调用构造函数,当对话框关闭时,其各个子控件对象被自动销毁。也可以不使用资源编辑器,自己在程序中写代码创建、显示控件并设置控件的属性。所有的控件类都继承自CWnd,控件的某些操作和属性设置需要用到CWnd本身的成员函数,CWnd某些函数经常用来操纵控件和设置控件属性。

SetWindowText:设置控件上要显示的标题文本,即用来设置控件的caption属性
GetWindowText:得到控件的标题文本
EnableWindow:设置控件的Disabled属性,即社会自控件是否可以接收键盘和鼠标的输入
SetWindowPos:改变窗口的大小、位置和Z轴次序。 MoveWindow:改变窗口的大小和位置
GetWindowRec:得到窗口的大小、位置(信息存放在一个矩形结构中)。
GetClientRect:得到窗口客户区的大小(信息存放在一个矩形结构中 ) ShowWindow:设置窗口的可见性(即窗口是否可见)
SetWindowText/GetWindowText还可以用来设置/得到对话框的标题文本。


转载

Button

按钮窗口(控件)在MFC中使用CButton表示,CButton包含了三种样式的按钮,Push Button,Check Box,Radio Box。所以在利用CButton对象生成按钮窗口时需要指明按钮的风格。

创建按钮:BOOL CButton::Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );其中lpszCaption是按钮上显示的文字,dwStyle为按钮风格,除了Windows风格可以使用外(如 WS_CHILD|WS_VISUBLE|WS_BORDER)还有按钮专用的一些风格。

· BS_AUTOCHECKBOX 检查框,按钮的状态会自动改变 Same as a check box, except that a check mark appears in the check box when the user selects the box; the check mark disappears the next time the user selects the box.

· BS_AUTORADIOBUTTON 圆形选择按钮,按钮的状态会自动改变 Same as a radio button, except that when the user selects it, the button automatically highlights itself and removes the selection from any other radio buttons with the same style in the same group.

· BS_AUTO3STATE 允许按钮有三种状态即:选中,未选中,未定 Same as a three-state check box, except that the box changes its state when the user selects it.

· BS_CHECKBOX 检查框 Creates a small square that has text displayed to its right (unless this style is combined with the BS_LEFTTEXT style).

· BS_DEFPUSHBUTTON 默认普通按钮 Creates a button that has a heavy black border. The user can select this button by pressing the ENTER key. This style enables the user to quickly select the most likely option (the default option).

· BS_LEFTTEXT 左对齐文字 When combined with a radio-button or check-box style, the text appears on the left side of the radio button or check box.

· BS_OWNERDRAW 自绘按钮 Creates an owner-drawn button. The framework calls the DrawItem member function when a visual aspect of the button has changed. This style must be set when using the CBitmapButton class.

· BS_PUSHBUTTON 普通按钮 Creates a pushbutton that posts a WM_COMMAND message to the owner window when the user selects the button.

· BS_RADIOBUTTON 圆形选择按钮 Creates a small circle that has text displayed to its right (unless this style is combined with the BS_LEFTTEXT style). Radio buttons are usually used in groups of related but mutually exclusive choices.

· BS_3STATE 允许按钮有三种状态即:选中,未选中,未定 Same as a check box, except that the box can be dimmed as well as checked. The dimmed state typically is used to show that a check box has been disabled.

rect为窗口所占据的矩形区域,pParentWnd为父窗口指针,nID为该窗口的ID值。

获取/改变按钮状态:对于检查按钮和圆形按钮可能有两种状态,选中和未选中,如果设置了BS_3STATE或BS_AUTO3STATE风格就可能出现第三种状态:未定,这时按钮显示灰色。通过调用int CButton::GetCheck( ) 得到当前是否被选中,返回0:未选中,1:选中,2:未定。调用void CButton::SetCheck( int nCheck );设置当前选中状态。

处理按钮消息:要处理按钮消息需要在父窗口中进行消息映射,映射宏为ON_BN_CLICKED( id, memberFxn )id为按钮的ID值,就是创建时指定的nID值。处理函数原型为afx_msg void memberFxn( );

Static Box

静态文本控件的功能比较简单,可作为显示字符串,图标,位图用。创建一个窗口可以使用成员函数: BOOL CStatic::Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff );
其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD,WS_VISIBLE外,你可以针对静态控件指明专门的风格。

· SS_CENTER,SS_LEFT,SS_RIGHT 指明字符显示的对齐方式。

· SS_GRAYRECT 显示一个灰色的矩形

· SS_NOPREFIX 如果指明该风格,对于字符&将直接显示,否则&将作为转义符,&将不显示而在其后的字符将有下划线,如果需要直接显示&必须使用&&表示。

· SS_BITMAP 显示位图

· SS_ICON 显示图标

· SS_CENTERIMAGE 图象居中显示

控制显示的文本利用成员函数SetWindowText/GetWindowText用于设置/得到当前显示的文本。

控制显示的图标利用成员函数SetIcon/GetIcon用于设置/得到当前显示的图标。

控制显示的位图利用成员函数SetBitmap/GetBitmap用于设置/得到当前显示的位图。下面一段代码演示如何创建一个显示位图的静态窗口并设置位图

1
CStatic* pstaDis=new CStatic; pstaDis->Create("",WS_CHILD|WS_VISIBLE|SS_BITMAP|SSCENTERIMAGE, CRect(0,0,40,40),pWnd,1); CBitmap bmpLoad; bmpLoad.LoadBitmap(IDB_TEST); pstaDis->SetBitmap(bmpLoad.Detach());

Edit Box

Edit窗口是用来接收用户输入最常用的一个控件。创建一个输入窗口可以使用成员函数:
BOOL CEdit::Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff );
其中dwStyle将指明该窗口的风格,除了子窗口常用的风格WS_CHILD,WS_VISIBLE外,你可以针对输入控件指明专门的风格。

· ES_AUTOHSCROLL,ES_AUTOVSCROLL 指明输入文字超出显示范围时自动滚动。

· ES_CENTER,ES_LEFT,ES_RIGHT 指定对齐方式

· ES_MULTILINE 是否允许多行输入

· ES_PASSWORD 是否为密码输入框,如果指明该风格则输入的文字显示为*

· ES_READONLY 是否为只读

· ES_UPPERCASE,ES_LOWERCASE 显示大写/小写字符

控制显示的文本利用成员函数SetWindowText/GetWindowText用于设置/得到当前显示的文本。

通过GetLimitText/SetLimitText可以得到/设置在输入框中输入的字符数量。

由于在输入时用户可能选择某一段文本,所以通过void CEdit::GetSel( int& nStartChar, int& nEndChar )得到用户选择的字符范围,通过调用void CEdit::SetSel( int nStartChar, int nEndChar, BOOL bNoScroll = FALSE )可以设置当前选择的文本范围,如果指定nStartChar=0 nEndChar=-1则表示选中所有的文本。void ReplaceSel( LPCTSTR lpszNewText, BOOL bCanUndo = FALSE )可以将选中的文本替换为指定的文字。

此外输入框还有一些和剪贴板有关的功能,void Clear( );删除选中的文本,void Copy( );可将选中的文本送入剪贴板,void Paste( );将剪贴板中内容插入到当前输入框中光标位置,void Cut( );相当于Copy和Clear结合使用。

最后介绍一下输入框几种常用的消息映射宏:

· ON_EN_CHANGE 输入框中文字更新后产生

· ON_EN_ERRSPACE 输入框无法分配内存时产生

· ON_EN_KILLFOCUS / ON_EN_SETFOCUS 在输入框失去/得到输入焦点时产生

使用以上几种消息映射的方法为定义原型如:afx_msg void memberFxn( );的函数,并且定义形式如ON_Notification( id, memberFxn )的消息映射。如果在对话框中使用输入框,Class Wizard会自动列出相关的消息,并能自动产生消息映射代码。

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 滚动条拖动完成(用户松开鼠标)

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会自动列出相关的消息,并能自动产生消息映射代码。

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会自动列出相关的消息,并能自动产生消息映射代码。

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”,TVI_ROOT);
在根结点上添加Parent1 hSubItem = m_tree.InsertItem(“Child1_1”,hItem);
//在Parent1上添加一个子结点 hSubItem =
m_tree.InsertItem(“Child1_2”,hItem,hSubItem);
//在Parent1上添加一个子结点,排在Child1_1后面 hSubItem =
m_tree.InsertItem(“Child1_3”,hItem,hSubItem); hItem =
m_tree.InsertItem(“Parent2”,TVI_ROOT,hItem); hItem =
m_tree.InsertItem(“Parent3”,TVI_ROOT,hItem);

如果你希望在每个结点前添加一个小图标,就必需先调用CImageList SetImageList( CImageList
pImageList, int nImageListType
);指明当前所使用的ImageList,nImageListType为TVSIL_NORMAL。在调用完成后控件中使用图片以设置的
ImageList中图片为准。然后调用 HTREEITEM InsertItem( LPCTSTR lpszItem, int
nImage, int nSelectedImage, HTREEITEM hParent = TVI_ROOT, HTREEITEM
hInsertAfter =
TVI_LAST);添加结点,nImage为结点没被选中时所使用图片序号,nSelectedImage为结点被选中时所使用图片序号。下面的代码演示了ImageList的设置。

/m_list 为CImageList对象 IDB_TREE 为16(164)的位图,每个图片为1616共4个图标*/
m_list.Create(IDB_TREE,16,4,RGB(0,0,0));
m_tree.SetImageList(&m_list,TVSIL_NORMAL);
m_tree.InsertItem(“Parent1”,0,1); //添加,选中时显示图标1,未选中时显示图标0

此外CTreeCtrl还提供了一些函数用于得到/修改控件的状态。 HTREEITEM GetSelectedItem(
);将返回当前选中的结点的句柄。BOOL SelectItem( HTREEITEM hItem );将选中指明结点。 BOOL
GetItemImage( HTREEITEM hItem, int& nImage, int& nSelectedImage ) /
BOOL SetItemImage( HTREEITEM hItem, int nImage, int nSelectedImage
)用于得到/修改某结点所使用图标索引。 CString GetItemText( HTREEITEM hItem ) /BOOL
SetItemText( HTREEITEM hItem, LPCTSTR lpszItem );用于得到/修改某一结点的显示字符。
BOOL DeleteItem( HTREEITEM hItem );用于删除某一结点,BOOL DeleteAllItems(
);将删除所有结点。

此外如果想遍历树可以使用下面的函数: HTREEITEM GetRootItem( );得到根结点。 HTREEITEM
GetChildItem( HTREEITEM hItem );得到子结点。 HTREEITEM
GetPrevSiblingItem/GetNextSiblingItem( HTREEITEM hItem
);得到指明结点的上/下一个兄弟结点。 HTREEITEM GetParentItem( HTREEITEM hItem );得到父结点。

树形控件的消息映射使用ON_NOTIFY宏,形式如同:ON_NOTIFY( wNotifyCode, id, memberFxn
),wNotifyCode为通知代码,id为产生该消息的窗口ID,memberFxn为处理函数,函数的原型如同void
OnXXXTree(NMHDR pNMHDR, LRESULT
pResult),其中pNMHDR为一数据结构,在具体使用时需要转换成其他类型的结构。对于树形控件可能取值和对应的数据结构为:

· TVN_SELCHANGED 在所选中的结点发生改变后发送,所用结构:NMTREEVIEW

· TVN_ITEMEXPANDED 在某结点被展开后发送,所用结构:NMTREEVIEW

· TVN_BEGINLABELEDIT 在开始编辑结点字符时发送,所用结构:NMTVDISPINFO

· TVN_ENDLABELEDIT 在结束编辑结点字符时发送,所用结构:NMTVDISPINFO

· TVN_GETDISPINFO 在需要得到某结点信息时发送,(如得到结点的显示字符)所用结构:NMTVDISPINFO

关于ON_NOTIFY有很多内容,将在以后的内容中进行详细讲解。

关于动态提供结点所显示的字符:首先你在添加结点时需要指明lpszItem参数为:LPSTR_TEXTCALLBACK。在控件显示该结点时会通过发送
TVN_GETDISPINFO来取得所需要的字符,在处理该消息时先将参数pNMHDR转换为LPNMTVDISPINFO,然后填充其中
item.pszText。但是我们通过什么来知道该结点所对应的信息呢,我的做法是在添加结点后设置其lParam参数,然后在提供信息时利用该参数来查找所对应的信息。下面的代码说明了这种方法:

char szOut[8][3]={“No.1”,”No.2”,”No.3”}; //添加结点 HTREEITEM hItem =
m_tree.InsertItem(LPSTR_TEXTCALLBACK,…) m_tree.SetItemData(hItem, 0
); hItem = m_tree.InsertItem(LPSTR_TEXTCALLBACK,…)
m_tree.SetItemData(hItem, 1 ); //处理消息 void
CParentWnd::OnGetDispInfoTree(NMHDR pNMHDR, LRESULT pResult) {
TV_DISPINFO pTVDI = (TV_DISPINFO)pNMHDR;
pTVDI->item.pszText=szOut[pTVDI->item.lParam];
//通过lParam得到需要显示的字符在数组中的位置 *pResult = 0; }

关于编辑结点的显示字符:首先需要设置树形控件的TVS_EDITLABELS风格,在开始编辑时该控件将会发送TVN_BEGINLABELEDIT,你可以通过在处理函数中返回TRUE来取消接下来的编辑,在编辑完成后会发送TVN_ENDLABELEDIT,在处理该消息时需要将参数pNMHDR转换为
LPNMTVDISPINFO,然后通过其中的item.pszText得到编辑后的字符,并重置显示字符。如果编辑在中途中取消该变量为NULL。下面的代码说明如何处理这些消息:

//处理消息 TVN_BEGINLABELEDIT void CParentWnd::OnBeginEditTree(NMHDR
pNMHDR, LRESULT
pResult) { TV_DISPINFO pTVDI = (TV_DISPINFO)pNMHDR;
if(pTVDI->item.lParam==0);//判断是否取消该操作 pResult = 1; else pResult = 0;
} //处理消息 TVN_BEGINLABELEDIT void CParentWnd::OnBeginEditTree(NMHDR
pNMHDR, LRESULT
pResult) { TV_DISPINFO pTVDI = (TV_DISPINFO)pNMHDR;
if(pTVDI->item.pszText==NULL);//判断是否已经取消取消编辑
m_tree.SetItemText(pTVDI->item.hItem,pTVDI->pszText); //重置显示字符
*pResult = 0; }

上面讲述的方法所进行的消息映射必须在父窗口中进行(同样WM_NOTIFY的所有消息都需要在父窗口中处理)。

List Ctrl

列表控件可以看作是功能增强的ListBox,它提供了四种风格,而且可以同时显示一列的多中属性值。MFC中使用CListCtrl类来封装列表控件的各种操作。通过调用
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT
nID );创建一个窗口,dwStyle中可以使用以下一些列表控件的专用风格:

· LVS_ICON LVS_SMALLICON LVS_LIST LVS_REPORT
这四种风格决定控件的外观,同时只可以选择其中一种,分别对应:大图标显示,小图标显示,列表显示,详细报表显示

· LVS_EDITLABELS 结点的显示字符可以被编辑,对于报表风格来讲可编辑的只为第一列。

· LVS_SHOWSELALWAYS 在失去焦点时也显示当前选中的结点

· LVS_SINGLESEL 同时只能选中列表中一项

首先你需要设置列表控件所使用的ImageList,如果你使用大图标显示风格,你就需要以如下形式调用: CImageList
SetImageList( CImageList
pImageList, LVSIL_NORMAL);
如果使用其它三种风格显示而不想显示图标你可以不进行任何设置,否则需要以如下形式调用: CImageList SetImageList(
CImageList
pImageList, LVSIL_SMALL);

通过调用 int InsertItem( int nItem, LPCTSTR lpszItem
);可以在列表控件中nItem指明位置插入一项,lpszItem为显示字符。除LVS_REPORT风格外其他三种风格都只需要直接调用
InsertItem就可以了,但如果使用报表风格就必须先设置列表控件中的列信息。

通过调用 int InsertColumn( int nCol, LPCTSTR lpszColumnHeading, int
nFormat , int nWidth, int
nSubItem);可以插入列。iCol为列的位置,从零开始,lpszColumnHeading为显示的列名,nFormat为显示对齐方式,
nWidth为显示宽度,nSubItem为分配给该列的列索引。

在有多列的列表控件中就需要为每一项指明其在每一列中的显示字符,通过调用 BOOL SetItemText( int nItem, int
nSubItem, LPTSTR lpszText
);可以设置每列的显示字符。nItem为设置的项的位置,nSubItem为列位置,lpszText为显示字符。下面的代码演示了如何设置多列并插入数据:

m_list.SetImageList(&m_listSmall,LVSIL_SMALL);//设置ImageList
m_list.InsertColumn(0,”Col 1”,LVCFMT_LEFT,300,0);//设置列
m_list.InsertColumn(1,”Col 2”,LVCFMT_LEFT,300,1);
m_list.InsertColumn(2,”Col 3”,LVCFMT_LEFT,300,2);
m_list.InsertItem(0,”Item 1_1”);//插入行 m_list.SetItemText(0,1,”Item
1_2”);//设置该行的不同列的显示字符 m_list.SetItemText(0,2,”Item 1_3”);

此外CListCtrl还提供了一些函数用于得到/修改控件的状态。 COLORREF GetTextColor( )/BOOL
SetTextColor( COLORREF cr );用于得到/设置显示的字符颜色。 COLORREF GetTextBkColor(
)/BOOL SetTextBkColor( COLORREF cr );用于得到/设置显示的背景颜色。 void
SetItemCount( int iCount );用于得到添加进列表中项的数量。 BOOL DeleteItem(int
nItem);用于删除某一项,BOOL DeleteAllItems( );将删除所有项。 BOOL SetBkImage(HBITMAP
hbm, BOOL fTile , int xOffsetPercent, int yOffsetPercent);用于设置背景位图。
CString GetItemText( int nItem, int nSubItem );用于得到某项的显示字符。

列表控件的消息映射同样使用ON_NOTIFY宏,形式如同:ON_NOTIFY( wNotifyCode, id, memberFxn
),wNotifyCode为通知代码,id为产生该消息的窗口ID,memberFxn为处理函数,函数的原型如同void
OnXXXList(NMHDR pNMHDR, LRESULT
pResult),其中pNMHDR为一数据结构,在具体使用时需要转换成其他类型的结构。对于列表控件可能取值和对应的数据结构为:

· LVN_BEGINLABELEDIT 在开始某项编辑字符时发送,所用结构:NMLVDISPINFO

· LVN_ENDLABELEDIT 在结束某项编辑字符时发送,所用结构:NMLVDISPINFO

· LVN_GETDISPINFO 在需要得到某项信息时发送,(如得到某项的显示字符)所用结构:NMLVDISPINFO

关于ON_NOTIFY有很多内容,将在以后的内容中进行详细讲解。

关于动态提供结点所显示的字符:首先你在项时需要指明lpszItem参数为:LPSTR_TEXTCALLBACK。在控件显示该结点时会通过发送
TVN_GETDISPINFO来取得所需要的字符,在处理该消息时先将参数pNMHDR转换为LPNMLVDISPINFO,然后填充其中
item.pszText。通过item中的iItem,iSubItem可以知道当前显示的为那一项。下面的代码演示了这种方法:

char szOut[8][3]={“No.1”,”No.2”,”No.3”}; //添加结点
m_list.InsertItem(LPSTR_TEXTCALLBACK,…)
m_list.InsertItem(LPSTR_TEXTCALLBACK,…) //处理消息 void
CParentWnd::OnGetDispInfoList(NMHDR pNMHDR, LRESULT pResult) {
LV_DISPINFO pLVDI = (LV_DISPINFO)pNMHDR;
pLVDI->item.pszText=szOut[pTVDI->item.iItem];
//通过iItem得到需要显示的字符在数组中的位置 *pResult = 0; }

关于编辑某项的显示字符:(在报表风格中只对第一列有效)首先需要设置列表控件的LVS_EDITLABELS风格,在开始编辑时该控件将会发送
LVN_BEGINLABELEDIT,你可以通过在处理函数中返回TRUE来取消接下来的编辑,在编辑完成后会发送LVN_ENDLABELEDIT,在处理该消息时需要将参数pNMHDR转换为LPNMLVDISPINFO,然后通过其中的item.pszText得到编辑后的字符,并重置显示字符。如果编辑在中途中取消该变量为NULL。下面的代码说明如何处理这些消息:

//处理消息 LVN_BEGINLABELEDIT void CParentWnd::OnBeginEditList(NMHDR
pNMHDR, LRESULT
pResult) { LV_DISPINFO pLVDI = (LV_DISPINFO)pNMHDR;
if(pLVDI->item.iItem==0);//判断是否取消该操作 pResult = 1; else pResult = 0;
} //处理消息 LVN_BEGINLABELEDIT void CParentWnd::OnBeginEditList(NMHDR
pNMHDR, LRESULT
pResult) { LV_DISPINFO pLVDI = (LV_DISPINFO)pNMHDR;
if(pLVDI->item.pszText==NULL);//判断是否已经取消取消编辑
m_list.SetItemText(pLVDI->item.iItem,0,pLVDI->pszText); //重置显示字符
*pResult = 0; }

上面讲述的方法所进行的消息映射必须在父窗口中进行(同样WM_NOTIFY的所有消息都需要在父窗口中处理)。

如何得到当前选中项位置:在列表控件中没有一个类似于ListBox中GetCurSel()的函数,但是可以通过调用GetNextItem(
-1, LVNI_ALL | LVNI_SELECTED);得到选中项位置。

Tab Ctrl

Tab属性页控件可以在一个窗口中添加不同的页面,然后在页选择发生改变时得到通知。MFC中使用CTabCtrl类来封装属性页控件的各种操作。通过调用
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT
nID );创建一个窗口,dwStyle中可以使用以下一些属性页控件的专用风格:

TCS_BUTTONS 使用按钮来表示页选择位置 TCS_MULTILINE 分行显示页选择位置 TCS_SINGLELINE
只使用一行显示页选择位置 在控件创建后必需向其中添加页面才可以使用,添加页面的函数为: BOOL InsertItem( int
nItem, LPCTSTR lpszItem
);nItem为位置,从零开始,lpszItem为页选择位置上显示的文字。如果你希望在页选择位置处显示一个图标,你可以调用 BOOL
InsertItem( int nItem, LPCTSTR lpszItem, int nImage
);nImage指明所使用的图片位置。(在此之前必须调用CImageList SetImageList( CImageList
pImageList );设置正确的ImageList)

此外CTabCtrl还提供了一些函数用于得到/修改控件的状态。 int GetCurSel( )/int SetCurSel( int
nItem );用于得到/设置当前被选中的页位置。 BOOL DeleteItem( int nItem )/BOOL
DeleteAllItems( );用于删除指定/所有页面。 void RemoveImage( int nImage
);用于删除某页选择位置上的图标。

属性页控件的消息映射同样使用ON_NOTIFY宏,形式如同:ON_NOTIFY( wNotifyCode, id, memberFxn
),wNotifyCode为通知代码,id为产生该消息的窗口ID,memberFxn为处理函数,函数的原型如同void
OnXXXTab(NMHDR pNMHDR, LRESULT
pResult),其中pNMHDR为一数据结构,在具体使用时需要转换成其他类型的结构。对于列表控件可能取值和对应的数据结构为:

TCN_SELCHANGE 在当前页改变后发送,所用结构:NMHDR TCN_SELCHANGING
在当前页改变时发送可以通过返回TRUE来禁止页面的改变,所用结构:NMHDR

一般来讲在当前页发生改变时需要隐藏当前的一些子窗口,并显示其它的子窗口。下面的伪代码演示了如何使用属性页控件:
CParentWnd::OnCreate(…)
{
m_tab.Create(…);
m_tab.InsertItem(0,”Option 1”);
m_tab.InsertItem(1,”Option 2”);
Create a edit box as the m_tab’s Child
Create a static box as the m_tab’s Child
edit_box.ShowWindow(SW_SHOW); // edit box在属性页的第一页
static_box.ShowWindow(SW_HIDE); // static box在属性页的第二页
}
void CParentWnd::OnSelectChangeTab(NMHDR pNMHDR, LRESULT pResult)
{//处理页选择改变后的消息
if(m_tab.GetCurSel()==0)
{//根据当前页显示/隐藏不同的子窗口
edit_box.ShowWindow(SW_SHOW);
static_box.ShowWindow(SW_HIDE);
}
else
{//
edit_box.ShowWindow(SW_HIDE);
static_box.ShowWindow(SW_SHOW);
}
}


坚持原创技术分享,您的支持将鼓励我继续创作!
-------------本文结束感谢您的阅读-------------