如何在 C# 中将 EM_CHARFROMPOS 与 RichTextBox 一起使用

发布于 2024-09-26 11:42:39 字数 1165 浏览 0 评论 0原文

我正在尝试使用以下代码按 RichTextBox 中的位置检索字符索引。我知道我可以使用 RichTextBox 类提供的 GetCharIndexFromPosition 方法,但我想知道以下代码有什么问题:

SendMessage 导入是这样的:

[DllImport("User32.dll", EntryPoint = "SendMessage", CharSet= CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref POINTL lParam);

然后这个调用:其中

int returnVal = (int)WinUser.SendMessage(this._textBox.Handle, (int)WinUser.Message.EM_CHARFROMPOS, 0, ref p);

p 是包含以 RichTextBox 左上角为原点的屏幕坐标的 POINTL 结构 实例。

POINTL 结构 定义为

[StructLayout(LayoutKind.Sequential)]
public struct POINTL
{
    public long x;
    public long y;
}

POINTL p 已初始化为:

WinUser.POINTL p;
p.x = 0;
p.y = 0;

现在的问题:

如果 p 已初始化 则 returnVal 为 0

如上面给出的,如果 p 是其他值,例如 {x = 10, y =10}, 或 {x = 1 且 y = 1},returnVal 为 1

在这两种情况下,函数 GetCharIndexFromPosition 给出正确的索引。

I am trying to use following code to retrieve character index by position in a RichTextBox. I know I can use GetCharIndexFromPosition method provided by RichTextBox Class, but I want to know what is wrong with following code:

SendMessage import is this:

[DllImport("User32.dll", EntryPoint = "SendMessage", CharSet= CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref POINTL lParam);

And then this call:

int returnVal = (int)WinUser.SendMessage(this._textBox.Handle, (int)WinUser.Message.EM_CHARFROMPOS, 0, ref p);

where p is the POINTL stucture instance containing the screen coordinates with upper-left corner of RichTextBox as origin.

The POINTL Structure is defined as

[StructLayout(LayoutKind.Sequential)]
public struct POINTL
{
    public long x;
    public long y;
}

The POINTL p has been initialized as:

WinUser.POINTL p;
p.x = 0;
p.y = 0;

NOW THE PROBLEM:

If p is initialized as given above the returnVal is 0

If p is anything else like {x = 10, y =10} or {x = 1 and y = 1} the returnVal is 1

In both the cases the function GetCharIndexFromPosition gives the correct index.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寒冷纷飞旳雪 2024-10-03 11:42:39

long 更改为 int
(Win32 LONG 是与 .Net int 相对应的 32 位整数)

.Net 的 GetCharIndexFromPosition 方法定义为

    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;
        // EM_CHARFROMPOS will return an invalid number if the last character in the RichEdit
        // is a newline. 
        //
        if (index >= t.Length) { 
            index = Math.Max(t.Length - 1, 0); 
        }
        return index; 
    }

NativeMethods .POINT 类型定义为

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

        public POINT() { 
        }

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

#if DEBUG
        public override string ToString() { 
            return "{x=" + x + ", y=" + y + "}";
        }
#endif
    } 

Change long to int.
(Win32 LONGs are 32-bit integers that correspond to .Net ints)

.Net's GetCharIndexFromPosition method is defined as

    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;
        // EM_CHARFROMPOS will return an invalid number if the last character in the RichEdit
        // is a newline. 
        //
        if (index >= t.Length) { 
            index = Math.Max(t.Length - 1, 0); 
        }
        return index; 
    }

The NativeMethods.POINT type is defined as

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

        public POINT() { 
        }

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

#if DEBUG
        public override string ToString() { 
            return "{x=" + x + ", y=" + y + "}";
        }
#endif
    } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文