按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
程序在初始化对话框的WM_INITDIALOG消息(如果建立的是窗口而不是对话框应该是WM_CREATE)中建立了一个状态栏和一个EDIT控件,并设置了一个定时器,用来在状态栏上显示时间。当窗口改变大小的时候,程序在WM_SIZE消息中重新安排状态栏和EDIT控件的位置。
另外,程序也处理状态栏发送的WM_NOTIFY通知消息,这是为了检测用户在第3栏上按下鼠标的动作,以便将文字在“插入”和“改写”之间切换,如果状态栏仅用于输出信息,那么就可以不处理WM_NOTIFY消息。
9。2。1 创建状态栏
创建状态栏可以使用CreateStatusWindow函数:
invoke CreateStatusWindow;style;lpszText;hwndParent;wID
mov hStatus;eax
style参数指明状态栏的风格,它可以是以下取值的组合:
● SBARS_SIZEGRIP——显示状态栏右下角的斜条,用户可以拖动这里来改变主窗口的大小。
● CCS_TOP,CCS_BOTTOM或CCS_NOMOVEY——代表状态栏的初始位置,分别表示位于主窗口上方、下方(默认值)和禁止沿Y方向移动。
● CCS_NOPARENTALIGN——状态栏只自动设置自己的高度,不自动设置自己的宽度,也不自动移动位置。
● CCS_NORESIZE——禁止状态栏所有的自动移动和自动设置自己大小的特性。并禁止CCS_TOP,CCS_BOTTOM,CCS_NOMOVEY和CCS_NOPARENTALIGN风格。
lpszText指向一个初始化的时候显示在状态栏上的字符串。hwndParent指明状态栏的父窗口。wID为状态栏控件的ID,这个ID值可以用来在WM_NOTIFY消息中判断消息是否来自于状态栏。
在例子程序中,用以下代码建立了一个自动缩放的状态栏,状态栏的ID值被定义为ID_STATUSBAR:
invoke CreateStatusWindow;WS_CHILD OR WS_VISIBLE OR
SBS_SIZEGRIP;NULL;hWinMain;ID_STATUSBAR
mov hWinStatus;eax
当然,使用CreateWindowEx函数也可以完成同样的功能,只不过多了很多没有必要指定的参数而已:
szClass db 'msctls_statusbar32';0
。。。
invoke CreateWindowEx;NULL;addr szClass;NULL;
WS_CHILD OR WS_VISIBLE OR SBS_SIZEGRIP;
0;0;0;0;hWnd;ID_STATUSBAR;hInstance;NULL
mov hWinStatus;eax
这几句语句的效果和使用CreateStatusWindow函数创建状态栏是一样的,语句中将位置和大小参数设置为0是因为状态栏有自动调整位置和大小的能力。
9。2。2 状态栏的控制消息
1。 将状态栏分栏
状态栏刚建立的时候只有1栏,为了在状态栏上显示不同种类的信息,有时候需要将状态栏划分成多个栏目,如图9。2中的状态栏就被划分成了4栏,我们使用了前面的3栏来显示信息。
可以通过向状态栏发送SB_SETPARTS消息来将它分栏:
dwStatusWidth dd 60;140;172;…1
。。。
invoke SendMessage;hWinStatus;SB_SETPARTS;4;offset wStatusWidth
其中SB_SETPARTS消息的wParam 参数4代表所分的栏目数量,lParam指向一个Y方向的坐标列表,坐标列表中的坐标数量和栏目数量相对应。如上面的代码将状态栏分为4栏,前面3栏分界点分别位于X方向的60、140和172处,最后一个坐标为?1,表示最后一栏占据了剩下的所有宽度。如果最后一个坐标指定的不是?1,比如说指定的是60,140,172,200,那么状态栏会是图9。3所示的样子——被分栏的地方是凹下的,剩余的地方则保持凸起的状态。
图9。3 状态栏的分栏
在程序中也可以获取分栏的状态,通过向状态栏发送SB_GETPARTS 消息就可以做到这一点:
dwStatusWidth dd 4 dup (?)
。。。
invoke SendMessage;hWinStatus;SB_GETPARTS;4;offset wStatusWidth
其中消息的wParam参数4代表用来接收分栏坐标的缓冲区的大小,lParam参数指向用来接收分栏坐标数据的缓冲区,SB_GETPARTS消息的返回值是状态栏的总栏目数。
2。 维护状态栏中的信息
通过向状态栏发送SB_SETTEXT消息可以将字符串显示到指定的状态栏分栏中:
invoke SendMessage;hWinStatus;SB_SETTEXT;iPart or uType;lpsz
消息的第一个参数指定分栏号和显示信息的方法,iPart表示分栏号,分栏编号从0开始,uType可以指定以下的方法:
● SBT_NOBORDERS——显示的文本不带边框(即分栏不显示为凹下的形状)。
● SBT_OWNERDRAW——分栏由用户自己绘画,当状态栏收到这样的消息后,会马上向父窗口发送WM_DRAWITEM 消息,并在WM_DRAWITEM 消息的lParam参数中指明一个DRAWITEMSTRUCT 结构,这个结构中包括需要绘画的分栏的hDC与坐标等参数,程序可以用任何GDI函数对这个hDC进行绘画,包括使用BitBlt函数将一幅位图画到状态栏分栏中。
● SBT_POPOUT——默认状态下,状态栏的分栏显示为凹下,指定SBT_POPOUT标志将使分栏以凸起的形状显示。
消息的第二个参数lParam中放置的lpsz指向需要显示的字符串。
程序也可以通过发送SB_GETTEXT消息来获取状态栏中某个分栏的文字:
invoke SendMessage;hWinStatus;SB_GETTEXT;iPart;lpsz
iPart参数指定需要获取的分栏编号,lpsz指向一个缓冲区,用来接收返回的字符串,消息的返回值是用SB_SETTEXT设置分栏文字时使用的uType,所以返回值可能是SBT_NOBORDERS或SBT_POPOUT等数值。
在发送SB_GETTEXT消息之前,也可以首先通过发送SB_GETTEXTLENGTH消息来获取分栏中字符串的长度:
invoke SendMessage;hWinStatus; SB_GETTEXTLENGTH;iPart;0
and eax;0ffffh
mov dwTextLength;eax
消息返回值的低16位是字符串的长度,高16位是用SB_SETTEXT设置分栏文字时使用的uType。
3。 移动和缩放状态栏
当状态栏的父窗口改变大小的时候,程序必须移动和缩放状态栏以保证它以正确的尺寸位于正确的位置上。虽然以默认风格建立的状态栏是可以自动缩放和移动位置的,但这并不代表父窗口不用通知它,实际上,“自动缩放和移动位置”的含义是父窗口通知状态栏需要移动和缩放的时候,并不需要将正确的位置和大小告诉状态栏,新的位置和大小是由状态栏自己计算的。
所以,例子程序中当父窗口收到WM_SIZE消息的时候,用下面的代码来移动和缩放状态栏:
invoke MoveWindow;hWinStatus;0;0;0;0;TRUE
我们看到,代码中并不需要指定有效的位置和尺寸。
如果创建状态栏的时候指定了CCS_NOPARENTALIGN或CCS_NORESIZE风格的话,那么在使用MoveWindow函数移动状态栏位置的时候就必须首先计算出正确的位置和大小。
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第9章 通用控件
9。2 使用状态栏(4)
9。2。3 在状态栏上显示菜单提示信息
本节演示当用户浏览菜单项的时候如何在状态栏上面显示菜单提示信息。每当用户将鼠标移过一个菜单项的时候,Windows会向窗口过程发送一条WM_MENUSELECT消息,当用户真正选择了菜单项的时候,Windows才会发送WM_MAND消息,为了显示菜单项提示信息,必须响应WM_MENUSELECT消息并根据浏览的菜单项显示对应的提示信息。
如果由我们自己实现这个功能,那么可以用4个步骤完成:首先是响应WM_MENUSELECT消息并从消息参数中获取用户浏览的菜单项ID;第2步是根据菜单项ID获取对应的提示信息字符串;第3步是将状态栏的分栏取消以便用整个状态栏显示提示信息;第4步是在状态栏上显示字符串。
但在现实中不必这样做,在状态栏上面显示菜单提示信息的应用是这样的广泛,以至于系统为此设置了一个专用的函数MenuHelp:
invoke MenuHelp;uMsg;wParam;lParam;hMenu;hInstance;hwndStatus;lpwIDs
这个函数是和WM_MENUSELECT消息配合使用的,输入参数中的uMsg,wParam和lParam可以取自WM_MENUSELECT消息的对应参数,hMenu是用户当前浏览的菜单句柄,由于WM_MENUSELECT消息的lParam参数传递过来的就是菜单句柄,所以函数的hMenu参数也可以直接使用lParam。hwndStatus参数指定了状态栏窗口的句柄。
hInstance和lpwIDs配合指定了需要显示的提示信息字符串,MenuHelp函数使用的字符串必须放在资源文件的字符串表中,函数会自动使用LoadString装入正确的字符串,参数hInstance指定了包含字符串资源的模块的实例句柄。lpwIDs指向一个包含4个双字的数组,用来指定函数装入的字符串的ID值基数,第一个双字指定命令菜单项的基数,第二个双字指定弹出式菜单的基数。基数加上用户当前浏览的菜单项ID得到的数值就是MenuHelp函数要装入的字符串ID。
举例说明,例子程序中调用MenuHelp函数如下:
dwMenuHelp dd 0;IDM_MENUHELP;0;0
。。。
。elseif eax WM_MENUSELECT
invoke MenuHelp;WM_MENUSELECT;wParam;lParam;lParam;hInstance;
hWinStatus;offset dwMenuHelp
资源脚本文件中的字符串表定义如下:
stringtable discardable
BEGIN
IDM_M