【问题标题】:Paste current time using global hotkey in C#在 C# 中使用全局热键粘贴当前时间
【发布时间】:2014-08-27 07:49:19
【问题描述】:

我正在尝试使用 C# 在任何窗口中粘贴当前时间。所以我在 C# 中定义了一个全局热键,当我在任何窗口中按下热键时,当前时间就会粘贴在那里。

问题是它与记事本完美配合,但在记事本++中它只粘贴一次当前时间,然后粘贴一些奇怪的字符,在记事本++中由SYN显示。我添加了一个 thread.sleep(500);在粘贴命令之前,它适用于每个窗口。

所以问题是为什么它可以在记事本中工作而不是在记事本++中?以及如何摆脱睡眠延迟以使其在每个窗口中都能正常工作?

提前致谢。

这是我的代码:

    public static void PasteDT()
    {
        ClipPut(DateTime.Now.ToString("HHmmss"));
        //Thread.Sleep(500); //<< without this line it works just once in Notepad++
        SendKeys.SendWait("^v");
    }

    public static void ClipPut(string ClipboardText)
    {
        Thread clipboardThread = new Thread(() => Clipboard.SetText(ClipboardText));
        clipboardThread.SetApartmentState(ApartmentState.STA);
        clipboardThread.IsBackground = false;
        clipboardThread.Start();
        clipboardThread.Join();
    }

【问题讨论】:

    标签: c# clipboard sendkeys


    【解决方案1】:

    问题在于按下热键时SendKeys.SendNotepad++ 处理。如果热键在Notepad++ 中已经有一个功能,或者它发生冲突,那么你会得到未定义的行为。

    睡眠之所以起作用,是因为它让你有时间释放初始触发热键,然后Notepad++ 正确处理粘贴命令。

    我不相信有办法使用SendKeys 解决这个问题,但是您可以使用SendInput,它会被应用程序排队并在“热键启动”时进行处理。

    过去,当我不得不向应用程序发送密钥时,我使用了Input Simulator,它在内部封装了低级 Win32 SendInput 调用。在您的情况下,生成的代码将是:

    //...
    Thread clipboardThread = new Thread(() =>
    {
        Clipboard.SetText(ClipboardText);
    });
    clipboardThread.SetApartmentState(ApartmentState.STA);
    clipboardThread.IsBackground = false;
    clipboardThread.Start();
    clipboardThread.Join();
    
    InputSimulator.Keyboard.ModifiedKeyStroke(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_V);
    //...
    

    【讨论】:

    • 感谢您的回答,但我宁愿不使用任何 dll 来完成此类任务。使用C#本身,不使用任何第三方dll,真的没有解决方案吗?
    • 有一个示例here 说明如何在没有第三方DLL 的情况下直接与SendInput 交互。它的工作方式与我的答案中的代码相同,但您必须在更精细的级别上处理按键
    猜你喜欢
    • 1970-01-01
    • 2013-12-08
    • 1970-01-01
    • 2018-12-21
    • 2017-12-20
    • 2021-12-21
    相关资源
    最近更新 更多