我很好奇是否可以编写一个程序来监控我的文本选择。一种可能的用途是编写编辑器/ IDE不可知代码格式化程序:
- >我很乐意这么做......
答案 0 :(得分:6)
如果不了解将要使用的每个控件/应用程序的具体知识,这是不可能的,因为他们可以以不同方式处理/处理它。
答案 1 :(得分:3)
我认为你不能注册任何类型的钩子。我认为你需要经常轮询“聚焦”或选定的窗口。
您可以使用Windows自动化API执行此操作,据我所知,这超过了旧的Accesibility API: http://msdn.microsoft.com/en-us/library/ms747327.aspx
我已使用此API自动执行GUI测试。我有点生疏,所以我不确定,但我有理由相信你可以用它来做你想做的事情。基本上,API允许您使用桌面上的根遍历自动化对象树。每个自动化元素往往是某种窗口控件,不同的控件实现不同的模式。您还可以获取鼠标光标下方的元素,并可能直接进入当前选中/聚焦的元素。
之后我注意到TextPattern类有一个GetSelection()方法,该方法记录为“检索与当前文本选择或选择相关联的不相交文本范围的集合”。我敢打赌,文本框的自动化对象实现了TextPattern。 http://msdn.microsoft.com/en-us/library/system.windows.automation.textpattern.aspx
答案 2 :(得分:3)
此代码可帮助您在焦点窗口中获取聚焦控制文本,我希望有所帮助:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TextFocusedns
{
public partial class TextFocusedFrm : Form
{
#region APIs
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out Point pt);
[DllImport("user32.dll", EntryPoint = "WindowFromPoint", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr WindowFromPoint(Point pt);
[DllImport("user32.dll", EntryPoint = "SendMessageW")]
public static extern int SendMessageW([InAttribute] System.IntPtr hWnd, int Msg, int wParam, IntPtr lParam);
public const int WM_GETTEXT = 13;
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
internal static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
internal static extern IntPtr GetFocus();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int GetWindowThreadProcessId(int handle, out int processId);
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
internal static extern int AttachThreadInput(int idAttach, int idAttachTo, bool fAttach);
[DllImport("kernel32.dll")]
internal static extern int GetCurrentThreadId();
[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);
#endregion
private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer() { Interval = 100, Enabled = true };
public TextFocusedFrm()
{
InitializeComponent();
}
private void TextFocusedFrm_Load(object sender, EventArgs e)
{
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
try
{
MultiLineTextBox.Text = GetTextFromFocusedControl();
}
catch (Exception exp)
{
MultiLineTextBox.Text += exp.Message;
}
}
//Get the text of the focused control
private string GetTextFromFocusedControl()
{
try
{
int activeWinPtr = GetForegroundWindow().ToInt32();
int activeThreadId = 0, processId;
activeThreadId = GetWindowThreadProcessId(activeWinPtr, out processId);
int currentThreadId = GetCurrentThreadId();
if (activeThreadId != currentThreadId)
AttachThreadInput(activeThreadId, currentThreadId, true);
IntPtr activeCtrlId = GetFocus();
return GetText(activeCtrlId);
}
catch (Exception exp)
{
return exp.Message;
}
}
//Get the text of the control at the mouse position
private string GetTextFromControlAtMousePosition()
{
try
{
Point p;
if (GetCursorPos(out p))
{
IntPtr ptr = WindowFromPoint(p);
if (ptr != IntPtr.Zero)
{
return GetText(ptr);
}
}
return "";
}
catch (Exception exp)
{
return exp.Message;
}
}
//Get the text of a control with its handle
private string GetText(IntPtr handle)
{
int maxLength = 512;
IntPtr buffer = Marshal.AllocHGlobal((maxLength + 1) * 2);
SendMessageW(handle, WM_GETTEXT, maxLength, buffer);
string w = Marshal.PtrToStringUni(buffer);
Marshal.FreeHGlobal(buffer);
return w;
}
}
}