在窗体中需要用到多页显示的时候就需要用到选项卡控件(TabControl)。
一、属性
1、Name(名称)
和窗口一样,Name属性是选项卡类的实例化,我们可以用【名称.属性/方法】来使用选项卡控件。
2、Style(样式)
选项卡样式有4种,分别指定了选项卡标签的位置。0 - 标签在顶部,1 - 标签在底部,2 - 标签在左边,3 - 标签在右边。
3、MultiLine(多行)
设置选项卡标签是否允许多行显示。
4、Enabled(可用)、Visible(显示)
使能和显示选项卡。
5、Selected(选中)
当前选中选项卡标签的序号,从0开始。
6、Text(文本)
设置选项卡标签的文本,参数为标签序号,从0开始。
7、ItemParam(子项参数)(永芳喜欢用ItemData,如果更新会是这个属性名)
这个属性为了方便操作绑定的选项卡窗口的,但是在5.2.10还没有添加到Class_Tab类里(虽然更新文件里写了,实际没添加),我们可以自己打开VFB的文件夹,在Compile文件夹下,找到inc,进入后找到WinClass,VBF的基础类文件都在这个文件夹里。我们在这个文件夹里找到ClsTab.inc文件,用文本文件打开,然后添加代码即可使用该属性。
首先在Type Class_TabControl和End Type的类函数声明里添加以下代码:
Declare Property ItemParam(Index As Long) As LPARAM '
Declare Property ItemParam(Index As Long,nParam As LPARAM)
然后在文本的最末尾(随便其他地方都可以,自己喜欢),添加以下代码:
Property Class_TabControl.ItemParam(Index As Long) As LPARAM '
Dim TB As TC_ITEM
TB.Mask = TCIF_PARAM '设置掩码,返回选项卡名
SendMessage(hWndControl,TCM_GETITEM,Index,Cast(LPARAM,VarPtr(TB)))
Return TB.lParam
End Property
Property Class_TabControl.ItemParam(Index As Long,nParam As LPARAM)
Dim TB As TC_ITEM
TB.Mask = TCIF_PARAM '设置掩码,返回选项卡名
TB.lParam = nParam
SendMessage(hWndControl,TCM_SETITEM,Index,Cast(LPARAM,VarPtr(TB)))
End Property
保存文件即可。
二、方法
1、AddTab (添加标签)
添加一个选项卡标签。该方法函数原型如下:
Function AddTab (TabText As CWSTR ,lParam As lParam = 0) As Boolean '添加或在选项卡,如果成功返回 TRUE 否则 FALSE 。
2、InsertTab (插入标签)
插入一个选项卡标签。该方法函数原型如下:
Function InsertTab (Index As Long ,TabText As CWSTR,lParam As lParam = 0) As Boolean '添加或在选项卡,如果成功返回 TRUE 否则 FALSE 。
3、Remove (移除标签)
移除一个选项卡标签。该方法函数原型如下:
Function Remove (Index As Long ) As Boolean '删除选项卡,如果成功返回 TRUE 否则 FALSE 。
4、RemoveAll(移除全部)
移除全部选项卡标签。该方法函数原型如下:
Function RemoveAll () As Boolean '删除所有选项卡,如果成功返回 TRUE 否则返回 FALSE。
5、GetCount (获取数量)
获取选项卡标签数量。该方法函数原型如下:
Function GetCount () As Long '返回选项卡数,如果不成功则为返回零。
三、事件
1、TCN_SelChange事件
Sub Form1_TabControl1_TCN_SelChange(hWndForm As hWnd, hWndControl As hWnd,pNMHDR As NMHDR ) '选择了列表
End Sub
选择新的选项卡标签后产生的事件。(这时已经改过去了,是新的标签)
2、TCN_SelChanging事件
Function Form1_TabControl1_TCN_SelChanging(hWndForm As hWnd, hWndControl As hWnd,pNMHDR As NMHDR ) As LResult '选择的项将要被切换至另一个
Function = False '允许更改选择。返回 TRUE 将不允许更改选择
End Function
选择选项卡标签时将要从原有标签改变到新标签时产生的事件。(这时还是没改过去,还是原先的标签)
四、示例
选项卡需要绑定每个选项卡的窗体,示例中使用3个选项卡,所以需要添加3个窗体(两个启动的时候设置,一个通过运行中通过按钮设置)。添加窗体在工程选项卡中右键单击,在弹出的菜单中选择新增窗体,然后选择“标准空窗口【模板】.frm”即可添加一个窗体。然后设置窗体属性Name分别改成frmTab0,frmTab1,frmTab2。同时设置WinStyle属性(该属性可以设置窗体的所有样式),这里设置比较彻底和快捷,同时也是因为TabControl控件没有把Visible属性添加的属性栏里允许设置。WinStyle属性窗口如下:
将样式里的WS_CAPTION,WS_MAXIMIZEBOX,WS_MINIMIZEBOX,WS_POPUP,WS_SIZEBOX,WS_SYSMENU,WS_THICKFRAME和WS_VISIBLE这些选项都去掉,同时勾选WS_CHILD(作为子窗体)。设置完成如下图所示:
添加完成后可以看到工程里有4个窗体,如图所示:
每个绑定的子窗体随意放上一些控件,如图:
frmTab0窗体:
frmTab1窗体:
frmTab2窗体:
主窗体设计如图:
代码如下:
Sub Form1_WM_Create(hWndForm As hWnd,UserData As Integer) '完成创建窗口及所有的控件后,此时窗口还未显示。注:自定义消息里 WM_Create 此时还未创建控件和初始赋值。
TabControl1.AddTab "Tab1",cast(LPARAM,frmTab0.Show(hWndForm)) '添加选项卡,同时将绑定的窗体句柄保存到子项参数里。
TabControl1.AddTab "Tab2",Cast(LPARAM,frmTab1.Show(hWndForm))
End Sub
Sub SetTabFormPos(hWndForm As hWnd,nTabPage As long)
Dim rc As RECT
GetWindowRect TabControl1.hWnd, @rc '获取Tab控件大小
TabCtrl_AdjustRect(TabControl1.hWnd, 0, @rc) '计算显示的区域大小,存在rc里
MapWindowPoints HWND_DESKTOP, hWndForm, Cast(LPPOINT, @rc), 2 '屏幕坐标转换成主窗体坐标
SetWindowPos Cast(HWND, TabControl1.ItemParam(nTabPage)), HWND_TOP, rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top, 0 '调整窗体位置
End Sub
Sub Form1_Shown(hWndForm As hWnd,UserData As Integer) '窗口完全显示后。UserData 来自显示窗口最后1个参数。
TabControl1.Selected = 0 '需要显示的标签页
frmTab0.Visible = True '需要显示的窗体
SetTabFormPos(hWndForm, 0) '调整窗体位置
End Sub
Sub Form1_TabControl1_TCN_SelChange(hWndForm As hWnd, hWndControl As hWnd,pNMHDR As NMHDR ) '选择了列表
SetTabFormPos(hWndForm, TabControl1.Selected) '调整窗体位置
ShowWindow Cast(HWND, TabControl1.ItemParam(TabControl1.Selected)), SW_SHOW '显示窗体
SetFocus pNMHDR.hwndFrom '设置焦点
End Sub
Function Form1_TabControl1_TCN_SelChanging(hWndForm As hWnd, hWndControl As hWnd,pNMHDR As NMHDR ) As LResult '选择的项将要被切换至另一个
ShowWindow Cast(HWND, TabControl1.ItemParam(TabControl1.Selected)), SW_HIDE '隐藏当前窗体
Function = False '允许更改选择。返回 TRUE 将不允许更改选择
End Function
Sub Form1_Command1_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd) '单击
if IsWindow(frmTab2.hWnd) Then Exit sub '如果创建了窗体,则不再重复创建
TabControl1.AddTab "新选项卡",Cast(LPARAM,frmTab2.Show(hWndForm))
End Sub
Sub Form1_Command2_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd) '单击
TabControl1.Remove TabControl1.Selected
TabControl1.Focus = 0 '把焦点默认给第1个选项卡
End Sub
Sub Form1_Command3_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd) '单击
ShowWindow Cast(HWND, TabControl1.ItemParam(TabControl1.Selected)), SW_HIDE '需要先隐藏当前窗体
TabControl1.RemoveAll '再清除选项卡标签
End Sub
Sub Form1_Command4_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd) '单击
AfxMsg "当前选中的是第" & TabControl1.Selected + 1 & "个选项卡标签"
End Sub
Sub Form1_Command5_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd) '单击
TabControl1.Text(TabControl1.Selected) = "新标签"
End Sub
运行效果:
完整代码:
https://github.com/rainheart311/VisualFreeBASIC/tree/master/TabControl