我正在尝试使用以下代码在 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/