4

カットアンドペーストをトリガーするプログラムに取り組んでいます

問題のない貼り付け(文字列をクリップボードにダンプするだけです)

カットやコピーはもう少し難しいことが証明されています

CTRL私が持っているプログラムは焦点が合っておらず、os + ALT+ 2 CTRL+ ALT+などに登録されたいくつかのホットキーがあります3

フォーカスされているウィンドウで強調表示されているものをすべてコピーするようにWindowsをトリガーするために使用したいもの

センドキーをやってみました

SendKeys.Send("^c");

しかし、それが機能しなくなったとしても、それは1回か2回は機能するようです。

別のウィンドウで強調表示されたコンテンツに対処するためにウィンドウをトリガーするためのより良い方法はありますか

4

2 に答える 2

13

これを行う1つの方法は、Win32SendInput関数を使用することです。を使用SendInputすると、キーを完全に押して登録するために、キーダウンイベントとキーアップイベントの両方をシミュレートする必要があります。CTRL+をシミュレートするCには、次のことを行う必要があります。

  • CTRLキーダウン
  • Cキーダウン
  • Cキーアップ
  • CTRLキーアップ

pinvoke.netにはいくつかの使用例がありSendInputます。注意すべき問題の1つは、キーがすでに押されているかどうかです。GetAsyncKeyStateキーがまだダウンしていない場合にのみ、キーダウンイベントをシミュレートするために使用できます。

CTRL以下は、 +をシミュレートする方法のサンプルコードですC。以下のコードを使用すると、単純に呼び出すことができます。Keyboard.SimulateKeyStroke('c', ctrl: true); これは、ユーザーが文字通りCTRL+を押したかのように機能するCため、アクティブなアプリケーションは、このようなイベントが発生したときに常に動作するように動作します(つまり、通常は何もコピーされない場合、何もコピーされません。この方法も)。

編集:送信された入力のバッチ処理については、以下のDavidのコメントを参照してください。SendInput以下のコードは、実際のユーザー入力イベントとのインターリーブ(および誤解)を回避するために、1回の呼び出しで入力イベントのシーケンス全体を送信する必要があります。

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);
        }
    }
}
于 2010-05-27T05:57:44.637 に答える
1

フォーカスされたウィンドウから選択したテキストを取得できる場合 (解決するのが簡単な問題かもしれません) 、クラスのSetTextメソッドを 使用する方がよいでしょう。System.Windows.Forms.Clipboard

于 2010-05-22T08:53:42.010 に答える