回 帖 发 新 帖 刷新版面

主题:刚刚找到一段代码,用SendMessage得到ListBox类里面的内容

在vb里面如何得到外部程序的ListBox内容

以下代码掩饰在得知两个ListBox句柄时,把其中一个里面的内容复制到另外一个里面

DuplicateListBox参数解释:
SourceHwnd=源ListBox句柄(HWnd)
TargetHwnd=目标ListBox句柄(HWnd)
AppendMode=是否对源ListBox的Content进行校验,True就可以了

========================================================================
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 Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) _
    As Long
   
Const LB_RESETCONTENT = &H184
Const LB_GETCOUNT = &H18B
Const LB_GETTEXT = &H189
Const LB_ADDSTRING = &H180
Const LB_GETITEMDATA = &H199
Const LB_SETITEMDATA = &H19A


Sub DuplicateListBox(SourceHwnd As Long, TargetHwnd As Long, _
    Optional AppendMode As Boolean)
    Dim index As Long
    Dim itmData As Long
    Dim numItems As Long
    Dim sItemText As String
    
    ' prepare the receiving buffer
    sItemText = Space$(512)
    
    ' temporarily prevent updating
    LockWindowUpdate TargetHwnd
    
    ' reset target contents, if not in append mode
    If Not AppendMode Then
        SendMessage TargetHwnd, LB_RESETCONTENT, 0, ByVal 0&
    End If

    ' get the number of items in the source list
    numItems = SendMessage(SourceHwnd, LB_GETCOUNT, 0&, ByVal 0&)
    
    For index = 0 To numItems - 1
        ' get the item text
        SendMessage SourceHwnd, LB_GETTEXT, index, ByVal sItemText
        ' get the item data
        itmData = SendMessage(SourceHwnd, LB_GETITEMDATA, index, ByVal 0&)
        ' add the item text to the target list
        SendMessage TargetHwnd, LB_ADDSTRING, 0&, ByVal sItemText
        ' add the item data to the target list
        SendMessage TargetHwnd, LB_SETITEMDATA, index, ByVal itmData
    Next
    
    ' allow redrawing
    LockWindowUpdate 0
    
End Sub

Private Sub Form_Load()
DuplicateListBox List2.hWnd, List1.hWnd, True
End Sub

===========================================================================

回复列表 (共9个回复)

沙发

看见你这么熟悉API问你一个问题
你知不知道如何在vb里实现 “屏幕取词”?

板凳

都是API

3 楼

看不懂诶!

4 楼

找到一段鼠标取词的代码,运行了下,还行.
在Form1上添加Text1,设为多行模式,输入一些文本.

这段代码演示的是用鼠标在TextBox里面取词,至于其它的控件就不知道了
不过我分析了下,这代码的核心就是得到鼠标所在的那一整行文本
在通过鼠标位置得到鼠标下面的单个字符
以这个字符为起点,分别向前向后,查找空格,标点,换行等一般用于分割单词的字符以确定最终结果

也就是说,其它控件只要能找到鼠标所在的行,和鼠标的位置,应该也可以用此方法
=======================================================================
Option Explicit
Private Const EM_CHARFROMPOS = &HD7
Private Const EM_GETLINECOUNT = &HBA
Private Const EM_GETLINE = &HC4
Private Const EM_LINEINDEX = &HBB
Private Const EM_LINELENGTH = &HC1
Private Const EM_SETSEL = &HB1

Private Declare Sub RtlMoveMemory Lib "KERNEL32" (lpvDest As Any, lpvSource As Any, ByVal cbCopy 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

Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim pos As Long, lc As Long
    Dim Line As Integer, CharPos As Integer
    
    pos = X / Screen.TwipsPerPixelX + Y / Screen.TwipsPerPixelY * 65536
    lc = SendMessage(Text1.hwnd, EM_CHARFROMPOS, 0, ByVal pos)
    
    Line = lc \ 65536
    CharPos = lc Mod 65536
    
    MsgBox " = " & GetLine(Text1, Line) & vbCrLf & "单词= " & GetWord(Text1, CharPos)
End Sub

Function GetWord(txt As TextBox, pos As Integer) As String
    Dim bArr() As Byte, pos1 As Integer, pos2 As Integer, i As Integer
    
    bArr = StrConv(txt.Text, vbFromUnicode)
    pos1 = 0: pos2 = UBound(bArr)
    
    For i = pos - 1 To 0 Step -1
        If IsDelimiter(bArr(i)) Then
            pos1 = i + 1
            Exit For
        End If
    Next
    
    For i = pos To UBound(bArr)
        If IsDelimiter(bArr(i)) Then
            pos2 = i - 1
            Exit For
        End If
    Next
    
    If pos2 > pos1 Then
        ReDim bArr2(pos2 - pos1) As Byte
        For i = pos1 To pos2
            bArr2(i - pos1) = bArr(i)
        Next
    
        GetWord = StrConv(bArr2, vbUnicode)
        

        SendMessage txt.hwnd, EM_SETSEL, pos1, ByVal CLng(pos2 + 1)
    Else
        GetWord = ""
    End If
End Function

Function IsDelimiter(ByVal Char As Byte) As Boolean
    Dim S As String
    
    S = Chr(Char)
    IsDelimiter = False
    If S = " " Or S = "," Or S = "." Or S = "?" Or S = vbCr Or S = vbLf Then
        IsDelimiter = True
    End If
End Function

Function GetLine(txt As TextBox, ByVal Line As Integer) As String
    Dim S As String, Length As Integer, pos As Long
    
    GetLine = ""
    pos = SendMessage(txt.hwnd, EM_LINEINDEX, Line, ByVal 0&)
    Length = SendMessage(txt.hwnd, EM_LINELENGTH, pos, ByVal 0&)
    S = String(Length, Chr(0))
    RtlMoveMemory ByVal S, Length, 2
    If SendMessage(Text1.hwnd, EM_GETLINE, Line, ByVal S) > 0 Then
        GetLine = S
    End If
End Function

Private Sub Text1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim pos As Long, lc As Long
    Dim Line As Integer, CharPos As Integer
    
    pos = X / Screen.TwipsPerPixelX + Y / Screen.TwipsPerPixelY * 65536
    lc = SendMessage(Text1.hwnd, EM_CHARFROMPOS, 0, ByVal pos)
    
    Line = lc \ 65536
    CharPos = lc Mod 65536
    
    Text1.ToolTipText = GetWord(Text1, CharPos)
End Sub
======================================================================

5 楼

[size=6]收藏[/size]

6 楼

不懂不要紧~~能用就成~~

7 楼

这个例子,我都不知道看到多少遍了
我要的是 金山词霸 那样的 完全的
  我已经看过 C++ 和 DEIPHI的例子了 ,但我不懂 所以 才想找着一个vb的

8 楼

麻烦把C++的帖出来看看~

9 楼

我就是不大看懂API,API到底怎么学吗

我来回复

您尚未登录,请登录后再回复。点此登录或注册