最后一个字符的GetCharIndexFromPosition() [英] GetCharIndexFromPosition() for the last char

查看:84
本文介绍了最后一个字符的GetCharIndexFromPosition()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在例如,如果我键入字符串 World ,然后将光标放在 l d 之间,则子字符串应为 d .到现在为止我的代码可以正常工作,但是如果我将光标放在字符串的末尾,它仍然会返回 d .

For example, if I type the string World then place the cursor between l and d, the sub-string should be d. Till now my code is working, however if I place the cursor at the end of the string, it still returns d.

在这种情况下,我希望它将返回空值.看起来像个虫子.参见 http://www.pcreview.co.uk/forums/problem-getcharindexfromposition-t4037504.html

I expect that it will return the empty then in this case. It looks like a bug. See http://www.pcreview.co.uk/forums/problem-getcharindexfromposition-t4037504.html

推荐答案

它是怎么回事?如果您查看该说明,它将获得最接近的字符.与您单击的位置最接近的字符确实是最后一个字母.我没有看到源,但是根据描述,它正在按预期工作.

How is it a bug? If you look at the discription, it gets the closest character. The closest character to the position you click is indeed the last letter. I haven't seen the source, but based on the description, it is working as intended.

在简要介绍 RichTextBox 可用的方法时,我发现没有一种方法可以轻松解决此问题.您可以做的就是在文本的结尾加上实际的字符,例如:空格.

In my brief look at the methods available to the RichTextBox I didn't see one that would resolve the issue easily. Something you could do is pad the ending of the text with an actual character, eg: a space.

//...
string originalText = richTextBox1.Text;
richTextBox1.Text += " ";

//Your code to get the index and substring

//Return the textbox to its original state
richTextBox1.Text = originalText;
richTextBox1.SelectionLength = 0;
richTextBox1.SelectionStart = positionBegin;

这应该可以满足您的要求,但这非常简单,并且效率低下,具体取决于要处理的文本量.如果您想创建一个功能类似于 GetCharIndexFromPosition(Point pt)的方法,则可能最终会进入非托管代码领域.

That should do what you are looking for, but it is rather simple and will be inefficient depending on the amount of text you're dealing with. If you wanted to create a method that functions like the GetCharIndexFromPosition(Point pt), you will probably end up in the unmanaged code realm.

我开始查看 RichTextBox 控件的源代码,它的确阻止了您选择超出文本长度最大长度的字符,如下所示:

I started looking at the source code of the RichTextBox control and it does indeed stop you from selecting a character outside the max length of the text length as seen here:

public override int GetCharIndexFromPosition(Point pt) {
    NativeMethods.POINT wpt = new NativeMethods.POINT(pt.X, pt.Y);
    int index = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.EM_CHARFROMPOS, 0, wpt);

    string t = this.Text;
    //This bit is stopping you from getting an index outside the length of the text
    if (index >= t.Length) {
        index = Math.Max(t.Length - 1, 0);
    }
    return index;
}

要修复"这样,您可以制作一个扩展方法,以相同的方式实现该方法,但是删除有关检查索引是否大于文本长度的检查点:

To "fix" this you can make a extension method that implements it the same way but remove the bit about checking to see if the index is larger than the length of the text:

public static class RichTextBoxExtensions
{
    private const int EM_CHARFROMPOS = 0x00D7;

    public static int GetTrueIndexPositionFromPoint(this RichTextBox rtb, Point pt)
    {
        POINT wpt = new POINT(pt.X, pt.Y);
        int index = (int)SendMessage(new HandleRef(rtb, rtb.Handle), EM_CHARFROMPOS, 0, wpt);

        return index;
    }

    [DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, POINT lParam);
}

[StructLayout(LayoutKind.Sequential)]
internal class POINT
{
    public int x;
    public int y;

    public POINT()
    {
    }

    public POINT(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

有了这个,您又回到了原始代码!只需将 GetCharIndexFromPosition 更改为 GetTrueIndexPositionFromPoint ,它将按预期工作.

With this you are back to your original code! Just change GetCharIndexFromPosition to GetTrueIndexPositionFromPoint and it will work as expected.

这篇关于最后一个字符的GetCharIndexFromPosition()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆