触发OS复制(Ctrl + C或按Ctrl-X)编程 [英] Trigger OS to copy (ctrl+c or Ctrl-x) programmatically

查看:355
本文介绍了触发OS复制(Ctrl + C或按Ctrl-X)编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个程序来触发多次剪切和粘贴

I'm working on a program to trigger cut and pastes

粘贴我有(我只是转储字符串到剪贴板)没有问题。

Pastes i have no problem with (i just dump a string into the clipboard)

剪切和或Copys被证明是有点困难。

Cut and or Copys are proving to be a little more difficult

该计划,我有不对焦,并具有与操作系统注册的几个快捷键(Ctrl + Alt + 2 CTRL + ALT + 3等)

The program i have is out of focus and has several hot keys registered with the os ( ctrl+alt+2 ctrl+alt+3 etc)

这是我想用触发的Windows拷贝任何在已聚焦窗口中高亮显示

that i want to use to trigger Windows to copy anything that is highlighted in the window that is focused

我试着做一个的SendKeys

I tried doing a sendkeys

SendKeys.Send("^c");

但似乎工作一次或两次,如果在所有然后停止工作。

but that seems to work once or twice if at all then stop working.

有没有更好的方式来尝试将Windows触发到一个不同的窗口

is there a better way to try to trigger windows into coping highlighted content on a different window

推荐答案

要做到这一点的方法之一是使用Win32的 SendInput 功能。随着 SendInput ,你必须向下既模拟键和键向上事件,以便为全键preSS注册。为了模拟按Ctrl + C,你必须做的:

One way to do this is by using the Win32 SendInput function. With SendInput, you have to simulate both the key down and key up events in order for the full key press to register. To simulate Ctrl+C, you'd have to do:


  • 控制下来

  • 'C'下来

  • 'C'了

  • 控制了

pinvoke.net 具有 SendInput 的使用。有一个问题要留神的是,如果关键是已经pressed。您可以使用<一个href=\"http://msdn.microsoft.com/en-us/library/ms646293%28VS.85%29.aspx\"><$c$c>GetAsyncKeyState仅模拟按键按下事件,如果关键是没有了。

pinvoke.net has some examples of SendInput usage. One issue to be mindful of is if the key is already pressed. You can use GetAsyncKeyState to only simulate a key down event if the key is not already down.

下面是你如何可以模拟按Ctrl + C一些例如code。与下面的code,你可以简单地调用 Keyboard.SimulateKeyStroke('C',CTRL:TRUE); 需要注意的是这个工程,如果用户从字面上pressed按Ctrl + C,所以活动的应用程序的行为当这样的事件发生,因为它总是(即如果没有正常复制,那么什么也不会用这种方法复制,无论是)。

Below is some example code of how you could simulate Ctrl+C. With the code below, you can simply call Keyboard.SimulateKeyStroke('c', ctrl: true); Note that this works as if the user literally pressed Ctrl+C, so the active application will behave as it always does when such an event happens (i.e. if nothing is normally copied, then nothing will be copied with this method, either).

编辑:查看下面的大卫的评论关于配料发送的输入。在code以下,应通过一个单一的调用来发送输入事件的整个序列 SendInput 来避免被交错(和misinter preTED)与真正的用户输入事件。

See David's comment below about batching the sent input. The code below should be sending the entire sequence of input events through a single call to SendInput to avoid being interleaved (and misinterpreted) with real user input events.

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;

namespace SimulateKeys
{
    static class Keyboard
    {
        public static void SimulateKeyStroke(char key, bool ctrl = false, bool alt = false, bool shift = false)
        {
            List<ushort> keys = new List<ushort>();

            if (ctrl)
                keys.Add(VK_CONTROL);

            if (alt)
                keys.Add(VK_MENU);

            if (shift)
                keys.Add(VK_SHIFT);

            keys.Add(char.ToUpper(key));

            INPUT input = new INPUT();
            input.type = INPUT_KEYBOARD;
            int inputSize = Marshal.SizeOf(input);

            for (int i = 0; i < keys.Count; ++i)
            {
                input.mkhi.ki.wVk = keys[i];

                bool isKeyDown = (GetAsyncKeyState(keys[i]) & 0x10000) != 0;

                if (!isKeyDown)
                    SendInput(1, ref input, inputSize);
            }

            input.mkhi.ki.dwFlags = KEYEVENTF_KEYUP;
            for (int i = keys.Count - 1; i >= 0; --i)
            {
                input.mkhi.ki.wVk = keys[i];
                SendInput(1, ref input, inputSize);
            }
        }

        [DllImport("user32.dll")]
        static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);

        [DllImport("user32.dll")]
        static extern short GetAsyncKeyState(ushort vKey);

        struct MOUSEINPUT
        {
            public int dx;
            public int dy;
            public uint mouseData;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        struct KEYBDINPUT
        {
            public ushort wVk;
            public ushort wScan;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        struct HARDWAREINPUT
        {
            public int uMsg;
            public short wParamL;
            public short wParamH;
        }

        [StructLayout(LayoutKind.Explicit)]
        struct MOUSEKEYBDHARDWAREINPUT
        {
            [FieldOffset(0)]
            public MOUSEINPUT mi;

            [FieldOffset(0)]
            public KEYBDINPUT ki;

            [FieldOffset(0)]
            public HARDWAREINPUT hi;
        }

        struct INPUT
        {
            public int type;
            public MOUSEKEYBDHARDWAREINPUT mkhi;
        }

        const int INPUT_KEYBOARD = 1;
        const uint KEYEVENTF_KEYUP = 0x0002;

        const ushort VK_SHIFT = 0x10;
        const ushort VK_CONTROL = 0x11;
        const ushort VK_MENU = 0x12;
    }

    class Program
    {
        static void Main(string[] args)
        {
            Thread.Sleep(3000);
            Keyboard.SimulateKeyStroke('c', ctrl: true);
        }
    }
}

这篇关于触发OS复制(Ctrl + C或按Ctrl-X)编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆