windows环境下32位汇编语言程序设计-第47章
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
■ 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_MCTRL和位图句柄IDB_STD_SMALL _COLOR来指定使用ctl32。dll中的预定义位图,并预定义了16个TBBUTTON结构,存放在常量stToolbar开始的地址中。
当使用预定义位图的时候,函数自己知道位图的大小和按钮的大小,所以位图和按钮的尺寸参数都可以设置为0。函数的返回值是工具栏窗口的句柄,把它存放到hWinToolbar变量中以便在以后使用。
有关代码如下:
。。。
stToolbar equ this byte
TBBUTTON
TBBUTTON
TBBUTTON
TBBUTTON
TBBUTTON
。。。
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_MCTRL;
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消息指定结构的长度:
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第9章 通用控件
9。3 使用工具栏(5)
invoke SendMessage;hToolbar;TB_ADDBUTTONS;uNumButtons;lpButtons
TB_ADDBUTTONS消息总是在工具栏的最后添加按钮,使用TB_INSERTBUTTON消息可以在几个按钮的中间插入新的按钮,但一次只能插入一个按钮,消息的wParam参数指定插入位置,lParam消息指向一个TBBUTTON结构:
invoke SendMessage;hToolbar;TB_INSERTBUTTON;iButtons;lpButton
当然,如果使用CreateToolbarEx函数创建工具栏,那么上面的步骤就全部由函数包办了,这就是使用专用函数的好处。
也可以通过发送TB_DELETEBUTTON消息来删除工具栏上的按钮,iButton参数指定按钮的位置索引,第一个按钮用0表示:
invoke SendMessage;hToolbar;TB_DELETEBUTTON;iButton;0
除了这些消息,还有一些消息可以用来获取工具栏的当前状态,如表9。3所示。
表9。3 获取工具栏状态的消息
消 息
WParam
Iparam
说 明
TB_BUTTONCOUNT
0
0
返回工具栏上按钮的数量
TB_GETBITMAP
idButton
0
返回指定按钮的图像索引
TB_GETBUTTON
iButton
lpButton
返回指定按钮的TBBUTTON结构
TB_GETROWS
0
0
返回多行工具栏当前包含的行数
TB_GETITEMRECT
iButton
lpRect
在lParam指定的位置返回包含指定按钮
的位置的RECT结构
所有消息的参数中,iButton指按钮的位置索引,idButton指按钮的命令ID值。
2。 移动和缩放工具栏
用默认参数建立的工具栏能够自动移动和缩放大小,当主窗口的宽度变宽的时候,即使不对工具栏进行调整,工具栏的宽度还是会自动扩展到父窗口的宽度。但有个小缺陷就是工具栏自动变宽的时候,图9。5中数字(1)所示的分隔线却不会自动变长,结果工具栏的外观似乎不是很好看,所以在主窗口的WM_SIZE消息中还是需要对工具栏进行调整。不过调整的方法很简单,只要对工具栏发送TB_AUTOSIZE消息就可以了:
invoke SendMessage;hToolbar;TB_AUTOSIZE;0;0
消息中不必指定位置和大小参数,工具栏会自动计算新的大小,消息发送以后分隔线也会被调整到正确的宽度,一切看起来就完美了。
3。 工具栏按钮的维护消息
工具栏按钮可以像菜单项一样有选中、允许和灰化等状态,在程序中可以使用一组TB_ISBUTTONxxxx类型的消息来检测按钮的状态:
invoke SendMessage;hToolbar;TB_ISBUTTONCHECKED;idButton;0 ;是否在选中状态
invoke SendMessage;hToolbar;TB_ISBUTTONENABLED;idButton;0 ;是否在允许状态
invoke SendMessage;hToolbar;TB_ISBUTTONHIDDEN;idButton;0 ;是否在隐藏状态
invoke SendMessage;hToolbar;TB_ISBUTTONINDETERMINATE;idButton;0 ;是否灰化
invoke SendMessage;hToolbar;TB_ISBUTTONPRESSED;idButton;0 ;是否在按下状态
对于上面这些消息,如果答案是肯定的,那么消息返回TRUE,否则消息返回FALSE。如果嫌每次调用只能检测一种状态显得比较麻烦,也可以发送TB_GETSTATE消息:
invoke SendMessage;hToolbar;TB_GETSTATE;idButton;0
函数会返回按钮所有状态的组合值(TBSTATE_INDETERMINATE,TBSTATE _CHECKED,TBSTATE_ENABLED,TBSTATE_HIDDEN或TBSTATE_PRESSED等状态的组合)。在上面这些消息中,idButton用来指定按钮对应的命令ID。
设置按钮的状态也可以通过一组消息来完成:
invoke SendMessage;hToolbar;TB_CHECKBUTTON;idButton;uState ;选中按钮
invoke SendMessage;hToolbar;TB_ENABLEBUTTON;idButton;uState ;允许按钮
invoke SendMessage;hToolbar;TB_HIDEBUTTON;idButton;uState ;隐藏按钮
invoke SendMessage;hToolbar;TB_PRESSBUTTON;idButton;uState ;按下按钮
对于这些消息,如果uState指定为TRUE,那么按钮会分别被设置为选中、允许、隐藏和按下状态;如果uState指定为FALSE,按钮会被设置为非选中、灰化、显示和凸起的状态。
同样,要一次性设置所有状态,可以发送TB_SETSTATE消息:
invoke SendMessage;hToolbar;TB_PRESSBUTTON;idButton;uState
uState参数可以指定为TBSTATE_INDETERMINATE,TBSTATE_CHECKED,TBSTATE _ENABLED,TBSTATE_HIDDEN或TBSTATE_PRESSED等按钮状态的组合值。
9。3。3 工具栏的通知消息
大部分通用控件向父窗口发送的通知消息是WM_NOTIFY,为了便于和菜单消息使用同一段命令处理的逻辑代码,当按动工具栏按钮的时候,工具栏控件向父窗口发送的是WM_MAND消息,但其他情况下发送的通知消息仍然是WM_NOTIFY消息。
工具栏发送的WM_NOTIFY消息主要用于显示工具提示和定制工具栏。
1。 工具提示
当工具栏的风格包含TBSTYLE_TOOLTIPS的时候,CreateToolbarEx函数自动创建一个工具提示控件(Tool Tip),并为工具栏上的每个按钮注册提示文本,当鼠标指针移动到按钮上并停留片刻的时候,工具提示信息会自动显示出来。
工具提示信息是工具提示控件通过包含TTN_NEEDTEXT通知码的WM_NOTIFY消息向父窗口索取的,所以这个WM_NOTIFY消息严格地说应该属于工具提示控件的通知消息而不是工具栏的通知消息,但这里的工具提示控件是CreateToolbarEx函数自动创建的,所以还是一起介绍。
在包含TTN_NEEDTEXT通知码的WM_NOTIFY消息中,lParam指向一个TOOLTIPTEXT结构——慢着!前面不是说WM_NOTIFY消息的lParam参数指向一个NMHDR吗?怎么又是TOOLTIPTEXT结构呢?由于不同控件的通知消息都使用WM_NOTIFY消息,有些通知消息可能需要附带其他数据,这时仅使用一个NMHDR结构来表达是不够的,Windows的处理办法是为需要附带其他数据的WM_NOTIFY消息定义不同的数据结构,但这些结构头部都是一个NMHDR结构,NMHDR结构以后才是其他字段,这样在得知通知码之前,把lParam参数指针当做一个NMHDR结构来处理总是正确的。而且只有先把lParam参数指针当做NMHDR结构处理并从中获取通知码以后,才真正知道lParam指向的究竟是什么结构。
好了,问题解决了,言归正传。TTN_NEEDTEXT通知码的lParam指向一个TOOLTIPTEXT结构,这个结构的定义是:
TOOLTIPTEXT STRUCT
hdr NMHDR ;头部位置是一个NMHDR结构
lpszText DWORD ? ;工具提示字符串指针
szText BYTE 80 dup (?) ;工具提示字符串缓冲区
hInst DWORD ? ;包含字符串资源的模块句柄
uFlags DWORD ? ;标志
TOOLTIPTEXT ENDS
当需要显示工具提示信息的时候,工具提示控件向父窗口发送TTN_NEEDTEXT通知码,父窗口将需要显示的提示字符串放在TOOLTIPTEXT结构中并返回以后,工具提示控件就会把它显示出来。设置TOOLTIPTEXT结构的办法有3种,读者可以任选其一:
(1)字符串包含在资源中,这时可以将hInst字段设置为包含资源的模块句柄,并把lpszText字段设置为字符串ID,其他字段保持为NULL,工具提示会自己使用LoadString函数装入字符串。
(2)将字符串放在内存中,将内存指针放入lpszText字段中,其他字段保持NULL。
(3)将字符串拷入szText字段中,其他字段保持NULL。
例子程序使用了第一种办法。由于NMHDR结构的idFrom字段已经返回了按钮的命令ID,所以在资源脚本文件中将字符串的ID和命令ID一一对应定义,然后使用第一种方法是最方便的,代码如下:
。elseif eax WM_NOTIFY
mov ebx;lParam
。if 'ebx + NMHDRde' TTN_NEEDTEXT
assume ebx:ptr TOOLTIPTEXT
mov eax;'ebx'。hdr。idFrom
mov 'ebx'。lpszText;eax
push hInstance
pop 'ebx'。hinst
assume ebx:nothing
。。。
读者可以自己尝试一下其他的方法。
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第9章 通用控件
9。3 使用工具栏(6)
2。 定制工具栏
定制功能是工具栏中最令人兴奋的特征:当工具栏包含CCS_ADJUSTABLE风格的时候,用户可以通过按下Shift键并拖动工具栏上的按钮来移动按钮位置;如果将按钮拖出工具栏的边界,按钮会被删除;更重要的是,如果向工具栏发送TB_CUSTOMIZE消息或者在工具栏的空白处双击鼠标,会显示出一个如图9。7所示的“自定义工具栏”对话框,对话框右边的列表框中列出了当前显示在工具栏上的按钮,左边列表框列出了可以添加到工具栏上的按钮,用户可以将一个按钮随意在使用和不使用之间切换,并且可以通过拖动按钮的上下位置来决定按钮在工具栏上的位置。
工具栏通过一系列的通知信息来和父窗口交互,共同维护“自定义工具栏”对话框,在这个对话框建立和关闭的时候,工具栏通过TBN_BEGINADJUST和TBN_ENDADJUST通知码来通知父窗口;每次按钮被调整的时候,发送的是TBN_TOOLBARCHANGE通知码;在按下对话框中的“帮助”按钮和“重置”按钮的时候,发送的是TBN_CUSTHELP和TBN_RESET通知码,对于这些通知码,父窗口可以不必响应,这并不会影响对话框的使用。
与对话框是否能够正常运行有关的通知码是TBN_QUERYINSERT,TBN_QUERYD