我想使用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行时,它可以正常工作,但是当它有多行时,它可以工作。
答案 0 :(得分:0)
文本框在没有聚焦时没有插入符号(因此当它不可见时)。具体来说,每个线程只有一个控件(“窗口”)可以随时插入插入符号。这意味着文本框必须以其他方式存储插入位置,而不是聚焦或不可见,并且当它再次聚焦时,在存储位置创建一个新的插入符号。
这为您提供了两个选项:
在文本框失去焦点之前获取并存储插入符位置(使用Leave事件或创建一个继承自TextBox类的类并覆盖LostFocus方法)。
使用TextBox的SelectionStart(+ SelectionLength)属性和GetPositionFromCharIndex方法查找文本框再次聚焦时创建插入符号的位置。