2

[コード コンテキスト]

皆さんこんにちは、

キーCとCtrlを押すキーボードイベントを送信して、コピーまたは貼り付けイベントを起動するアプリケーションに取り組んでいます。

私は実際にKbイベントを送信するためにこのメソッドを持っています:

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

public static void PressKey(Keys key, bool up)
{
    const int KEYEVENTF_EXTENDEDKEY = 0x1;
    const int KEYEVENTF_KEYUP = 0x2;
    if (up)
    {
        keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0);
    }
    else
    {
        keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0);
    }
}

で呼び出されます:

private void launchCopy()
{
    PressKey(Keys.ControlKey, false);
    PressKey(Keys.C, false);
    PressKey(Keys.C, true);
    PressKey(Keys.ControlKey, true);
}

そして静的メソッドで結果を取得します:

System.Windows.Forms.Clipboard.GetText()

ユーザーはマウスを使用して他のキーを押してこのイベントを起動する必要があるためKeyboard.IsKeyPressed(Keyboard.Key key);、SFML 2.0 の関数を使用してユーザー アクションを取得するために SFML を使用しています。

ユーザーイベントを待機する無限ループを作成し、コピーを起動してコピーデータを処理しました。このコードは正常に動作します 次に、いくつかのウィンドウで別の WPF ソリューションを作成し、NotifyIconを使用しています。メイン ウィンドウは、ロードされた後、ループのあるメソッドでスレッドを作成します (ユーザー イベント -> launchCopy)。

[デバッグ]

ユーザーがコピー イベントを押すと、PressKey メソッドが呼び出されますが、メソッドによって空の文字列が返されClipBoard.GetText ()ます。SFMLを使用して、キーが本当に押されているかどうかを確認しました

  private void PrintState ()
  {
    Console.WriteLine(Keyboard.IsKeyPressed(Keyboard.Key.C)  &&
                      (Keyboard.IsKeyPressed(Keyboard.Key.LControl) ||
                       Keyboard.IsKeyPressed(Keyboard.Key.RControl)));
  }

private void launchCopy()
{
    PrintState ();
    PressKey(Keys.ControlKey, false);
    PressKey(Keys.C, false);
    PrintState ();
    PressKey(Keys.C, true);
    PressKey(Keys.ControlKey, true);
    PrintState ();
}

出力は次のとおりです。

偽 真 偽

あるべきように...

【質問】

このアプリケーションでショートカット コピーのシミュレーションが機能しないのはなぜですか? 作業コードから私:

  • コードを別のスレッドに入れる
  • 1 他のスレッドだが同じアプリケーション: WPF ウィンドウ + NotifyIcon ライブラリ

WPF と競合することは可能ですか? または、PrintState 別のスレッドでメソッドを使用する際の問題ですか?

私はこれをデバッグしようとしています。

どんな助けやアイデアもいただければ幸いです

ありがとう。

4

1 に答える 1

0

遅すぎることはありません。

私の問題はこのスレッドによって解決されました。送信イベントではなく、問題はクリップボード データを取得することでした。

別のスレッドからクリップボードを使用するために使用したコードは次のとおりです。

public static class fastClipboard
{
        [DllImport("user32.dll")]
        static extern IntPtr GetClipboardData(uint uFormat);
        [DllImport("user32.dll")]
        static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
        [DllImport("user32.dll")]
        static extern bool IsClipboardFormatAvailable(uint format);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool OpenClipboard(IntPtr hWndNewOwner);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool CloseClipboard();
        [DllImport("kernel32.dll")]
        static extern IntPtr GlobalLock(IntPtr hMem);
        [DllImport("kernel32.dll")]
        static extern bool GlobalUnlock(IntPtr hMem);

        const uint CF_UNICODETEXT = 13;

        public static bool SetText(string data)
        {
            if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
                return false;
            if (!OpenClipboard(IntPtr.Zero))
                return false;

            var ptr = Marshal.StringToHGlobalUni(data);
            var res = SetClipboardData(CF_UNICODETEXT, ptr);
            CloseClipboard();
            if (res != IntPtr.Zero)
                return true;
            else
                return false;
        }

        public static string GetText()
        {
            if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
                return null;
            if (!OpenClipboard(IntPtr.Zero))
                return null;

            string data = null;
            var hGlobal = GetClipboardData(CF_UNICODETEXT);
            if (hGlobal != IntPtr.Zero)
            {
                var lpwcstr = GlobalLock(hGlobal);
                if (lpwcstr != IntPtr.Zero)
                {
                    data = Marshal.PtrToStringUni(lpwcstr);
                    GlobalUnlock(lpwcstr);
                }
            }
            CloseClipboard();
            return data;
        }
    }
于 2013-10-12T15:36:34.353 に答える