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消息控制的ListBox的应用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 iFor i = 1 To 200List1.AddItem Str(i) + " Samples in this list is " + Str(i)Next iEnd Sub Private Sub List1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)Dim lXPoint As LongDim lYPoint As LongDim 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 IfEnd WithEnd IfEnd Sub首先在Form1中加入一个ListBox控件,然后再将上面的代码加入到Form1的代码窗口中?br />T诵谐绦颍惫獗暝?列表中移动时,可以看到根据光标所在的不同的列表项,提示文字也不相同。 2、向列表中加入横向滚动条使得可以浏览长列表项当向列表中加入的列表项超出了列表的显示范围后,列表并不会出现横向滚动条让你可以通过滚动来浏览项目 的全部内容。利用LB_SETHORIZONTALEXTENT消息可以设置列表的横向滚动条以及滚动长度。下面是范例程序:Option Explicit Private Type RECTLeft As LongTop As LongRight As LongBottom As LongEnd TypePrivate 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 = &H194Const DT_CALCRECT = &H400 Public Function ListTextWidth(ByRef lstThis As ListBox) As LongDim i As LongDim tR As RECTDim lW As LongDim lWidth As LongDim lHDC As Long With lstThis.Parent.Font.Name = lstThis.Font.Name.Size = lstThis.Font.Size .Bold = lstThis.Font.Bold .Italic = lstThis.Font.ItalicEnd WithlHDC = lstThis.Parent.hdc'便历所有的列表项以找到最长的项For i = 0 To lstThis.ListCount - 1DrawText lHDC, lstThis.List(i), -1, tR, DT_CALCRECTlW = tR.Right - tR.Left + 8If (lW > lWidth) ThenlWidth = lWEnd IfNext i'返回最长列表项的长度(像素)ListTextWidth = lWidthEnd Function Private Sub Form_Load()Dim astr As StringDim iDim l As Longl = List1.FontSize * 20 / Screen.TwipsPerPixelXFor i = 1 To 10astr = astr + "我们This is a very long item " + Str(i)Next iList1.AddItem astr + "aaa"'加入一个很厂的列表项l = ListTextWidth(List1)SendMessage List1.hwnd, LB_SETHORIZONTALEXTENT, l, 0End 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 = &H18FDim astr As String Private Sub Form_KeyPress(KeyAscii As Integer)Dim l As Longastr = astr + Chr(KeyAscii)l = SendMessageStr(List1.hwnd, LB_FINDSTRING, -1, astr)If l ThenList1.ListIndex = lEnd IfEnd Sub Private Sub Form_Load()'向List中加入列表项For i = 65 To 85For j = 65 To 85List1.AddItem Chr(i) + Chr(j)Next jNext iEnd Sub Private Sub List1_DblClick()'清除原来的查找字符串astr = ""End Sub Private Sub List1_KeyPress(KeyAscii As Integer)'如果按下的是字母键就将击键消息传递到Form1If ((KeyAscii >= 65 And KeyAscii <= 90) Or (KeyAscii >= 97 _Or KeyAscii <= 122)) ThenKeyAscii = 0End IfEnd Sub首先在Form1中加入一个ListBox控件,然后再将上面的代码加入到Form1的代码窗口中?br />2⒔獿ist1的Sorted属性设置为True。运行程序,在列表中敲入字符,例如"av" "gm",列表就会高亮显示相近的列表项,双击列表就可以清除原来的输入。

评论