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

标签 c# winapi richtextbox

我正在尝试使用以下代码在 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 都会给出正确的索引。

最佳答案

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
    } 

关于c# - 如何在 C# 中将 EM_CHARFROMPOS 与 RichTextBox 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3855722/

相关文章:

c# - 为什么我重新实现的方法保留了基类的属性?

c++ - CWnd::CreateDlgIndirect 离开 m_hWnd==NULL

c# - RichTextBox 粘贴限制为 32k 个字符?

c# - 与类名同名的命名空间

c# - 关于在哪里放置 Try 和 Catch 语句的问题

c# - 如何对 ASP.NET Web API 路由进行单元测试?

visual-studio - 如何显示 Win32 MessageBox?

c++ - 是否可以将 Windows 控制台应用程序与 Windows GUI 应用程序一起运行?

c# - 当表单没有焦点时,RichTextBox 不会在按下鼠标时开始选择

c# - 将编号的音乐节点放入 RichTextBox