[DllImport("user32.dll")]
public static extern IntPtr WindowFromPoint(Point lpPoint);
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out Point lpPoint);
public static IntPtr GetWindowUnderCursor()
{
Point ptCursor = new Point();
if (!(PInvoke.GetCursorPos(out ptCursor)))
return IntPtr.Zero;
return WindowFromPoint(ptCursor);
}
private IntPtr WinProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case Win32.WmChangecbchain:
if (wParam == this.hWndNextViewer)
this.hWndNextViewer = lParam; //clipboard viewer chain changed, need to fix it.
else if (this.hWndNextViewer != IntPtr.Zero)
Win32.SendMessage(this.hWndNextViewer, msg, wParam, lParam); //pass the message to the next viewer.
break;
case Win32.WmDrawclipboard:
Win32.SendMessage(this.hWndNextViewer, msg, wParam, lParam); //pass the message to the next viewer //clipboard content changed
if (Clipboard.ContainsText() && !string.IsNullOrEmpty(Clipboard.GetText().Trim()))
{
Application.Current.Dispatcher.Invoke(
DispatcherPriority.Background,
(Action)
delegate
{
var currentText = Clipboard.GetText().RemoveSpecialCharacters();
if (!string.IsNullOrEmpty(currentText))
{
//In this section, we are doing something, because TEXT IS CAPTURED.
Task.Run(
async () =>
{
if (this.mainWindow.CancellationTokenSource.Token.IsCancellationRequested)
return;
await
this.WhenClipboardContainsTextEventHandler.InvokeSafelyAsync(this,
new WhenClipboardContainsTextEventArgs { CurrentString = currentText });
});
}
});
}
break;
}
return IntPtr.Zero;
}
private IKeyboardMouseEvents globalMouseHook;
public MainWindow()
{
// Note: for the application hook, use the Hook.AppEvents() instead.
globalMouseHook = Hook.GlobalEvents();
// Bind MouseDoubleClick event with a function named MouseDoubleClicked.
globalMouseHook.MouseDoubleClick += MouseDoubleClicked;
// Bind DragFinished event with a function.
// Same as double click, so I didn't write here.
globalMouseHook.MouseDragFinished += MouseDragFinished;
}
// I make the function async to avoid GUI lags.
private async void MouseDoubleClicked(object sender, System.Windows.Forms.MouseEventArgs e)
{
// Save clipboard's current content to restore it later.
IDataObject tmpClipboard = System.Windows.Clipboard.GetDataObject();
System.Windows.Clipboard.Clear();
// I think a small delay will be more safe.
// You could remove it, but be careful.
await Task.Delay(50);
// Send Ctrl+C, which is "copy"
System.Windows.Forms.SendKeys.SendWait("^c");
// Same as above. But this is more important.
// In some softwares like Word, the mouse double click will not select the word you clicked immediately.
// If you remove it, you will not get the text you selected.
await Task.Delay(50);
if (System.Windows.Clipboard.ContainsText())
{
string text = System.Windows.Clipboard.GetText();
// Your code
}
else
{
// Restore the Clipboard.
System.Windows.Clipboard.SetDataObject(tmpClipboard);
}
}
3条答案
按热度按时间7fhtutme1#
经过一番阅读,我已经找到了办法:
1.使用类似globalmousekeyhook.codeplex.com的代码挂钩双击事件
1.保存剪贴板的当前状态
1.使用
GetCursorPos
从user32.dll
获取当前鼠标位置1.使用
WindowFromPoint
从user32.dll
获取基于光标位置的窗口1.使用
SendMessage``user32.dll
发送复制命令(参见Using User32.dll SendMessage To Send Keys With ALT Modifier)1.您的代码
1.恢复在步骤2中保存的剪贴板内容
hk8txs482#
我实现了属于我的this项目。好的,我该怎么处理这个,让我解释一下。
应该考虑两件主要的事情。
所以,@jcrada的答案包含了一个很好的观点,那就是选项1。
根据上述方法,步骤必须是:
首先,创建包含剪贴板事件的Win32帮助器类。
注册鼠标和剪贴板事件,
鼠标事件;
最后一部分,当我们抓到,
诀窍是发送复制命令到窗口或操作系统另一方面控制+C命令,所以
SendKeys.SendWait("^c");
这样做。zvokhttg3#
前面的两个答案是有点难懂和不详细。无论如何,非常感谢他们,因为它帮助我实现了这个功能,经过多次尝试。
现在是2021年!让我们深入了解我详细、简单且最新的方法
1.从Nuget安装鼠标键挂钩,它以前是全局鼠标键挂钩。
1.将鼠标事件(MouseDoubleClick事件和MouseDragFinished事件,在这种情况下,您可能选择了一些文本)注册到函数中。
1.保存剪贴板的当前内容以便以后恢复。(可选)
1.清除剪贴板以确定您是否已在以后选择了某些文本。
1.发送
Ctrl+C
命令简单通过System.Windows.Forms.SendKeys.SendWait("^c");
1.获取剪贴板的内容。
如果你已经选择了一些文本,通过
System.Windows.Clipboard.GetText()
简单地得到它,然后做任何你想做的事情。如果没有,请恢复剪贴板。(可选)
这是我的代码