正文

SendMessage函数应用(一)2005-09-27 13:26:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/iamben250/5408.html

分享到:






SendMessage函数应用(一)

在Windows编程中,向文本框控件、列表控件、按钮控件等是我们最常接触的控件了。?br />窃赩B中这些控件有时无法实现我们的需要。在这时,我们只要简单的利用Windows API函数就可以扩充这些控件的功能了。
顾名思义,SendMessage函数就是向窗口(这里的窗口指的是向按钮、列表框、编辑框?br />染哂衕Wnd属性的控件)发送消息的函数,该函数的定义如下:
Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long

其中hwnd指定接受消息的窗口,参数wMsg指定消息值,参数wParam lParam分别定义传递到窗口的附加参数。而在Windows系统的很多消息中,有一些不仅仅是?br /> 峁┮桓龃翱谙⒛敲醇虻ァK强梢钥刂拼翱诘亩骱褪粜浴O旅嫖医执蜗蛳虼蠹医樯躍
endMessage函数在扩充基本控件功能方面的应用。


一、列表(ListBox)控件
在Windows中,有一系列的以LB_开头的列表消息,这里介绍的就是利用LB消息控制的ListBo
x的应用
1、使列表中光标移动到不同的列表项上有不同的提示(ToolTip)
在列表框控件中有一个ToolTipText属性,该属性决定了当光标在列表框上移动时出现的提?br />疚淖帧5侨绾问沟? 当光标在不同的列表项上移动时的提示文字也不同呢?问题的关键是要知道在光标移动时光
标所在的列表项的索引,使 用SendMessage函数发送LB_ITEMFROMPOINT消息就可以获得。下面是程序范例:


Option Explicit


Const LB_ITEMFROMPOINT = &H1A9


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


Private Sub Form_Load()
Dim i

For i = 1 To 200
List1.AddItem Str(i) + " Samples in this list is " + Str(i)
Next i
End Sub


Private Sub List1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim lXPoint As Long
Dim lYPoint As Long
Dim 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))
'将ListBox的Tooltip设置为该标题行的文本
If (lIndex >= 0) And (lIndex <= .ListCount) Then
.ToolTipText = .List(lIndex) 'Return the text = .list(lIndex)
Else
.ToolTipText = ""
End If
End With
End If
End Sub

首先在Form1中加入一个ListBox控件,然后再将上面的代码加入到Form1的代码窗口中?br />T诵谐绦颍惫獗暝?列表中移动时,可以看到根据光标所在的不同的列表项,提示文字也不相同。


2、向列表中加入横向滚动条使得可以浏览长列表项
当向列表中加入的列表项超出了列表的显示范围后,列表并不会出现横向滚动条让你可
以通过滚动来浏览项目 的全部内容。利用LB_SETHORIZONTALEXTENT消息可以设置列表的横向滚动条以及滚动长度。
下面是范例程序:
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
End If
Next i

'返回最长列表项的长度(像素)
ListTextWidth = lWidth
End Function


Private Sub Form_Load()
Dim astr As String
Dim i
Dim l As Long

l = List1.FontSize * 20 / Screen.TwipsPerPixelX
For i = 1 To 10
astr = astr + "我们This is a very long item " + Str(i)
Next i
List1.AddItem astr + "aaa"
'加入一个很厂的列表项
l = ListTextWidth(List1)

SendMessage List1.hwnd, LB_SETHORIZONTALEXTENT, l, 0
End Sub

首先在Form1中加入一个ListBox控件,然后再将上面的代码加入到Form1的代码窗口中?br />T诵谐绦颍梢钥吹搅斜碇谐鱿至撕嵯蚬龆酰夜龆段д檬橇斜硐畹某ざ取?br>
3、使列表可以响应用户击键
有时我们需要列表根据用户的敲入字符串自动调整列表的ListIndex到最接近的列表项?br /> 拖骎B中动态感应用户输入控件属性的编辑器一样。问题的关键是如何在列表中查找含有?br /> 付ㄗ址牧斜硐睿褂肔B_FINDSTRING消息可以在列表中查找指定字符串。下面是范例:



Private Declare Function SendMessageStr Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As String) As Long


Const LB_FINDSTRING = &H18F
Dim astr As String


Private Sub Form_KeyPress(KeyAscii As Integer)
Dim l As Long

astr = astr + Chr(KeyAscii)

l = SendMessageStr(List1.hwnd, LB_FINDSTRING, -1, astr)

If l Then
List1.ListIndex = l
End If
End Sub


Private Sub Form_Load()
'向List中加入列表项
For i = 65 To 85
For j = 65 To 85
List1.AddItem Chr(i) + Chr(j)
Next j
Next i
End Sub


Private Sub List1_DblClick()
'清除原来的查找字符串
astr = ""
End Sub


Private Sub List1_KeyPress(KeyAscii As Integer)
'如果按下的是字母键就将击键消息传递到Form1
If ((KeyAscii >= 65 And KeyAscii <= 90) Or (KeyAscii >= 97 _
Or KeyAscii <= 122)) Then
KeyAscii = 0
End If
End Sub

首先在Form1中加入一个ListBox控件,然后再将上面的代码加入到Form1的代码窗口中?br />2⒔獿ist1的Sorted属性设置为True。运行程序,在列表中敲入字符,例如"av" "gm",列表就会高亮显示相近的列表项,双击列表就可以清除原来的输入。

阅读(2775) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册