WIN32汇编语言教程:第09章 通用控件 · 9.3 使用工具栏(4)
● TBSTYLE_FLAT——按钮的样式为平面样式,如果指定TBSTYLE_FLAT风格,创建的工具栏如图9.5上方的工具栏所示,如果不指定这个风格,则创建如图9.5下方所示的传统样式的工具栏。
● CCS_NODIVIDER——工具栏边上没有分隔线,如果指定这个风格,那么图9.5中就不会有数字(1)标出的横线。
● TBSTYLE_WRAPABLE——工具栏支持多行显示。
● CCS_TOP,CCS_BOTTOM或CCS_NOMOVEY——指定工具栏的位置,分别表示工具栏位于窗口的上方(默认风格)、底部和不会自动在垂直方向移动。
● CCS_NOPARENTALIGN——工具栏自动设置自己的高度,但不自动设置宽度和位置。
● CCS_NORESIZE——禁止工具栏的自动缩放功能,相当于禁止了上面的CCS_TOP、CCS_BOTTOM,CCS_NOMOVEY和CCS_NOPARENTALIGN风格。
● CCS_ADJUSTABLE——允许用户在按下Shift键的同时通过拖动工具栏上的按钮来调整按钮位置以及删除按钮。
● TBSTYLE_ALTDRAG——对CCS_ADJUSTABLE风格的工具栏将拖动时的按键由Shift键改为Alt键。
● TBSTYLE_TOOLTIPS——工具栏支持工具提示信息。
图9.5 工具栏的风格
hBMInst和wBMID参数用来指定绘画工具栏上的按钮使用的位图,位图可以在资源中定义也可以是已经装入内存的位图。如果使用资源中的位图,那么hBMInst指定包含位图资源的模块的实例句柄,wBMID指定位图资源的ID;如果hBMInst指定为NULL,那就表示要使用一个已经装入内存的位图,这时wBMID必须指定一个合法的位图句柄。
指定了使用的位图以后,nBitmaps,dxBitmap和dyBitmap参数继续给出了位图的属性,工具栏中的每个按钮并不使用一幅单独的位图,而是所有按钮的位图水平排列在一起组成一幅大的位图,nBitmaps参数说明了这幅大位图中包含多少个按钮位图,dxBitmap和dyBitmap参数指出了单个按钮位图的宽度和高度。显然,整个位图的高度就等于dyBitmap,宽度等于nBitmaps乘以dxBitmap。
图9.6是一幅典型的在工具栏中使用的位图,位图中包含了15个按钮。由于工具栏按照位置来分隔并使用位图,所以位图中各按钮的位置必须严格按照尺寸等距离排列,而且位图中不同按钮位图的尺寸必须是相同的。
图9.6 工具栏使用的位图
除了使用自定义的位图以外,Comctl32.dll库文件中也提供一些通用的位图供工具栏使用。为了使用这组位图,可以在hBMInst参数中使用预定义的模块实例句柄HINST_COMMCTRL。
Comctl32.dll包含了两组可以使用的位图。第一组就是如图9.6所示的位图,可以在wBMID中指定IDB_STD_LARGE_COLOR(24×24像素)或IDB_STD_SMALL_COLOR(16×16像素)来引用它们。这组位图包括15个按钮,Windows.inc文件中已经为每个按钮的位置索引定义了预定义值,从左到右分别是STD_CUT,STD_COPY,STD_PASTE,STD_UNDO,STD_REDOW(不知道REDO后面为什么有个W),STD_DELETE,STD_FILENEW,STD_FILEOPEN,STD_FILESAVE,STD_PRINTPRE,STD_PROPERTIES,STD_HELP,STD_FIND,STD_REPLACE和STD_PRINT。
第二组位图可以在wBMID中使用IDB_VIEW_LARGE_COLOR或IDB_VIEW_SMALL_COLOR来引用它们,这个位图包含12个按钮图像,索引值0~11分别被预定义为VIEW_LARGEICONS,VIEW_SMALLICONS,VIEW_LIST,VIEW_DETAIL,VIEW_SORTNAME,VIEW_SORTSIZE,VIEW_SORTDATE,VIEW_SORTTYPE,VIEW _PARENTFOLDER,VIEW_NETCONNECT,VIEW_NETDISCONNECT和VIEW _NEWFOLDER,读者从字面上就可以想出这些位图究竟是什么样的。
参数dxButton和dyButton指定工具栏上按钮的尺寸,按钮的尺寸一般比按钮图像的尺寸要大一点。
剩余的3个参数lpButtons,iNumButtons和uStructSize用来定义工具栏上的按钮,函数根据它们给出的数据创建工具栏上的全部按钮。lpButtons参数指向一组按顺序排列的TBBUTTON结构,每个TBBUTTON结构定义一个按钮,TBBUTTON结构的排列顺序决定了按钮在工具栏上的排列顺序;iNumButtons参数指定工具栏上的按钮总数,也就是lpButtons指向的数据中包含的TBBUTTON结构的总数;uStructSize参数指明TBBUTTON结构的长度。
TBBUTTON结构的定义如下:
TBBUTTON STRUCT iBitmap DWORD ? ;按钮使用的位图编号 idCommand DWORD ? ;按钮按下时在WM_COMMAND中使用的ID fsState BYTE ? ;按钮状态 fsStyle BYTE ? ;按钮风格 _wPad1 WORD ? ; dwData DWORD ? ;自定义数据 iString DWORD ? ;按钮字符串索引 TBBUTTON ENDS
上面的结构定义取自MASM32软件包所附带的Windows.inc文件,但是Microsoft Win32 API手册中的结构定义并没有_wPad1字段,现在并没有资料判定Windows.inc中的定义是否正确,但这个定义在实际使用中并不会出错,所以本书中的例子沿用这个定义,这一点请读者注意。结构中各字段的含义如下。
● iBitmap——按钮使用的图像在wBMID 参数指定的位图中的位置索引。位置索引从0开始,也就是说第一个按钮图像的位置索引是0。
● idCommand——按下按钮以后,工具栏会向父窗口发送WM_COMMAND消息,这个字段指定消息附带的命令ID号,一般在这里指定与按钮对应的菜单项使用的ID。
● fsState——按钮的类型和初始状态,可以是下面取值的组合:
■ TBSTATE_CHECKED——按钮的类型是复选框按钮,并且按钮初始化为选中状态(即保持按下状态)。
■ TBSTATE_ENABLED——按钮被允许,如果不指定这个标志,按钮将显示为灰色,并且不会接收用户的动作。
■ TBSTATE_HIDDEN——隐藏状态,按钮不显示在工具栏上。
■ TBSTATE_INDETERMINATE——按钮处于灰化状态,但可以接收用户的动作。
■ TBSTATE_PRESSED——按钮处于按下状态。
■ TBSTATE_WRAP——在包含TBSTYLE_WRAPABLE风格的多行工具栏中,从此按钮开始换行。
● fsStyle——按钮风格,可以是下面取值的组合:
■ TBSTYLE_BUTTON——标准按钮。
■ TBSTYLE_CHECK——复选框按钮(按钮状态在按下和凸起之间切换)。
■ TBSTYLE_GROUP——指定复选框按钮的分组边界。
■ TBSTYLE_CHECKGROUP——TBSTYLE_CHECK风格和TBSTYLE_GROUP风格的组合。
■ TBSTYLE_SEP——按钮之间的分隔线。
● dwData——用户自定义数据。设置后可以通过TB_GETBUTTON消息查询。
● iString——按钮标记的索引。
在例子程序中,使用模块句柄HINST_COMMCTRL和位图句柄IDB_STD_SMALL _COLOR来指定使用Comctl32.dll中的预定义位图,并预定义了16个TBBUTTON结构,存放在常量stToolbar开始的地址中。
当使用预定义位图的时候,函数自己知道位图的大小和按钮的大小,所以位图和按钮的尺寸参数都可以设置为0。函数的返回值是工具栏窗口的句柄,把它存放到hWinToolbar变量中以便在以后使用。
有关代码如下:
... stToolbar equ this byte TBBUTTON <STD_FILENEW,IDM_NEW,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1> TBBUTTON <STD_FILEOPEN,IDM_OPEN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1> TBBUTTON <STD_FILESAVE,IDM_SAVE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1> TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1> TBBUTTON <STD_PRINTPRE,IDM_PAGESETUP,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1> ... NUM_BUTTONS EQU 16 ... invoke CreateToolbarEx,hWinMain,WS_VISIBLE or WS_CHILD or TBSTYLE_FLAT \ or TBSTYLE_TOOLTIPS or CCS_ADJUSTABLE,ID_TOOLBAR,0,HINST_COMMCTRL,\ IDB_STD_SMALL_COLOR,offset stToolbar,NUM_BUTTONS,\ 0,0,0,0,sizeof TBBUTTON mov hWinToolbar,eax
9.3.2 工具栏的控制消息
程序可以通过向工具栏控件发送消息来控制工具栏,工具栏的控制消息比较多,下面分类进行讨论。
1. 工具栏的创建和维护消息
如果使用CreateWindowEx函数来创建工具栏,那么创建的是一个空白的工具栏,还需要对工具栏进行初始化。初始化的工作包括指定位图、指定TBBUTTON结构长度和添加按钮。
指定工具栏使用的位图使用TB_ADDBITMAP消息:
invoke SendMessage,hToolbar,TB_ADDBITMAP,nButtons,lptbab
wParam中的nButtons指定位图中包含的按钮图像数量,lptbab指向一个TBADDBITMAP结构,结构中定义了两个字段:位图资源的模块句柄和位图ID,这两个字段的定义方法和CreateToolbarEx函数的hBMInst和wBMID参数的定义方法是一样的。结构定义如下:
TBADDBITMAP STRUCT hInst DWORD ? ;包含位图的模块实例句柄 nID DWORD ? ;位图资源的ID TBADDBITMAP ENDS
指定了位图以后,需要发送TB_SETBITMAPSIZE和TB_SETBUTTONSIZE消息来指定按钮图像的大小和按钮的大小,这一步相当于指定CreateToolbarEx函数中使用的dxButton,dyButton,dxBitmap和dyBitmap参数。
宽度和高度参数分别由lParam参数的高16位和低16位指定:
invoke SendMessage,hToolbar,TB_SETBITMAPSIZE,0,dwWidth + dwHeight shl 16 invoke SendMessage,hToolbar,TB_SETBUTTONSIZE,0,dwWidth + dwHeight shl 16
CreateToolbarEx函数的最后一个参数uStructSize是为了向系统通知TBBUTTON的结构长度,如果使用CreateWindowEx函数来创建工具栏,那么这一步必须通过发送TB_BUTTONSTRUCTSIZE消息来完成:
invoke SendMessage,hToolbar,TB_BUTTONSTRUCTSIZE,sizeof TBBUTTON,0
接下来可以使用TB_ADDBUTTONS消息来添加按钮,uNumButtons参数指定要添加的按钮数量,lpButtons参数指向一组TBBUTTON结构,结构的数量和uNumButtons参数相对应,在发送这个消息前必须先发送TB_BUTTONSTRUCTSIZE消息指定结构的长度: