GetCaretPos()工作不正常?

时间:2013-03-09 05:04:39

标签: c# winforms winapi

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

1 个答案:

答案 0 :(得分:0)

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

这为您提供了两个选项:

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

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