• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

SendMessage函数巧应用(一)

发布: 2007-6-21 21:57 | 作者:   | 来源:   | 查看: 26次 | 进入软件测试论坛讨论

领测软件测试网

   
  SendMessage函数巧应用(一)
    在Windows编程中,向文本框控件、列表控件、按钮控件等是我们最常接触的控件了。但是在VB中这些控件有时
无法实现我们的需要。在这时,我们只要简单的利用Windows API函数就可以扩充这些控件的功能了。

    顾名思义,SendMessage函数就是向窗口(这里的窗口指的是向按钮、列表框、编辑框等具有hWnd属性的控件)
发送消息的函数,该函数的定义如下:
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
系统的很多消息中,有一些不仅仅是提供一个窗口消息那么简单。它们可以控制窗口的动作和属性。下面我将分次向
向大家介绍SendMessage函数在扩充基本控件功能方面的应用。

一、列表(ListBox)控件
    在Windows中,有一系列的以LB_开头的列表消息,这里介绍的就是利用LB消息控制的ListBox的应用
1、使列表中光标移动到不同的列表项上有不同的提示(ToolTip)
    在列表框控件中有一个ToolTipText属性,该属性决定了当光标在列表框上移动时出现的提示文字。但是如何使得
当光标在不同的列表项上移动时的提示文字也不同呢?问题的关键是要知道在光标移动时光标所在的列表项的索引,使
用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的代码窗口中。运行程序,当光标在
列表中移动时,可以看到根据光标所在的不同的列表项,提示文字也不相同。

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的代码窗口中。运行程序,可以
看到列表中出现了横向滚动条,而且滚动范围正好是列表项的长度。
    3、使列表可以响应用户击键
    有时我们需要列表根据用户的敲入字符串自动调整列表的ListIndex到最接近的列表项,就象VB中动态感应
用户输入控件属性的编辑器一样。问题的关键是如何在列表中查找含有指定字符串的列表项,使用LB_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的代码窗口中。并将List1的Sorted属性
设置为True。运行程序,在列表中敲入字符,例如“av” “gm”,列表就会高亮显示相近的列表项,双击列表就可以
清除原来的输入。

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网