想制作一个类似于VB编辑器中智能提示这样的功能,也想做成控件,用ListBox或ListView模拟,但问题也相当多,如到了屏幕底部,要向上拉出,点击窗体空白区域后要消失(然而点击窗体空白区域后并不激发ListBox的LostFocus事件)
哪位有这方面的经验,能否指点一下。另外,有没有现成的示例?

解决方案 »

  1.   

    多行的TOOLTIPTEXT 可以参考 http://www.vbforums.com/attachment.php?attachmentid=19082
      

  2.   

    我不是要用ToolTip,是想一个下拉列表框,像VB编辑中的智能提示。
      

  3.   

    。这个似乎见过人家实现了。。是一个 VC的插件,安上以后让VC象VB一样能够自动提示。。我想这个问题想解决只需要一个API就可以了。。也许是吧。我去写写,似乎很清晰一会给代码。
      

  4.   

    饿
    测试代码需要2个FRM,名称默认,FORM1中添加一个TEXTBOX,名称默认,FORM2中添加一个LISTBOX,名称默认,将FORM2设置为无边框
    '以下代码在FORM1中
    '**************************************************************
    Option Explicit
    '1、在TEXT的CHANGE事件中判断刚输入的字符是不是“.”,如果是,获取插入符位置
    '2、在插入符相应位置弹出窗体(无边框,只有一个LIST控件,并把焦点移动到LIST)
    '3、在LIST控件的KEYDOWN事件中,识别依次按下了哪些字符,并寻找批配行,设置LIST控件的LISTINDEX属性,
    '4、当LIST控件的KEYDOWN事件中接收字符为空格时,将LIST控件当前行字符覆盖到最后一个“.”以后(这里有一个细节,就是如果不符合就不覆盖而是直接插入)
    Private Declare Function GetCaretPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
    Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
    Private Type POINTAPI
            x As Long
            y As Long
    End TypePrivate Sub Form_Load()
    '初始化弹出窗体和列表框内容
    Form2.BorderStyle = 0
    '一般来说,这里就是你要提示输入的字符,可以放在一个TXT文件或资源文件中,当判断“.”前面的内容后,就可以确定这里的内容了(具体方法见Text1_Change的注释)
    Form2!List1.AddItem "aaaaa"
    Form2!List1.AddItem "abc"
    Form2!List1.AddItem "A1234"
    Form2!List1.AddItem "Azx"
    Form2!List1.AddItem "bbb"
    Form2!List1.AddItem "cbbb"
    Form2!List1.AddItem "dbbb"
    Form2!List1.AddItem "Eaaaa"
    Form2!List1.AddItem "Fbbbbb"
    Form2!List1.AddItem "fBBBB"
    End SubPrivate Sub Text1_Change()
    Dim mPOINTAPI As POINTAPI, mx As Long, my As Long
    If Right(Text1.Text, 1) = "." Then
    '在这里就可以确定"."前面是什么字符串了,确定当前这个"."前面的第一个空格或者".",这两个位置之间的字符如果匹配你可以用的"提示头"那么就弹出
    '下面这部分代码被注释掉了,因为只是思路,没具体写,可能在IF语句那里位置有错误,你自己测试一下改改,思路就是这样了
    'Dim p1 As Long,dim p2 as long,dim mp as long
    'p1 = InStrRev(Left(Text1.Text, Len(Text1.Text) - 1), ".") '获取"."出现位置
    'p2 = InStrRev(Left(Text1.Text, Len(Text1.Text) - 1), " ") '获取空格出现位置
    '比较之,取大的一个
    'If p1 > p2 Then mp = p1 Else mp = p2
    'If Mid(Text1.Text, mp, Len(Text1.Text) - mp - 1) = "我要判断的某个字符串" Then
    '初始化对应提示的代码
    '*****************************************************************************
    '获得插入符位置
    GetCaretPos mPOINTAPI
    '位置似乎有点问题,你再看看再改改
    MoveWindow Form2.hwnd, mPOINTAPI.x + Form1.Left \ 14 + Text1.Left, mPOINTAPI.y + Form1.Top \ 14 + Text1.Top + 14, Form2!List1.Width \ 14, Form2!List1.Height \ 14, True
    '将窗体弹出,至此,弹出窗体部分完成,其他代码在FORM2!LIST1的KEYDOWN事件处理,主要是识别输入字符并且将焦点移动到相应行
    Form2.Show
    'end if
    End If
    End Sub
    '*******************************************************************************
    '以下代码在FORM2中
    '*******************************************************************************
    Option Explicit
    Dim mStr As StringPrivate Sub Form_GotFocus()
    Me.Hide
    End SubPrivate Sub Form_LostFocus()
    List1.SetFocus
    End SubPrivate Sub List1_KeyPress(KeyAscii As Integer)
    Debug.Print KeyAscii
    '这里可以LIST的自动特性,如果连续输入字符,那么就自动的来到刚输入的字符串列了,但是如果一停止,那就重新了...
    '我使用的方法是利用临时字符处理
    Dim i As Long
    If Len(mStr) Then
        If KeyAscii = 8 Then mStr = Left(mStr, Len(mStr) - 1) Else mStr = mStr & Chr(KeyAscii)
    End If
    Debug.Print Left(List1.List(i), Len(mStr)), mStr
    For i = 0 To List1.ListCount - 1
        If Left(List1.List(i), Len(mStr)) = mStr Then
            List1.ListIndex = i
            Select Case KeyAscii
            
                Case 32 '输入了空格,将当前行字符输入到插入符号后面,同样在这里处理其他字符
                    '这里的代码将FORM1!TEXT1当前行最后一个"."后面的字符覆盖为LIST1.LIST(List1.ListIndex)即可
                    '使用的方法可以是SENDMESSAGE,获取当前行内容,然后更改,不写了,前几天刚讨论过这个,你可以自己翻看一下
                Case Else
                
            End Select
            
        Else
            'Me.Hide
        End If
    Next
    End Sub
    '*********************************************************************
    '代码到此结束
      

  5.   

    忘记了,FORM1中TEXT1设置为多行...其实测试时不设置一样,因为是用GetCaretPos获取插入符位置,和行不行的就没关系了,声明里面多了一个ClientToScreen开始想用来着,呵呵,后来没用...代码还不完善,你自己弄吧,思路就象我上面写的,但是这里有一个问题,这个FORM2一出来,焦点就跑了,要解决这个问题其实也不难,把FORM2写成一个控件加载好象就可以了,在FORM2获得焦点时FORM1的标题蓝就还是蓝色的那种了吧.....也许吧,才起床(懒吧)还没吃饭,饿...吃饭去