[转]SendMessage函数的常用消息及其应用2
时 间:2008-12-02 08:10:07
作 者:andymark ID:1350 城市:深圳
摘 要:SendMessage函数的常用消息及其应用
正 文:
SendMessage函数应用(一)
在Windows系统的很多消息中,有一些不仅仅是提供一个窗口消息那么简单。它们可以控制窗口的
动作和属性。下面向大家介绍SendMessage函数在扩充列表(ListBox)控件功能方面的应用。
在 Windows 中,有一系列的以 LB_ 开头的列表消息,这里介绍的就是利用LB消息控制的ListBox
的应用。
1、使列表中光标移动到不同的列表项上有不同的提示(ToolTip)
在列表框控件中有一个 ToolTipText 属性,该属性决定了当光标在列表框上移动时出现的提示文
字。但是如何使得当光标在不同的列表项上移动时的提示文字也不同呢?问题的关键是要知道在光标移
动时光标所在的列表项的索引,使用SendMessage函数发送 LB_ITEMFROMPOINT 消息就可以获得。
在 Form1 中加入一个 ListBox 控件,运行程序,当光标在列表中移动时,可以看到根据光标所在
的不同的列表项,提示文字也不相同。代码如下(我已试验成功):
Const LB_ITEMFROMPOINT = &H1A9
Private Sub Form_Load()
Dim ZXS As Long
Drive1.Drive = "G:": Dir1.Path = "G:\一江秋水的文档"
Combo1.Text = Combo1.List(0)
ZXS = SendMessage(Text1.hwnd, 186, 0, 0)
Label1.Caption = "共 " & ZXS & " 行," & Len(Text1.Text) & " 字"
For i = 1 To 200: List1.AddItem Str(i) + " 列表框试验项目": Next
End Sub
Private Sub List1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim lXPoint As Long, lYPoint As Long, lIndex As Long
If Button = 0 Then '确定在移动鼠标的同时没有按下功能键或者鼠标键
lXPoint = CLng(X / Screen.TwipsPerPixelX) '获得光标的位置,以像素为单位
lYPoint = CLng(Y / Screen.TwipsPerPixelY)
With List1
lIndex = SendMessage(.hwnd, LB_ITEMFROMPOINT, 0, ByVal ((lYPoint * 65536) + lXPoint)) '获得光标所在的标题行的索引
If lIndex < .ListCount Then .ToolTipText = .List(lIndex) Else .ToolTipText = ""
End With
End If
End Sub
2、向列表中加入横向滚动条使得可以浏览长列表项
当向列表中加入的列表项超出了列表的显示范围后,列表并不会出现横向滚动条让你可以通过滚动来浏览
项目的全部内容。利用 LB_SETHORIZONTALEXTENT 消息可以设置列表框的横向滚动条以及滚动长度。
在 Form1 中加入一个 ListBox 控件,运行程序,可以看到列表中出现了横向滚动条,而且滚动范围正好
是列表项的长度。代码如下(我已试验成功):
Option Explicit
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hdc As Long, _
ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Const LB_SETHORIZONTALEXTENT = &H194
Const DT_CALCRECT = &H400
Public Function ListTextWidth(ByRef lstThis As ListBox) As Long '获取最长项目的象素长度值
Dim i As Long
Dim tR As RECT
Dim lW As Long
Dim lWidth As Long
Dim lHDC As Long
With lstThis.Parent.Font
.Name = lstThis.Font.Name
.Size = lstThis.Font.Size
.Bold = lstThis.Font.Bold
.Italic = lstThis.Font.Italic
End With
lHDC = lstThis.Parent.hdc
For i = 0 To lstThis.ListCount - 1 '遍历所有的列表项以找到最长的项
DrawText lHDC, lstThis.List(i), -1, tR, DT_CALCRECT
lW = tR.Right - tR.Left + 8
If lW > lWidth Then lWidth = lW
Next
ListTextWidth = lWidth '返回最长列表项的长度(像素)
End Function
Private Sub Form_Load()
Dim astr As String
Dim i
Dim l As Long
For i = 1 To 10: astr = Str(i) + "这是真正的长项目" + astr: List1.AddItem astr: Next '加入一个很大的列表项
L = ListTextWidth(List1)
SendMessage List1.hwnd, LB_SETHORIZONTALEXTENT, L, 0
End Sub
3、使列表框可以响应用户击键
有时我们需要列表根据用户的敲入字符串自动调整列表的ListIndex到最接近的列表项,就象VB中动态
响应用户输入控件属性的编辑器一样。问题的关键是如何在列表中查找含有指定字符串的列表项,使用
LB_FINDSTRING消息可以在列表中查找指定字符串。
在 Form1 中加入一个 TextBox 控件和一个 ListBox 控件,并将 List1的 Sorted 属性设置为True。
运行程序,在文本框中敲入字符,例如"av" "gm",列表就会高亮显示相近的列表项。代码如下(已成功):
Const LB_FINDSTRING = &H18F
Dim st As String
Private Sub Form_Load()
For i = 65 To 90: For j = 65 To 90: List1.AddItem Chr(i) + Chr(j): Next: Next '向List中加入列表项
End Sub
Private Sub Text1_KeyPress(KeyAscii As Integer)
If Len(st) > 1 Then st = ""
If ((KeyAscii > 64 And KeyAscii < 91) Or (KeyAscii > 96 Or KeyAscii < 123)) Then
Dim L As Long
st = st + Chr(KeyAscii)
L = SendMessage(List1.hwnd, LB_FINDSTRING, -1, ByVal st)'注意!当参数4传入的是字符串时,必须用ByVal传递
If L Then List1.ListIndex = L
End If
End Sub
4.在列表框中查找匹配的项目
在Win95风格的帮助系统中一般都有一个“索引”页,索引页含有一个文本框和一个列表框,当用户
在文本框中输入文字时,下拉列表会动态地显示与文本框中文字最匹配的项目,为用户提供了最大的方
便。这种效果在应用程序的帮助系统中很容易实现(只要按照 Win95帮助系统的正常制作过程制作就可
以实现),如果想在应用程序的其它地方实现这种特性就需费一番心思了。
而使用SendMessage函数实现上述特性则非常简单,甚至只需一条语句就足够了,那就是在文本框的
Change事件中给列表框发一条LB_FINDSTRING(&H18F)消息,该消息告诉列表框在列表中查找匹配的项
目。
在发LB_FINDSTRING消息时,wParam参数代表从列表框的哪一个项目后面开始查找,一般情况下该参
数可定为-1,表示从List1(0)即第一项开始向后循环查找,lParam则传进欲搜索的字符串(必须采用值
传递)。
具体的代码和运行画面与下面的 5. 合并在一起演示。
Access软件网QQ交流群 (群号:54525238) Access源码网店
常见问答:
技术分类:
源码示例
- 【源码QQ群号19834647...(12.17)
- Access对子窗体数据进行批...(10.30)
- 最精简的组合框行来源数据快速输...(10.25)
- Access仿平台的多值选择器...(10.24)
- 【Access日期区间段查询】...(10.22)
- 【Access源码示例】VBA...(10.12)
- Access累乘示例,Acce...(10.09)
- 数值8.88,把整数8去掉,转...(10.08)
- 【Access自定义函数】一个...(09.30)
- 【Access选项卡示例】Ac...(09.09)
学习心得
最新文章
- Access快速开发平台--对上传...(11.22)
- Access快速开发平台企业版--...(11.18)
- 不会用多表联合查询,多表查询没结果...(11.16)
- 【案例分享】主键字段值含有不间断空...(11.16)
- Access快速开发平台--后台D...(11.14)
- 微软Access邀测新Monaco...(11.12)
- Access列表框左右互选、列表框...(11.11)
- 高效率在导入数据前删除记录(11.10)
- Access报价单转订单示例代码(11.08)
- Access系统自带的日期选择器不...(11.08)