WIN32汇编语言教程:第05章 使用资源 · 5.4 对话框(8)
和其他子窗口控件发送WM_COMMAND消息不同,水平滚动条向对话框窗口发送WM_HSCROLL消息,而垂直滚动条则发送WM_VSCROLL消息,所以针对两种方式的滚动条要分别处理不同的消息。
WM_xSCROLL消息的参数如下所示:
wParam的低16位 = nScrollCode ;动作码
wParam的高16位 = nPos ;滚动条当前位置
lParam = hwndScrollBar ;滚动条控件的窗口句柄
其中nScrollCode代表了滚动条的当前动作,定义值及其含义如下:
● SB_BOTTOM 滚动条移到了最下/右边。
● SB_ENDSCROLL 用户停止了滚动动作。
● SB_THUMBPOSITION 滚动条被拖动到某处。
● SB_THUMBTRACK 滚动条在拖动中。
● SB_TOP 滚动条移到了最上/左边。
● SB_LINELEFT 滚动条左移了一格(对于水平滚动条)。
● SB_LINERIGHT 滚动条右移了一格(对于水平滚动条)。
● SB_PAGELEFT 滚动条左移了一页(对于水平滚动条)。
● SB_PAGERIGHT 滚动条右移了一页(对于水平滚动条)。
● SB_LINEDOWN 滚动条下移了一格(对于垂直滚动条)。
● SB_LINEUP 滚动条上移了一格(对于垂直滚动条)。
● SB_PAGEDOWN 滚动条下移了一页(对于垂直滚动条)。
● SB_PAGEUP 滚动条上移了一页(对于垂直滚动条)。
nPos的值只有当动作码是SB_THUMBPOSITION或SB_THUMBTRACK时才有效,其他的时候为0,图5.7示出了鼠标点击滚动条各处时对应的nScrollCode。
第一眼看到SB_xxx动作码的时候,读者可能会以为水平滚动条和垂直滚动条的动作码是不相同的——水平滚动条是SB_xxxLEFT、SB_xxxRIGHT,而垂直滚动条是SB_xxxUP、SB_xxxDOWN,但在Windows.inc中查看一下就可以发现,SB_xxxLEFT和SB_xxxUP在数值上是相同的,SB_xxxRIGHT和SB_xxxDOWN也是如此,所以不同定义方法只是为了直观起见而已。
图5.7 鼠标单击滚动条各处时产生的nScrollCode
以水平滚动条为例,处理滚动条消息的代码一般是如下结构:
.elseif eax == WM_HSCROLL ;窗口的消息处理分支,eax为wMsg mov eax, lParam .if eax == hWnd滚动条1 mov eax,wParam .if ax == SB_LINELEFT dec 位置变量 .elseif ax == SB_LINERIGHT inc 位置变量 .elseif ax == SB_PAGELEFT sub 位置变量,页长 .elseif ax == SB_PAGERIGHT add 位置变量,页长 .elseif ax == SB_THUMBPOSITION || ax == SB_THUMBTRACK mov eax,wParam shr eax,16 mov 位置变量,eax .endif .elseif eax == hWnd滚动条2 ;处理滚动条2的代码,同上面的结构 ... .endif
在例子程序Control.asm中只定义了一个滚动条,所有的消息肯定都是它发出的,所以去掉了判断lParam是哪个滚动条的步骤直接处理wParam中的动作码。
在用户按动滚动条后,滚动条不会自己移动位置,它只是将用户的动作以WM_xSCROLL消息的形式反馈给程序,真正要移动它还是要靠程序来设置,所以代码中要根据不同的动作首先计算新的位置,并判断新的位置是否越界,例子程序中的这些代码判断新的位置是否超出0~100的范围,如果是,则校正到0~100之间:
cmp dwPos,0 jge @F mov dwPos,0 @@: cmp dwPos,100 jle @F mov dwPos,100
在介绍MASM语句的时候提到过,.if dwPos > 0语句只可以用来比较无符号数,所以在这里使用cmp指令自己构建测试分支而不是使用 .if伪指令。
当计算好新位置的时候要将位置设置回去,用户才会看到滚动条移动了,方法是向滚动条发送SBM_SETPOS消息:
invoke SendDlgItemMessage,hWnd,IDC_SCROLL,SBM_SETPOS,dwPos,TRUE
最后一个参数为TRUE表示设置后重新绘画滚动条。
在初始化的时候,要给滚动条发送SBM_SETRANGE消息来设定滚动范围:
invoke SendDlgItemMessage,hWnd,IDC_SCROLL,SBM_SETRANGE,最小值,最大值
如果需要获取滚动条的信息,可以尝试发送下面两个消息:SBM_GETPOS可以获取滚动条的当前位置,也就是上一次用SBM_SETPOS设置的值;SBM_GETRANGE可以获取滚动的范围,也就是用SBM_SETRANGE设置的值。
7. 使用组合框
顾名思义,组合框是一个“组合”起来的东西,它由一个可供选择的列表和一个可供输入的edit类组合而成。组合框让用户既可以自己输入文本,也可以选择列表中的某一项当做输入。用不同的风格定义可以产生3种类型的组合框,如图5.8所示。左边的是CBS_SIMPLE风格的组合框,它的上面可以输入文本,下面的列表可供选择预设文本;中间的是CBS_DROPDOWN风格的组合框,上面同样可以输入文本,但下面的列表是下拉式的,平时处于收起状态,点击编辑框右边的三角形才会拉下来;右边的是CBS_DROPDOWNLIST风格的组合框,它仅是一个下拉的选择框,上面的框中不允许输入文字。
图5.8 组合框的3种风格
组合框中还有几种常用的、可以附加的风格:
● CBS_AUTOHSCROLL 输入过长的文本时输入框自动卷动。
● CBS_LOWERCASE 自动将所有的文本转换成小写。
● CBS_SORT 自动将插入的文本项排序。
● CBS_UPPERCASE 自动将所有的文本转换成大写。
组合框中列表框部分的文字添加、项目的选择等操作都是通过发送消息来完成的,主要的消息如表5.5所示。