是否有可能编写一个Windows应用程序获取通知时,在另一个Windows应用程序中select文本?

我很好奇,如果有可能写一个监视我的文本select的程序。 一个可能的用途是编写一个编辑器/ IDE不可知的代码格式化程序:

  1. 应用程序/服务P启动并以某种方式挂接到窗口,以便在任何窗口中select文本时得到通知。
  2. 其他应用程序A启动。
  3. 用户selectA中的文本
  4. P将被select的文本通知。

– >我很乐意得到这个…

Solutions Collecting From Web of "是否有可能编写一个Windows应用程序获取通知时,在另一个Windows应用程序中select文本?"

这是不可能的,如果没有每个控制/应用程序的具体知识将被使用,因为他们都可以处理/处理不同。

我不认为你可以注册任何形式的钩子。 我认为你需要不断地轮询“重点”或选定的窗口。

您可能可以使用Windows自动化API来执行此操作,就我所知,它是早期的Accesibility API的取代: http : //msdn.microsoft.com/zh-cn/library/ms747327.aspx

我已经使用这个API来自动化GUI测试。 我有点生疏,所以我不知道,但我相当有信心,你可以用它来做你想做的事情。 基本上,API允许您使用桌面上的根来遍历自动化对象的树。 每个自动化元素往往是某种窗口控制,不同的控制实现不同的模式。 您也可以获取鼠标光标下方的元素,并且可以直接进入当前选定的/被聚焦的元素。

之后,我注意到TextPattern类例如有一个GetSelection()方法,记录为“检索与当前文本选择或选择相关联的不相交的文本范围的集合”。 我敢打赌,文本框的自动化对象实现了TextPattern。 http://msdn.microsoft.com/en-us/library/system.windows.automation.textpattern.aspx

这段代码可以帮助你在专注的窗口中获得专注的控制文本,我希望这有助于:

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; } } }