Я использую GetGUIThreadInfo для отслеживания каретки в любом приложении Windows. Я понимаю, что это может не работать для всех приложений. Прямо сейчас я тестирую в Блокноте, WordPad и Word. Я не могу объяснить некоторые несоответствия в координатах каретки, возвращаемых GetGUIThreadInfo в разных случаях. Особенно результаты, которые я вижу, когда текст выделен, а не выделен.
Я работаю с текстом abcd. Я выбираю слева направо. Вот мои результаты ...
WordPad
abcd| = left: 60, right: 61, top: 14, bottom: 32
abc|d| = left: 58, right: 66, top: 14, bottom: 15
Слово
abcd| = left: 53, right: 54, top: 113, bottom: 131
abc|d| = left: 45, right: 46, top: 113, bottom: 147
При выделении текста в WordPad нижняя часть уменьшается с 32 до 15. Почему?
Когда текст выделяется в Word, правое сужается с 54 до 46. В действительности, нижняя часть увеличивается с 131 до 147. Почему?
Я также думаю, что координаты, возвращаемые для Word, всегда неверны из-за небольшого количества. Я говорю это потому, что когда я конвертирую клиентские координаты rcCaret в экранные координаты, основанные на hwndCaret, а затем показываю окно в этом месте, оно никогда не находится рядом с кареткой. Неважно, выделен текст или нет.
Может кто-нибудь объяснить мне эти результаты? И, если возможно, также дайте мне несколько советов о том, как лучше занять позицию каретки?
namespace TrackCaret
{
class Program
{
static void Main(string[] args)
{
Timer trackCaretTimer = new Timer((TimerCallback)delegate(object data)
{
Win32.GUITHREADINFO guiInfo = new Win32.GUITHREADINFO();
guiInfo.cbSize = Marshal.SizeOf(guiInfo);
Win32.GetGUIThreadInfo(0, out guiInfo);
string msg = string.Format("left: {0}, right: {1}, top: {2}, bottom: {3}",
guiInfo.rcCaret.left, guiInfo.rcCaret.right, guiInfo.rcCaret.top, guiInfo.rcCaret.bottom);
Console.WriteLine(msg);
}, null, 0, 5000);
Console.ReadLine();
}
}
class Win32
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct GUITHREADINFO
{
public int cbSize;
public uint flags;
public IntPtr hwndActive;
public IntPtr hwndFocus;
public IntPtr hwndCapture;
public IntPtr hwndMenuOwner;
public IntPtr hwndMoveSize;
public IntPtr hwndCaret;
public RECT rcCaret;
}
[DllImport("user32.dll")]
public static extern bool GetGUIThreadInfo(uint idThread, out GUITHREADINFO lpgui);
}
}