【问题标题】:How to get selected text from other applications and keeping clipboard text at the same time如何从其他应用程序中获取选定的文本并同时保留剪贴板文本
【发布时间】:2016-08-20 17:50:36
【问题描述】:

我正在尝试使用以下四行从其他应用程序中获取选定的文本,我对此没有任何问题:

Thread.Sleep(20);
SendCtrlC(GetWindowUnderCursor());
Thread.Sleep(30);
label1.Text = Clipboard.GetText();

我的问题是同时我想保留剪贴板文本,因为SendCtrlC(GetWindowUnderCursor()); 更改了剪贴板文本,为此我使用了变量before,如下代码:

string before = ""; //use before to keep clipboard text

//keep clipboard text
IDataObject iData = Clipboard.GetDataObject();
if (iData.GetDataPresent(DataFormats.Text))
before = ((String)iData.GetData(DataFormats.Text));

//get selected text
Thread.Sleep(20);
SendCtrlC(GetWindowUnderCursor());
Thread.Sleep(30);
label1.Text = Clipboard.GetText();

//return clipboard text back
Clipboard.SetText(before);

但它不会使文本和剪贴板数据仍然丢失...
有人知道是什么原因吗?

这是所有代码:

using MouseKeyboardActivityMonitor;
using MouseKeyboardActivityMonitor.WinApi;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private readonly KeyboardHookListener m_KeyboardHookManager;
        private readonly MouseHookListener m_MouseHookManager;
        private bool ctrlHeld;
        string pressedKey;
        public Form1()
        {
            InitializeComponent();

            m_KeyboardHookManager = new KeyboardHookListener(new GlobalHooker());
            m_KeyboardHookManager.Enabled = true;
            m_KeyboardHookManager.KeyDown += HookManager_KeyDown;
            m_KeyboardHookManager.KeyUp += HookManager_KeyUp;

            m_MouseHookManager = new MouseHookListener(new GlobalHooker());
            m_MouseHookManager.Enabled = true;
            m_MouseHookManager.MouseDown += HookManager_MouseDown;
            m_MouseHookManager.MouseUp += HookManager_MouseUp;

        }

        private void HookManager_KeyDown(object sender, KeyEventArgs e)
        {
            pressedKey = e.KeyCode + "";
            if (pressedKey == "LControlKey")
            {
                ctrlHeld = true;
            }
        }

        private void HookManager_KeyUp(object sender, KeyEventArgs e)
        {
            pressedKey = e.KeyCode + "";
            if (pressedKey == "LControlKey")
            {
                ctrlHeld = false;
            }
        }

        private void HookManager_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && (ctrlHeld))
            {
                string before = "";

                IDataObject iData = Clipboard.GetDataObject();
                if (iData.GetDataPresent(DataFormats.Text))
                    before = ((String)iData.GetData(DataFormats.Text));

                Thread.Sleep(20);
                SendCtrlC(GetWindowUnderCursor());
                Thread.Sleep(30);
                label1.Text = Clipboard.GetText();

                Clipboard.SetText(before);

            }
        }


        private void HookManager_MouseDown(object sender, MouseEventArgs e)
        {

        }


        [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 (!(Form1.GetCursorPos(out ptCursor)))
                return IntPtr.Zero;

            return WindowFromPoint(ptCursor);
        }

        /////////////////////////////////////////////////////////

        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static public extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);

        private void SendCtrlC(IntPtr hWnd)
        {
            uint KEYEVENTF_KEYUP = 2;
            byte VK_CONTROL = 0x11;
            SetForegroundWindow(hWnd);
            keybd_event(VK_CONTROL, 0, 0, 0);
            keybd_event(0x43, 0, 0, 0); //Send the C key (43 is "C")
            keybd_event(0x43, 0, KEYEVENTF_KEYUP, 0);
            keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);// 'Left Control Up

        }
    }
}

【问题讨论】:

  • 剪贴板数据是否更新为新值?
  • 你的意思是选中文本的值?
  • 是的,正如您所说,剪贴板数据丢失。

标签: c# .net clipboard


【解决方案1】:

试试这个:

// Get previous selcetd text
string before = Clipboard.GetText(TextDataFormat.UnicodeText);

// Get the selected text
Thread.Sleep(20);
SendCtrlC(GetWindowUnderCursor());
Thread.Sleep(30);
label1.Text = Clipboard.GetText(TextDataFormat.UnicodeText);

// Set the clipboard text back to the original value.
Clipboard.SetDataObject(before, false, 10, 2000);
// Clipboard.SetDataObject(string value, ignore this, try changing the clipboard a few times, the delay inbetween trying to chnage it in milliseconds);

【讨论】:

  • 感谢工作,但它在选择文本时冻结了我的鼠标
  • 那只保留文本。使用DataObject before = Clipboard.GetDataObject() as DataObject;可能会更好
【解决方案2】:

不确定要达到的直线路径 - 试试这条迂回路线。

在发送到 SendCtrlC(GetWindowUnderCursor()) 时,为什么不能尝试使用 SendCtrlC (GetWindowUnderCursor() + + 旧剪贴板数据)

不可打印字符 - ASCII 的前 31 个字符无法通过键盘输入

读取旧剪贴板数据并连接

当您读取数据时,您已使用相同的不可打印字符进行拆分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 2010-09-11
    • 2017-07-16
    • 2012-02-04
    相关资源
    最近更新 更多