8

外部デバイスからの信号をキャプチャし、キーストロークを別のアプリケーションに送信するC#プログラムを作成しています。SendKeysを使用していますが、正常に動作します。

SendKeysは、キーを押したまますぐに離すことで、キーを「押し」ます。キーを押して自由に離したいのですが。

私の質問は、「キーに「プッシュ」信号を送信し、一定時間後に「リリース」信号を送信する方法はありますか?」です。

SendKeysがこれを実行できるかどうかはわかりません。どんな手掛かり ?

4

4 に答える 4

5

.NET から直接行うことはできないと思います。ここで説明されているように、関数を p/invoking することで、keybd_event ネイティブ呼び出しを試すことができます: http://pinvoke.net/default.aspx/user32.keybd_event

keybd_event の MSDN はこちら: http://msdn.microsoft.com/en-us/library/ms646304(VS.85).aspx

それが役立つことを願っています!

于 2008-10-05T18:11:45.003 に答える
4

受け入れられた回答keybd_eventでは、廃止されたものを使用しています。公式の API は現在SendInput. http://inputsimulator.codeplex.comには、そのための優れたラッパーもあります。

ただし、上記のいずれも「鍵の保持」シナリオに完全には対応していません。これは、キーを保持すると複数のWM_KEYDOWNメッセージが生成され、その後WM_KEYUPリリース時に 1 つのメッセージが生成されるためです (これは Spy++ で確認できます)。

メッセージの頻度は、WM_KEYDOWNハードウェア、BIOS 設定、およびいくつかの Windows 設定によって異なりKeyboardDelayますKeyboardSpeed。後者は、Windows フォーム ( SystemInformation.KeyboardDelaySystemInformation.KeyboardSpeed) からアクセスできます。

前述の Input Simulator ライブラリを使用して、実際の動作を模倣するキー保持メソッドを実装しました。await/async準備万端、キャンセル対応。

static Task SimulateKeyHold(VirtualKeyCode key, int holdDurationMs, 
                            int repeatDelayMs, int repeatRateMs, CancellationToken token)
{
    var tcs = new TaskCompletionSource<object>();
    var ctr = new CancellationTokenRegistration();
    var startCount = Environment.TickCount;
    Timer timer = null;
    timer = new Timer(s =>         
    {
        lock (timer)
        {
            if (Environment.TickCount - startCount <= holdDurationMs)
                InputSimulator.SimulateKeyDown(key);
            else if (startCount != -1)
            { 
                startCount = -1; 
                timer.Dispose();
                ctr.Dispose();                    
                InputSimulator.SimulateKeyUp(key);
                tcs.TrySetResult(null);
            }
        }
    });
    timer.Change(repeatDelayMs, repeatRateMs);

    if (token.CanBeCanceled)
        ctr = token.Register(() =>
                       {
                           timer.Dispose();
                           tcs.TrySetCanceled();
                       });
    return tcs.Task;
}
于 2012-03-01T02:01:10.567 に答える
3

SendInput または keyb_event を使用できます。どちらもネイティブ API 関数です。SendInput には keybd_event よりもいくつかの利点がありますが、SendInput は XP 以降でのみ使用できます。

ここにmsdnリンクがあります http://msdn.microsoft.com/en-us/library/ms646310.aspx

お役に立てれば

于 2008-10-05T18:22:55.590 に答える
1

私はかつて、パワーポイントで同じことを行い、カーソルを非表示にし、後でスライドショーを停止しようとしていました. しかし、パワーポイントには多くのトップ レベル ウィンドウが表示されるため、難しくて注意が必要です。また、エミュレーションのどの部分が機能しない場合に失敗したかを特定するのも困難です。Spy++ を使用してメッセージ キューを調べたところ、キーを押した後にアクセラレータ コマンドが送信されたことがわかりました。代わりに、アクセラレータ コマンドをエミュレートしたところ、魅力的に動作しました。したがって、このような代替案を検討することをお勧めします。

于 2008-10-06T02:36:58.073 に答える