GetGUIThreadInfo - 如何在选择文本时在任何应用程序中准确获取插入符号的位置?

时间:2011-05-20 17:04:12

标签: c# winapi pinvoke caret

我正在使用GetGUIThreadInfo来跟踪任何Windows应用程序中的插入符号。我意识到它可能不适用于所有应用程序。现在我正在使用记事本,写字板和Word进行测试。我无法解释GetGUIThreadInfo在不同情况下返回的插入符坐标中的一些不一致。特别是我选择文本时未看到的结果。

我正在使用的文字是'abcd'。我是从左到右选择的。这是我的结果......

写字板

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

在写字板中选择文本时,底部会从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);
  }
}

0 个答案:

没有答案