工具栏的图标视图

工具栏的列表视图

只有图像的列表视图

只有标题的列表视图

第一步:设置子类化窗体
首先,我们需要获取窗体的基础信息,例如窗体、客户区和VBE编辑器的句柄。然后,我们需要对窗体进行子类化,让用户可以对子窗口(工具栏)进行自定义,例如处理来自工具栏的各种通知、完成工具栏的绘制操作等。
第二步:创建空白工具栏
想要把一个Windows通用控件创建出来是非常简单的,大家可以直接使用API函数CreateWindowEx来实现。这是一个创建空白工具栏控件的使用案例:
Dim DstyleS&: DstyleS = WS_CHILD Or WS_VISIBLE Or CCS_TOP Or TBSTYLE_FLAT Or TBSTYLE_LIST
Dim DstyleE&: DstyleE = 0
Uf.Tobr = CreateWindowExA(DstyleE, TOOLBARCLASSNAME, vbNullString, DstyleS, 0, 0, 0, 0, Uf.Clit, 0, 0, ByVal 0)
值得注意的是,WS_VISIBLE样式代表工具栏在创建之初即为可见。工具栏默认具有CCS_TOP样式,它指示了工具栏在父窗口顶部显示,当然你也可以将其更换为CCS_BOTTOM样式以在底部显示。列表视图的按钮文本会在图像右侧显示,它由TBSTYLE_FLAT和TBSTYLE_LIST两个样式指定,若不包含这两个样式则显示为图标视图。
由于本例的工具栏是窗体的子控件,因此在创建工具栏时,我们应该指定窗口样式包含WS_CHILD,同时设置父窗口为窗体的客户区(注意不是整个窗体,否则会造成无法接收工具栏通知的现象)。此外,像是工具栏和状态栏等控件,在创建时,用户不需要指定左上角位置和宽高值,因为它们默认会依据父窗口自行决定。
当不再需要工具栏时,用户需要调用DestroyWindow函数手动销毁工具栏,以释放资源。
DestroyWindow Uf.Tobr
第三步:创建图像列表
为了让工具栏能够显示按钮图像,我们需要先创建一个图像列表,并将其与工具栏相关联。随后,用户可以往图像列表中添加自己需要的图像,图像的索引在图像列表中按照添加顺序依次排布,第一个添加的图像索引为0,第二个为1,等等。在创建完图像列表之后,用户便可以使用图像索引来指定按钮要显示的图像。
我们先使用API函数ImageList_Create来创建一个空白图像列表,然后使用SendMessage函数给工具栏发送TB_SETIMAGELIST消息,将图像列表与工具栏相关联。随后,我们再给工具栏发送一个TB_LOADIMAGES消息,为图像列表添加一些系统图像。
Uf.Imge = ImageList_Create(16, 16, ILC_MASK Or ILC_COLOR16, 4, 1)
SendMessageA Uf.Tobr, TB_SETIMAGELIST, 0, ByVal Uf.Imge
SendMessageA Uf.Tobr, TB_LOADIMAGES, IDB_HIST_SMALL_COLOR, ByVal HINST_COMMCTRL
创建完的图像列表具有以下特征:16像素宽、16像素高、支持透明背景、16位彩色、最初具有4个图像、每次超出添加时扩容 1个位置。
工具栏控件为用户提供了一些可用的系统图像,它们被分类集合到了系统图像集中。本例指定了IDB_HIST_SMALL_COLOR系统图像集,它包含了左箭头、右箭头和收藏夹等图像。其它的系统图像集,例如包含复制、粘贴和剪切等图像的IDB_STD_SMALL_COLOR,包含大图标、小图标、列表视图和详细视图等图像的IDB_VIEW_SMALL_COLOR。
当不再使用图像列表时,用户需要调用ImageList_Destroy函数手动销毁图像列表,以释放资源。
ImageList_Destroy Uf.Imge
第四步:为工具栏添加命令按钮
在这一步,我们将为空白的工具栏添加用户可以交互的命令按钮。关于命令按钮,你需要提前了解它的一些属性:标题、标识符、图像索引、状态和样式。
|
按钮标题 |
按钮的标题文本。 |
|
按钮标识符 |
每个按钮都有一个标识符,用户可以自定义它的数值,用以区分用户点击了哪个按钮。 |
|
按钮图像索引 |
每个按钮都可以显示图像,用户可以使用图像索引指定要显示图像列表中的第几个图像。如果使用I_IMAGENONE(值为-2),则表示该按钮无图像。 |
|
按钮状态 |
代表了按钮可以具有的状态,例如TBSTATE_ENABLED表示默认按钮状态,TBSTATE_INDETERMINATE表示按钮呈灰显状态且不可用,TBSTATE_CHECKED表示按钮已被选中,等等。 |
|
按钮样式 |
代表按钮可采用的样式,例如BTNS_CHECK表示切换按钮,BTNS_BUTTON表示默认按钮,BTNS_AUTOSIZE表示自动宽度按钮,BTNS_SEP表示分隔符,等等 |
以下是晚间写好的自定义函数,参数依次是工具栏句柄、图像索引、唯一识别符、标题、状态和样式,你可以使用它来添加工具栏按钮:
#If VBA7 And Win64 Then
Public Function TOOLBAR_AddButton(ByVal TOOLBAR As LongPtr, ByVal ImageIndex As Long, ByVal Id As Long, ByVal Text As String, ByVal State As Long, ByVal Style As Long) As Boolean
#Else
Public Function TOOLBAR_AddButton(ByVal TOOLBAR As Long, ByVal ImageIndex As Long, ByVal Id As Long, ByVal Text As String, ByVal State As Long, ByVal Style As Long) As Boolean
#End If
Dim Tbutton As TBBUTTON
Tbutton.iBitmap = ImageIndex
Tbutton.idCommand = Id
Tbutton.fsState = State
Tbutton.fsStyle = Style
Tbutton.iString = StrPtr(Text)
SendMessageA TOOLBAR, TB_BUTTONSTRUCTSIZE, LenB(Tbutton), ByVal 0
TOOLBAR_AddButton = SendMessageA(TOOLBAR, TB_ADDBUTTONSW, 1, ByVal VarPtr(Tbutton))
End Function
1. 添加单选按钮
单选按钮需要将按钮样式设置为BTNS_CHECK Or BTNS_GROUP。使用以下代码添加的单选按钮1001和1002,当用户点击其中一个按钮时另一个按钮自动取消选中。你也可以将BTNS_GROUP样式去掉,以添加切换按钮,当用户点击它的时候,按钮会切换选中/未选中状态。
TOOLBAR_AddButton Uf.Tobr, 0, 1001, "左箭头", TBSTATE_ENABLED, BTNS_CHECK Or BTNS_GROUP Or BTNS_AUTOSIZE
TOOLBAR_AddButton Uf.Tobr, 1, 1002, "右箭头", TBSTATE_ENABLED Or TBSTATE_CHECKED, BTNS_CHECK Or BTNS_GROUP Or BTNS_AUTOSIZE
2. 添加默认按钮
默认按钮需要指定样式包含BTNS_BUTTON,当用户点击时按钮会呈现按压后弹起的效果。
TOOLBAR_AddButton Uf.Tobr, 2, 1003, "收藏夹", TBSTATE_ENABLED, BTNS_BUTTON Or BTNS_AUTOSIZE
TOOLBAR_AddButton Uf.Tobr, 3, 1004, "添加到收藏夹", TBSTATE_ENABLED, BTNS_BUTTON Or BTNS_AUTOSIZE
TOOLBAR_AddButton Uf.Tobr, 4, 1005, "视图树", TBSTATE_ENABLED, BTNS_BUTTON Or BTNS_AUTOSIZE
第五步:自动调整工具栏大小
工具栏窗口在收到WM_SIZE或TB_AUTOSIZE消息时会自动调整大小。当用户对按钮进行操作之后,如添加新按钮,建议手动发送上述任一消息,以避免按钮显示不完全的现象。
SendMessageA Uf.Tobr, TB_AUTOSIZE, 0, 0
VBA完整代码展示

相关文章
https://mp.weixin.qq.com/s/LMFJfRn-EMzQj0W-XiHdMg



