GetCaretPos()工作不正常

本文关键字:不正常 工作 GetCaretPos | 更新日期: 2023-09-27 18:02:59

我想使用GetCaretPos() Win32 API来获取文本框的插入符号的位置,即使它是不可见的。如果文本框只有一行,它似乎可以正常工作,但是它拥有的行越多,插入符号的y坐标就越不同(如GetCaretPos()所报告的那样)。GetCaretPos()报告的插入符号的y坐标总是大于插入符号的实际y坐标。

是什么原因导致的,我如何解决它?

代码如下:

[DllImport("user32")]
private extern static int GetCaretPos(out Point p);
[DllImport("user32")]
private extern static int SetCaretPos(int x, int y);
[DllImport("user32")]
private extern static bool ShowCaret(IntPtr hwnd);
[DllImport("user32")]
private extern static int CreateCaret(IntPtr hwnd, IntPtr hBitmap, int width, int height);
//Suppose I have a TextBox with a few lines already input.
//And I'll make it invisible to hide the real caret, create a new caret and set its position to see how the difference between them is.
private void TestCaret(){
   textBox1.Visible = false;//textBox1 is the only Control on the Form and has been focused.
   CreateCaret(Handle, IntPtr.Zero, 2, 20);
   Point p;
   GetCaretPos(out p);//Retrieve Location of the real caret (calculated in textBox1's coordinates)
   SetCaretPos(p.X + textBox1.Left, p.Y + textBox1.Top);
   ShowCaret(Handle);
}

正如我所说,textBox1在表单上的任何地方,当它不可见时,调用上面的方法将在真正的(隐藏的)插入符号的确切位置显示一个伪造的插入符号。当textBox1只有一行时,它工作正常,但当它有多行时,它就不工作了。

GetCaretPos()工作不正常

文本框在未聚焦时没有插入符号(因此当它不可见时也是如此)。具体来说,每个线程在任何时候只有一个控件("窗口")可以有插入符号。这意味着当文本框没有聚焦或不可见时,必须以其他方式存储插入符号的位置,并在再次聚焦时在存储的位置创建一个新的插入符号。

这留给你两个选择:

  1. 在文本框失去焦点之前获取并存储插入符号位置(使用Leave事件或创建一个继承TextBox类并覆盖LostFocus方法的类)。

  2. 使用TextBox的SelectionStart (+SelectionLength)属性和GetPositionFromCharIndex方法来查找当文本框再次聚焦时插入符号将被创建的位置。