C#中取得TextBox多行文本的行、列位置与定位

在模仿Windows自带的记事本做练习时,发现TextBox控件没有直接的办法取得当前的行和列的位置,也没有定位的功能。查了资料发现可以能过Windows API来实现,具体要用到SendMessage函数和EM_LINEFROMCHAR(0xC9)与EM_LINEINDEX(0xBB)两个消息常量,这需要自己引入或定义。下面是测试代码。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication7
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //引入LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
        [System.Runtime.InteropServices.DllImport("User32.DLL")]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int iParam);

        private const int EM_LINEFROMCHAR = 0xC9;
        private const int EM_LINEINDEX = 0xBB;
       
        //取得行列位置
       private Point GetCursorPos(TextBox textBox)
        {
            Point cursorPos = new Point(0, 0);
            int x, y;
            y = SendMessage(textBox.Handle, EM_LINEFROMCHAR, textBox.SelectionStart, 0);
            x = textBox.SelectionStart - SendMessage(textBox.Handle, EM_LINEINDEX, y, 0);
            cursorPos.Y = ++y;
            cursorPos.X= ++x;
            return cursorPos;
        }

        //经过测试,C#中需要在TextBox的Click事件、KeyUp事件和KeyDown事件中添加代码才可能实时取得行列位置
        private void textBox1_Click(object sender, EventArgs e)
        {
            Point cursorPos = GetCursorPos(this.textBox1);
            this.Text = cursorPos.ToString();
        }
     
        private void textBox1_KeyUp(object sender, KeyEventArgs e)
        {
            Point cursorPos = GetCursorPos(this.textBox1);
            this.Text = cursorPos.ToString();
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            Point cursorPos = GetCursorPos(this.textBox1);
            this.Text = cursorPos.ToString();
        }

        //定位行号,EM_LINEINDEX会根据指定的行号得到它的字符位置,把返回值指定给SelectionStart实现定位。
        private void button1_Click(object sender, EventArgs e)
        {
            this.textBox1.SelectionStart= SendMessage(this.textBox1.Handle, EM_LINEINDEX, 3, 0);
            this.textBox1.Focus();

            Point cursorPos = GetCursorPos(this.textBox1);
            this.Text = cursorPos.ToString();
        }
    }
}

补充说明:

EM_LINEFROMCHAR用于根据“字符位置”取得和设置当前行号,字符位置是指从开始到当前位置的字符数;
EM_LINEINDEX用于定位行号,实际是上修改字符位置定位到指定行的开始位置。


Delphi中关于EM_LINEFROMCHAR的帮助说明
An application sends an EM_LINEFROMCHAR message to retrieve the index of the line that contains the specified character index in a multiline edit control. A character index is the number of characters from the beginning of the edit control.

EM_LINEFROMCHAR
wParam = (WPARAM) ich; // character index
lParam = 0;             // not used; must be zero

Parameters

ich
Value of wParam. Specifies the character index of the character contained in the line whose number is to be retrieved. If the
ich parameter is -1, either the line number of the current line (the line containing the caret) is retrieved or, if there is a selection, the line number of the line containing the beginning of the selection is retrieved.

Return Values
The return value is the zero-based line number of the line containing the character index specified by ich.

Remarks
In a rich edit control, if the character index is greater than 64K, use the message EM_EXLINEFROMCHAR.

Delphi中关于EM_LINEINDEX的帮助说明
An application sends an EM_LINEINDEX message to retrieve the character index of a line in a multiline edit control. The character index is the number of characters from the beginning of the edit control to the specified line.

EM_LINEINDEX
wParam = (WPARAM) line; // line number
lParam = 0;             // not used; must be zero

Parameters

line
Value of wParam. Specifies the zero-based line number. A value of -1 specifies the current line number (the line that contains the caret).

Return Values
The return value is the character index of the line specified in the line parameter, or it is -1 if the specified line number is greater than the number of lines in the edit control.
 
 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值