C# 是否可以编写一个windows应用程序,在另一个windows应用程序中选择文本时获取通知?
我很好奇是否可以编写一个程序来监控我的文本选择。一种可能的用途是编写编辑器/IDE不可知代码格式化程序:C# 是否可以编写一个windows应用程序,在另一个windows应用程序中选择文本时获取通知?,c#,c++,windows,winapi,C#,C++,Windows,Winapi,我很好奇是否可以编写一个程序来监控我的文本选择。一种可能的用途是编写编辑器/IDE不可知代码格式化程序: 应用程序/服务P被启动,并以某种方式连接到窗口,以便在任何窗口中选择文本时收到通知 启动了另一个应用程序A 用户选择A中的文本 P将收到所选文本的通知 -->我很高兴能走到这一步。如果不了解将要使用的每个控件/应用程序,这是不可能的,因为它们都可以以不同的方式处理/处理它。我认为您无法注册任何类型的钩子。我认为您需要不断地对“聚焦”或选定的窗口进行投票 您可能可以使用Windows Auto
-->我很高兴能走到这一步。如果不了解将要使用的每个控件/应用程序,这是不可能的,因为它们都可以以不同的方式处理/处理它。我认为您无法注册任何类型的钩子。我认为您需要不断地对“聚焦”或选定的窗口进行投票 您可能可以使用Windows Automation API来实现这一点,据我所知,它取代了旧的Accessibility API: 我使用这个API来自动化GUI测试。我对它有点生疏,所以我不确定,但我有理由相信你可以用它来做你想做的事情。基本上,API允许您使用桌面上的根遍历自动化对象树。每个自动化元素往往是某种windows控件,不同的控件实现不同的模式。您还可以在鼠标光标下找到元素,也可以直接找到当前选定/聚焦的元素 在此之后,我注意到TextPattern类有一个GetSelection()方法,该方法被记录为“检索与当前文本选择相关联的不相交文本范围的集合”。我打赌TextBox的自动化对象实现了TextPattern。
此代码帮助您在聚焦窗口中获取聚焦控件文本,我希望这有助于:
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;
}
}
}
您是否真的希望在选择时收到通知,或者是否知道什么时候某些内容被复制到剪贴板上就足够了?这不是完全相同的事情,但可能很接近。您可以监视数据何时进入剪贴板。这对用户来说是一个额外的步骤,但可能都是一样的。。。看这个:+1喜欢这个问题,但我认为如果应用程序已经启动,它应该更有可能。