奇怪,在我的程序里就会出错,SendMessageByRef txtA.hwnd, EM_GETSEL, l1, l2这个函数返回的l1,l2分别是代表什么意思?l = SendMessage(txtA.hwnd, EM_LINEINDEX, -1, 0)
这个函数在我的程序里每次返回的都是当前行第一列在文本中的位置,在你的例子里每次都返回是0,这个值到底是表示什么意思?我想自己改正这个程序,所以不把代码帖出来了

解决方案 »

  1.   

    大虾快来告诉我,l = SendMessage(txtA.hwnd, EM_LINEINDEX, -1, 0)的返回值l到底是表示什么,我估计应该是表示光标所在行的第一列在整个字符串中的绝对位置,但是在我自己的抄写里,返回的是这个值,在你给的例子里,每次都是返回0,我记得第一次用的时候列数是对的,后来每次再试,就不对了,列数等于richtextbox。selstart这个属性,我都是用拷贝的,怎么会出现这种想不通的错误,我都快晕死了
      

  2.   

    收到,EM_LINEINDEX消息返回某一行第一个字符在整个文本中的位置。其中wParam(就是)
    l1定义行数,如果设定为-1,那么将返回当前插入符所在的行的第一各字符的索引。
      

  3.   

    你是指用了我的函数:
    Sub GetCurPos(txtA As TextBox)
        Dim l, l1, l2 As Long
        Dim astr As String * 256
        
        l = SendMessage(txtA.hwnd, EM_LINEINDEX, -1, 0)
        iLineY = SendMessage(txtA.hwnd, EM_LINEFROMCHAR, l, 0)
        
        SendMessageByRef txtA.hwnd, EM_GETSEL, l1, l2
        iLineX = l1 - l
        Label1.Caption = "列:" + Str(iLineX)
        Label2.Caption = "行:" + Str(iLineY)
    End Sub就会总是返回0吗?
    另外对于 SendMessageByRef txtA.hwnd, EM_GETSEL, l1, l2 语句获得控件中被选择文本 
    的起始以及结束位置。l1指的是起始位置,l2指的是结束位置。由于前面
    l = SendMessage(txtA.hwnd, EM_LINEINDEX, -1, 0)
    语句已经获得了插入符所在行的第一个字符在字符串中的位置,那么用l1-l就可以得到插入
    符在该行的那个位置,即列值。
      

  4.   

    如果l是返回当前行的第一个字符位置的话,有个小bug,就是从上往下拖的时候,l1会小于l,所以我说会出现负数,也就是这个帖子的问题所在,应该用if判断,如果l1小于l,列值就应该是l2-l,这次很感谢TechnoFantasy大虾的帮忙,可以说这个求列值问题是我的程序里出现的最大问题了,现在已经完全解决了求列值的问题,我也知道了方法,不过只是理论上,实际上,不知道为什么单独用这个函数总是不对,是不是用重装win98了,不知道大虾试过结果怎么样。还有,我对这些消息很感兴趣,不知道应该从什么地方入手学习,看到这么多消息和消息值,真不知道该怎么应付了,请大虾指点在下,谢了
      

  5.   

    出现负数的原因可能在这里,注意前面的贴子里面关于API函数SendMessageByRef的定义:
    Private Declare Function SendMessageByRef Lib "user32" Alias "SendMessageA" _
            (ByVal hwnd As Long, ByVal wMsg As Long, wParam As Long, _
            lParam As Long) As Long
    里面wParam以及lParam都不是ByVal。而这个SendMessageByRef 在程序中调用:
    SendMessageByRef txtA.hwnd, EM_GETSEL, l1, l2
    这是因为发送EM_SETSEL函数获得的文本被选择区域的起始以及结束位置是保存在wParam
    以及lParam指向的缓冲区的(也就是指针),所以不能使用Byval定义wParam以及lParam。
    如果是使用了Byval,那么l1 l2始终为0。那么后面的语句:
    iLineX = l1 - l
    就会得到负数。
      

  6.   

      上面的我看得不大明白,没办法,太菜了,但是我认为出现负数的原因不是这样,虽然我只是个菜鸟,但是这个问题我必须和你讨论清楚
      如你所说,L1返回选定文本起始位置,L2返回选定文本结束位置,L是当前行第一列在整个文本中的位置。那么从上往下选定文本,比如从第一行到第二行,选定后,当前行在第二行,那么返回的L值必定比L1值大,因为选定的起始点在第一行,也就是说L在整个文本中的位置大于L1,如果这个时候还用L1-L,就会出现负数,应该是这样写:
      if L>L1 then 
        iLineX=L2-L  '如果起始点所在的行在当前行的前面,列数就是结束位置减L 
      else
        iLineX=L1-L  '如果起始点所在的行在当前行的后面,列数就是开始位置减L 
      end if
    这样做就不会出现负数了
    PS:我另外的程序中L还是总等于零,是不是vb的bug呀
      

  7.   

    不是的,有两种选择方法,一种是鼠标拖动选择,你可以使用如下语句:
    Sub GetCurPos(txtA As RichTextBox)
        Dim l, l1, l2 As Long
        Dim astr As String * 256
        
        l = SendMessage(txtA.hwnd, EM_LINEINDEX, -1, 0)
        iLineY = SendMessage(txtA.hwnd, EM_LINEFROMCHAR, l, 0)
        
        SendMessageByRef txtA.hwnd, EM_GETSEL, l1, l2
        Debug.Print l, l1, l2
        
        Label1.Caption = "列:" + Str(iLineX)
        Label2.Caption = "行:" + Str(iLineY)
    End Sub
    然后在Text的MouseMove事件中加入以下代码:
    If Button = 1 Then
        GetCurPos Text1
    End If
    你会发现无论是象那个方向拖动,都是 1<=l1<=l2 的,如果选择文本是从下向上的。l、l1
    会变化,如果是从上到下,则只有l2变化。
      

  8.   

    这个程序怎么总是给我返回L=0,你看看有没有错误,我拷过来的
    Option ExplicitPrivate Declare Function SendMessage Lib "user32" Alias "SendMessageW" _
            (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
            lParam As Any) As Long
    Private Declare Function SendMessageByRef Lib "user32" Alias "SendMessageA" _
            (ByVal hwnd As Long, ByVal wMsg As Long, wParam As Long, _
            lParam As Long) As Long
            
    Const EM_LINEFROMCHAR = &HC9
    Const EM_LINEINDEX = &HBB
    Const EM_GETLINE = &HC4
    Const EM_GETSEL = &HB0Dim iLineX, iLineY As LongSub GetCurPos(txtA As TextBox)
        Dim l, l1, l2 As Long
        Dim astr As String * 256
        
        l = SendMessage(txtA.hwnd, EM_LINEINDEX, -1, 0)
        iLineY = SendMessage(txtA.hwnd, EM_LINEFROMCHAR, l, 0)
        
        SendMessageByRef txtA.hwnd, EM_GETSEL, l1, l2
        iLineX = l1 - l
        Label1.Caption = "列:" + Str(iLineX)
        Label2.Caption = "行:" + Str(iLineY)
    End SubPrivate Sub Form_Load()
        Dim iFile
        Dim astr As String
        
        Label1.Height = 300: Label2.Height = 300
        Text1.Left = 0: Text1.Top = 0
        Text1.Text = ""
        Label1.Caption = ""
        Label2.Caption = ""
        
        iFile = FreeFile
        Open "C:\windows\readme.txt" For Input As #iFile
        Do
            Line Input #iFile, astr
            Text1.Text = Text1.Text + astr + vbCrLf
        Loop Until EOF(iFile)
        Close iFile
    End SubPrivate Sub Form_Resize()
        Label1.Top = Me.ScaleHeight - 300
        Label2.Top = Me.ScaleHeight - 300    Label1.Left = 0: Label2.Left = 1200
        Label1.Width = 1200
        Label2.Width = 1200
        
        Text1.Width = Me.ScaleWidth
        Text1.Height = Me.ScaleHeight - Label1.Height
    End SubPrivate Sub Text1_Click()
        GetCurPos Text1
    End SubPrivate Sub Text1_KeyUp(KeyCode As Integer, Shift As Integer)
        GetCurPos Text1
    End Sub
      

  9.   

    总算是搞定了,原来都是98惹得祸,我到2000下一切就正常了,不过不管怎么样试,L<=L1<=L2只在从下向上成立,如果是从上向下的话(起码要选定两行以上),就是L1<L<=L2,我运行的结果是不管向上还是向下(要越行),L都会变动
      

  10.   

    我明白是为什么了,你使用的是TextBox控件,而我用的是RTF控件,这两个控件在处理利用
    鼠标拖放选择文本时的插入符位置方面不同。