1

我想使用 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 只有 1 行时它可以正常工作,但当它有多行时则不行。

4

1 回答 1

0

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

这使您有两个选择:

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

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

于 2014-11-29T12:42:16.483 回答