private void keyHookProc(object sender, KeyboardHookedEventArgs e) { if (e.UpDown == KeyboardUpDown.Down) { if (e.KeyCode == Keys.Space) { label1.Text = $"[Space]キーDownを検知"; } else { label1.Text = $"[他]キーDownを検知"; } } else if (e.UpDown == KeyboardUpDown.Up) { if (e.KeyCode == Keys.Space) { label1.Text = $"[Space]キーUpを検知"; } else { label1.Text = $"[他]キーUpを検知"; } } }
/// <summary> /// キーフック時に通知されるイベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnKeyboardHooked(object sender, KeyboardHookedEventArgs e) { Debug.WriteLine($"[hooking key code]:{e.ScanCode}({e.KeyCode})"); var main = ((App)System.Windows.Application.Current).main; //main?.optionWindow.setKeyState($"[hooking key code]:{e.ScanCode}({e.KeyCode})"); //main?.optionWindow.setKeyState($"hook({e.KeyCode},{IsShiftDown},{IsCtrlDown},{IsAltDown}) updown({e.UpDown})"); // Shift,Ctrl,Altならフラグ処理して終了 if (CheckEffectiveKeys(e)) { return; } // キー押下時以外は処理しないで終了 if (e.UpDown != KeyboardUpDown.Down) { return; } // 対象のショートカットが見つかれば実行する KeyShortcutDictionary.GetValueOrDefault(GetMixedKeyFromKey(e.KeyCode, IsShiftDown, IsCtrlDown, IsAltDown), null)?.Invoke(); // Window上でのキー操作でBeep音が鳴るのを防ぐ(コントロール・ウィンドウにキーイベントをバブリングしない) //if (Application.Current.Windows.Cast<Window>().Where(win=>win.IsActive).FirstOrDefault() != null) //{ // e.Cancel = true; //} }
private void OnHookedKeyboard(object sender, KeyboardHookedEventArgs e) { if (e.AltDown && e.KeyCode == Keys.F5) { OnClickTabToSpace(sender, e); } }
private void KeyboardHooked(object sender, KeyboardHookedEventArgs e) { if (e.UpDown == KeyboardUpDown.Up && API.GetForegroundWindow() == Handle && !ToolStripTextBox_SkinName.Focused) { e.Cancel = true; // 選択 ToolStripComboBox_Keys.SelectedItem = e.KeyCode; } }
public void SelfEventPathThroughTest() { var config = ConfigUtil.Deserialize(Resources.TestConfig13); var dsc = new DummySendKeyCode(); var model = new Model(config, dsc); var windowInfo = new WindowInfo("ClipStudioPaint.exe", "新規ファイル.clip - CLIP STUDIO PAINT"); model.WindowInfo = windowInfo; model.ApplicationGroup.Name.Is("CLIP STUDIO PAINT"); model.Bank.Name.Is(""); model.Bank.Entries.Count.Is(3); model.Bank.Entries[0].Trigger.Is("F"); model.Bank.Entries[0].ActionItem.ActionType.Is(ActionType.Send); model.Bank.Entries[0].ActionItem.ActionValue.Is("g"); model.Bank.Entries[1].Trigger.Is("G"); model.Bank.Entries[1].ActionItem.ActionType.Is(ActionType.Send); model.Bank.Entries[1].ActionItem.ActionValue.Is("r"); var ksF = new KeyboardState { KeyCode = Keys.F }; var ksG = new KeyboardState { KeyCode = Keys.G }; // Fを押す model.SetEvent(new KeyboardHookedEventArgs( KeyboardMessage.KeyDown, ref ksF)); // g を送出する dsc.EventLog.Count.Is(1); dsc.EventLog[0].Type.Is(DummySendKeyCode.EventType.SendWait); dsc.EventLog[0].Value.Is("g"); // g を自分で受け取ってしまう var e1 = new KeyboardHookedEventArgs( KeyboardMessage.KeyDown, ref ksG); model.SetEvent(e1); var e2 = new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref ksG); model.SetEvent(e2); // g がキャンセルされて、r が送出されてしまっているとまずい。 dsc.EventLog.Count.Is(1); e1.Cancel.Is(false); e2.Cancel.Is(false); model.SetEvent(new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref ksF)); dsc.EventLog.Count.Is(1); }
//横流しするだけ private void OnKeyboardUpDown(object sender, KeyboardHookedEventArgs e) { try { this.KeyboardUpDown?.Invoke(this, e); } catch (Exception ex) { MessageBox.Show("Error when executing KeyboardUpDown event:" + ex.Message); } }
private void KeyboardHooked(object sender, KeyboardHookedEventArgs e) { if (e.UpDown == KeyboardUpDown.Up && API.GetForegroundWindow() == Handle) { var item = setting.Keys.FirstOrDefault(target => target.Key == e.KeyCode); if (item != null) { ListBox_Registered.SelectedItem = item; } } }
private void KeyboardHook_KeyboardHooked(object sender, KeyboardHookedEventArgs e) { if ((int)e.KeyCode == KeyInterop.VirtualKeyFromKey(Documents.ShiftaKey) && e.UpDown == KeyboardUpDown.Down) { shiftaTimeSec = Documents.CountDownTime; shiftaStopwatch.Restart(); } if ((int)e.KeyCode == KeyInterop.VirtualKeyFromKey(Documents.DebandKey) && e.UpDown == KeyboardUpDown.Down) { debandTimeSec = Documents.CountDownTime; debandStopwatch.Restart(); } }
private void KeyHookEvent( object sender, KeyboardHookedEventArgs e ) { if( e.UpDown != KeyboardUpDown.UP ) { return; } var keycode = (byte)e.KeyCode; // ReSharper disable once SwitchStatementMissingSomeCases switch( keycode ) { case (byte)Keys.Return: this.result = Result.OK; Close(); return; case (byte)Keys.Escape: if( this._keyList.Count == 0 ) { this.result = Result.CANCEL; Close(); return; } break; } switch( this.keyType ) { case KeyType.SINGLE: this._keyList.Clear(); if( keycode == (byte)Keys.Escape ) { this.lblInputKey.Text = "Press Any Key"; return; } this.lblInputKey.Text = Key.KEY_TEXT[keycode]; this._keyList.Add( keycode ); break; case KeyType.MULTI: if( (byte)e.KeyCode == (byte)Keys.Escape ) { this.lblInputKey.Text = "Press Any Key"; this._keyList.Clear(); return; } if( this._keyList.Count == 0 ) { this._keyList.Add( keycode ); this.lblInputKey.Text = Key.KEY_TEXT[keycode]; } else { this._keyList.Add( keycode ); this.lblInputKey.Text = this.lblInputKey.Text + " + " + Key.KEY_TEXT[keycode]; } break; default: throw new ArgumentOutOfRangeException(); } }
public void SetEvent(KeyboardHookedEventArgs e) { if (_keySending != 0) { return; } if (_ApplicationGroup.Name != "") { Debug.WriteLine($"{e.KeyCode} {e.UpDown}"); } var result = _stateMachine.Exec( _Bank.Entries, e.KeyCode, e.UpDown, IsMenuVisible); e.Cancel = result.ShouldCancel; ProcessExecResult(result); }
/// <summary> /// キーダウン/アップフラグをセットする /// </summary> /// <param name="e"></param> private void SetKeyInputFlag(KeyboardHookedEventArgs e) { try { if (e.KeyCode.ToString() == "LShiftKey" || e.KeyCode.ToString() == "RShiftKey") { ShiftKeyDown = e.UpDown == Macrobo.Utils.Gui.KeyboardUpDown.Down; } if (e.KeyCode.ToString() == "LControlKey" || e.KeyCode.ToString() == "RControlKey") { ControlKeyDown = e.UpDown == Macrobo.Utils.Gui.KeyboardUpDown.Down; } if (e.KeyCode.ToString() == "S") { SKeyDown = e.UpDown == Macrobo.Utils.Gui.KeyboardUpDown.Down; } } catch (Exception ex) { throw Program.ThrowException(ex); } }
/// <summary> /// マシン全体のキー操作をDBに反映します。 /// </summary> private void OnKeyboardHooked(object sender, KeyboardHookedEventArgs e) { // キーアップ以外は無視 if (e.UpDown != KeyboardUpDown.Up) { return; } if (IsLoading) { return; } try { var ret = _currentService.CountUp(e.KeyCode); _currentHolder.SetCount(ret.Code, ret.Count); } catch (Exception ex) { Logger.Error($"カウントアップに失敗しました。KeyCode={e.KeyCode}", ex); } }
/// <summary> /// 装飾キーの押下状態を更新 /// </summary> /// <param name="e"></param> /// <returns></returns> private bool CheckEffectiveKeys(KeyboardHookedEventArgs e) { switch (e.KeyCode) { case Key.LeftShift: case Key.RightShift: IsShiftDown = (e.UpDown == KeyboardUpDown.Down); return(true); case Key.LeftCtrl: case Key.RightCtrl: IsCtrlDown = (e.UpDown == KeyboardUpDown.Down); return(true); case Key.LeftAlt: case Key.RightAlt: IsAltDown = (e.UpDown == KeyboardUpDown.Down); return(true); default: return(false); } }
public void NoMatchingApplicationGroupTest() { var config = ConfigUtil.Deserialize(Resources.TestConfig07); var model = new Model(config, new DummySendKeyCode()); model.Basic.Title.Is("Title01"); model.ApplicationGroups.IsNotNull(); model.ApplicationGroup.Name.Is(""); model.Bank.Name.Is(""); // 該当あり model.WindowInfo = new WindowInfo("ClipStudioPaint.exe", "新規ファイル.clip - CLIP STUDIO PAINT"); model.ApplicationGroup.IsNotNull(); model.ApplicationGroup.Name.Is("CLIP STUDIO PAINT B"); model.Bank.Name.Is(""); model.IsMenuVisible.IsFalse(); model.MainWindowVisibility.Is(Visibility.Visible); // 該当なし model.WindowInfo = new WindowInfo("booboo.exe", "BOOBOO PAINT"); model.ApplicationGroups.IsNotNull(); model.ApplicationGroup.Name.Is(""); model.IsMenuVisible.IsFalse(); model.MainWindowVisibility.Is(Visibility.Hidden); var state = new KeyboardState { KeyCode = Keys.NumPad5 }; var e = new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref state); model.SetEvent(e); }
/// <summary> /// キーフックイベント /// フックしたキーをjobの各メソッドに振り分ける /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void KeyHookEvent( object sender, KeyboardHookedEventArgs e ) { #if DEBUG this._sw.Start(); #endif if( this._otherWindowOpen ) { #if DEBUG goto echo; #else return; #endif } if( this._job.ActiveWindow && this._job.BarrageEnable && e.ExtraInfo != (int)Key.EXTRA_INFO ) { if( CurrentSettingFile.CancelList.Contains( (byte)e.KeyCode ) ) { e.Cancel = true; } } switch( e.UpDown ) { case KeyboardUpDown.DOWN: if( this._job.ActiveWindow && this._job.BarrageEnable ) { //キーダウンイベント Task.Run( () => this._job.KeydownEvent( e ) ); } break; case KeyboardUpDown.UP: if( this._job.ActiveWindow && this._job.BarrageEnable ) { //キーアップイベント Task.Run( () => this._job.KeyupEvent( e ) ); } if( e.ExtraInfo != (int)Key.EXTRA_INFO ) { //setting change hot key if( this._hotKeys.ContainsKey( (byte)e.KeyCode ) ) { CurrentSettingName = this._hotKeys[(byte)e.KeyCode]; #if DEBUG goto echo; #else return; #endif } if( (byte)e.KeyCode == Properties.Settings.Default.hotKeyLorSwitching ) { this._job.BarrageEnable = !this._job.BarrageEnable; } } break; default: throw new ArgumentOutOfRangeException(); } #if DEBUG echo: this._sw.Stop(); if( this._sw.Elapsed.TotalMilliseconds > 0.05 ) { Console.WriteLine( this._sw.Elapsed.TotalMilliseconds + ":" + KeysToText((byte)e.KeyCode) + "," + e.UpDown); } this._sw.Reset(); #endif }
/// <summary> /// キーダウン時に呼ばれる /// EnablekeyFは関数のはじめに、 /// EnablekeyEは関数の終わりにそれぞれtrueに書き換えられる /// ここでは /// コマンドの呼び出し、 /// 連打切替の有効無効の切り替え、 /// 方向キーの記憶を行う /// </summary> /// <param name="e"> 押されたキー情報 </param> internal async void KeydownEvent(KeyboardHookedEventArgs e) { var key = (byte)e.KeyCode; //このキー入力がどこから発行されたものか判定 if (e.ExtraInfo == (int)Key.EXTRA_INFO) { //LORから switch (key) { case (byte)Keys.Left: _frontDirection = (byte)Keys.Left; _backDirection = (byte)Keys.Right; break; case (byte)Keys.Right: _frontDirection = (byte)Keys.Right; _backDirection = (byte)Keys.Left; break; default: return; } } else { // キーボードから if (this._commandTask?.Status == TaskStatus.Running) { //コマンド実行中で、 if (this._mass.Barrages.Any(b => b.Push.Contains(key) && !b.Push.Any(k => !_enablekeyE[k]))) { //連打キーだった場合コマンドの終了待機 await this._commandTask; } if (this._mass.Commands.Any(c => CommandCheck(key, c.Push))) { //コマンドキーだった場合 return; } } } _enablekeyF[key] = true; //コマンド foreach (var c in this._mass.Commands.Where(c => CommandCheck(key, c.Push))) { this._commandTask = Task.Run(() => ThreadCommand(c.sendList, _frontDirection, _backDirection)); break; } // ReSharper disable once SwitchStatementMissingSomeCases switch (key) { case (byte)Keys.Left: _frontDirection = (byte)Keys.Left; _backDirection = (byte)Keys.Right; break; case (byte)Keys.Right: _frontDirection = (byte)Keys.Right; _backDirection = (byte)Keys.Left; break; } //切替 foreach (var t in this._mass.Toggles.Where(t => CommandCheck(key, t.Push))) { //not typo this._mass.ChangeEnable(t.Id, t.Enable = this._enableToggle[t.Id] = !this._enableToggle[t.Id]); DIconUpdate(); } _enablekeyE[key] = true; }
/// <summary> /// キーアップ時に呼ばれる /// 該当するキーの押下フラグをfalseにする /// また、マウス操作もキーアップをトリガーとして発動させるようにする /// </summary> /// <param name="e"> 離されたキー情報 </param> internal void KeyupEvent(KeyboardHookedEventArgs e) { if (e.ExtraInfo != (int)Key.EXTRA_INFO) { _enablekeyF[(byte)e.KeyCode] = false; _enablekeyE[(byte)e.KeyCode] = false; foreach (var m in this._mass.Mice.Where(m => !m.Push.Any(k => !_enablekeyE[k] && k != (byte)e.KeyCode))) { if (this._mouseTask?.Status == TaskStatus.Running) { if (Properties.Settings.Default.mouseReClick == 0) { return; } else { this._mouseTaskCancelToken.Cancel(); while (this._mouseTask?.Status == TaskStatus.Running) { } } } //スイッチの状態によって、操作する/しないを判定する if (m.mouseData.SwitchState != SwitchingStyle.BOTH && m.mouseData.SwitchState != Client.SwitchState) { continue; } this._mouseTaskCancelToken = new CancellationTokenSource(); this._mouseTask = Task.Run(() => { foreach (var send in m.mouseData.Value) { if (this._mouseTaskCancelToken.Token.IsCancellationRequested) { throw new TaskCanceledException(); } var x = Client.x + (int)Math.Round(send.x * Client.ratioW); var y = Client.y + (int)Math.Round(send.y * Client.ratioH); switch (send.op) { case Operation.LEFT: Win32.Mouse.SetCursorPos(x, y); Click.Left(x, y, send.sleepBetween); break; case Operation.RIGHT: Win32.Mouse.SetCursorPos(x, y); Click.Right(x, y, send.sleepBetween); break; case Operation.MOVE: Win32.Mouse.SetCursorPos(x, y); break; default: throw new ArgumentOutOfRangeException(); } if (this._mouseTaskCancelToken.Token.IsCancellationRequested) { throw new TaskCanceledException(); } Thread.Sleep(send.sleepAfter); } }, this._mouseTaskCancelToken.Token); } } }
private void _hook_KeyboardHooked(object sender, KeyboardHookedEventArgs e) { Event = e; }
public void SendSelfKeyTest() { var ksF = new KeyboardState { KeyCode = Keys.F }; var config = ConfigUtil.Deserialize(Resources.TestConfig16); var dsc = new DummySendKeyCode(); var model = new Model(config, dsc); var windowInfo = new WindowInfo("ClipStudioPaint.exe", "新規ファイル.clip - CLIP STUDIO PAINT"); model.WindowInfo = windowInfo; model.ApplicationGroup.Name.Is("CLIP STUDIO PAINT"); model.Bank.Name.Is(""); model.Bank.Entries.Count.Is(1); model.Bank.Entries[0].Trigger.Is("F"); model.Bank.Entries[0].ActionItem.ActionType.Is(ActionType.None); model.Bank.Entries[0].ActionItem.ActionValue.IsNull(); model.Bank.Entries[0].ActionItem.NextBank.Is("Bank02"); // f(down) -> f(up) model.SetEvent(new KeyboardHookedEventArgs( KeyboardMessage.KeyDown, ref ksF)); model.SetEvent(new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref ksF)); dsc.EventLog.Count.Is(0); model.Bank.Name.Is("Bank02"); model.Bank.Entries.Count.Is(1); model.Bank.Entries[0].Trigger.Is("F"); model.Bank.Entries[0].ActionItem.ActionType.Is(ActionType.Send); model.Bank.Entries[0].ActionItem.ActionValue.Is("f"); model.Bank.Entries[0].ActionItem.NextBank.Is(""); /* * 処理の時系列が反転するけれども、 * dsc.SendWaitLambda に処理をセットしておくと SendWait() の中で呼び * 出される。 * これにより、ProcAction() 中で呼び出される SendWait() の中から呼び * 出されたイベントが model の中に到達してそれがキャンセルされずに、 * 操作対象のアプリケーションに届くことを 確認できる。 * 検証に失敗した場合は dsc.SendWaitLambdaExceptions に記録されるので、 * 件数を検証する必要がある。 */ dsc.SendWaitLambda = () => { var ksF2 = new KeyboardState { KeyCode = Keys.F }; var e1 = new KeyboardHookedEventArgs( KeyboardMessage.KeyDown, ref ksF2); model.SetEvent(e1); e1.Cancel.Is(false); dsc.EventLog.Count.Is(1); var e2 = new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref ksF2); model.SetEvent(e2); e2.Cancel.Is(false); dsc.EventLog.Count.Is(1); }; // action を呼び出す。この中で SendWait() が呼び出されて、 // dsc.SendWaitLambda が呼び出され、上記の検証が走る var e3 = new KeyboardHookedEventArgs( KeyboardMessage.KeyDown, ref ksF); model.SetEvent(e3); e3.Cancel.Is(true); dsc.SendWaitLambda = null; // 余分に呼び出されないようにクリア dsc.SendWaitLambdaExceptions.Count.Is(0); dsc.EventLog.Count.Is(1); // ここらへんで LoadBank が起こる model.Bank.Name.Is(""); model.Bank.Entries.Count.Is(1); // 最後にユーザー入力の f(up) が来る var e4 = new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref ksF); model.SetEvent(e4); e4.Cancel.Is(true); dsc.EventLog.Count.Is(1); }
public void ProceActionTest() { var config = ConfigUtil.Deserialize(Resources.TestConfig15); var dsc = new DummySendKeyCode(); var model = new Model(config, dsc); var windowInfo = new WindowInfo("ClipStudioPaint.exe", "新規ファイル.clip - CLIP STUDIO PAINT"); model.WindowInfo = windowInfo; model.ApplicationGroup.Name.Is("CLIP STUDIO PAINT"); model.Bank.Name.Is(""); model.Bank.Entries.Count.Is(2); model.Bank.Entries[0].Trigger.Is("F"); model.Bank.Entries[0].ActionItem.ActionType.Is(ActionType.Send); model.Bank.Entries[0].ActionItem.ActionValue.Is("a"); model.Bank.Entries[1].Trigger.Is("G"); model.Bank.Entries[1].ActionItem.ActionType.Is(ActionType.Menu); model.Bank.Entries[1].ActionItem.ActionValue.Is("01"); var action = model.Bank.Entries[1].ActionItem; model.ProcAction(action, KeyboardUpDown.Down); model.ProcAction(action, KeyboardUpDown.Up); model.Menu.Name.Is("01"); model.Menu.MenuItem.Count.Is(1); model.Menu.MenuItem[0].ActionItem.ActionType.Is(ActionType.Send); model.Menu.MenuItem[0].ActionItem.ActionValue.Is("f"); /* * 処理の時系列が反転するけれども、 * dsc.SendWaitLambda に処理をセットしておくと SendWait() の中で呼び * 出される。 * これにより、ProcAction() 中で呼び出される SendWait() の中から呼び * 出されたイベントが model の中に到達してそれがキャンセルされずに、 * 操作対象のアプリケーションに届くことを 確認できる。 * 検証に失敗した場合は dsc.SendWaitLambdaExceptions に記録されるので、 * 件数を検証する必要がある。 */ dsc.SendWaitLambda = () => { var ksF = new KeyboardState { KeyCode = Keys.F }; var e1 = new KeyboardHookedEventArgs( KeyboardMessage.KeyDown, ref ksF); model.SetEvent(e1); e1.Cancel.Is(false); dsc.EventLog.Count.Is(1); var e2 = new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref ksF); model.SetEvent(e2); e2.Cancel.Is(false); dsc.EventLog.Count.Is(1); }; // action を呼び出す。この中で SendWait() が呼び出されて、 // dsc.SendWaitLambda が呼び出され、上記の検証が走る action = model.Menu.MenuItem[0].ActionItem; model.ProcAction(action, KeyboardUpDown.Down); dsc.SendWaitLambda = null; // 余分に呼び出されないようにクリア dsc.SendWaitLambdaExceptions.Count.Is(0); dsc.EventLog.Count.Is(1); dsc.EventLog[0].Type.Is(DummySendKeyCode.EventType.SendWait); dsc.EventLog[0].Value.Is("f"); model.ProcAction(action, KeyboardUpDown.Up); dsc.EventLog.Count.Is(1); }
public void SendAfterLoadBankTest() { var config = ConfigUtil.Deserialize(Resources.TestConfig14); var dsc = new DummySendKeyCode(); var model = new Model(config, dsc); var windowInfo = new WindowInfo("ClipStudioPaint.exe", "新規ファイル.clip - CLIP STUDIO PAINT"); model.WindowInfo = windowInfo; model.ApplicationGroup.Name.Is("CLIP STUDIO PAINT"); model.Bank.Name.Is(""); model.Bank.Entries.Count.Is(2); model.Bank.Entries[0].Trigger.Is("F"); model.Bank.Entries[0].ActionItem.ActionType.Is(ActionType.None); model.Bank.Entries[0].ActionItem.ActionValue.IsNull(); model.Bank.Entries[0].ActionItem.NextBank.Is("Bank01"); model.Bank.Entries[1].Trigger.Is("R"); model.Bank.Entries[1].ActionItem.ActionType.Is(ActionType.Send); model.Bank.Entries[1].ActionItem.ActionValue.Is("a"); model.Bank.Entries[1].ActionItem.NextBank.Is(""); var ksF = new KeyboardState { KeyCode = Keys.F }; var ksG = new KeyboardState { KeyCode = Keys.G }; var ksR = new KeyboardState { KeyCode = Keys.R }; // Fを押す model.SetEvent(new KeyboardHookedEventArgs( KeyboardMessage.KeyDown, ref ksF)); dsc.EventLog.Count.Is(0); // この時点で LoadBank が完了していなければならない。 model.Bank.Name.Is("Bank01"); model.Bank.Entries.Count.Is(2); model.Bank.Entries[0].Trigger.Is("G"); model.Bank.Entries[0].ActionItem.ActionType.Is(ActionType.Send); model.Bank.Entries[0].ActionItem.ActionValue.Is("r"); model.Bank.Entries[0].ActionItem.NextBank.Is(""); model.Bank.Entries[1].Trigger.Is("R"); model.Bank.Entries[1].ActionItem.ActionType.Is(ActionType.Send); model.Bank.Entries[1].ActionItem.ActionValue.Is("b"); model.Bank.Entries[1].ActionItem.NextBank.Is(""); // f(down)のまま g(down) を送出する model.SetEvent(new KeyboardHookedEventArgs( KeyboardMessage.KeyDown, ref ksG)); // この時に SendWait("r") が実行済みでなければならない。 dsc.EventLog.Count.Is(1); dsc.EventLog[0].Type.Is(DummySendKeyCode.EventType.SendWait); dsc.EventLog[0].Value.Is("r"); // 当然、LoadBank も完了済みでなければならない。 model.Bank.Name.Is(""); model.Bank.Entries.Count.Is(2); // 自分で出した r を受け取ってしまう。 model.SetEvent(new KeyboardHookedEventArgs( KeyboardMessage.KeyDown, ref ksR)); dsc.EventLog.Count.Is(1); model.SetEvent(new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref ksR)); dsc.EventLog.Count.Is(1); // g(up) と f(up) はどこかのタイミングで発生する。 // これらのいずれもキャンセルされなければならない。 var e1 = new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref ksG); model.SetEvent(e1); e1.Cancel.Is(true); dsc.EventLog.Count.Is(1); var e2 = new KeyboardHookedEventArgs( KeyboardMessage.KeyUp, ref ksF); model.SetEvent(e2); e2.Cancel.Is(true); dsc.EventLog.Count.Is(1); }
/// <summary> /// キーアップ時に呼ばれる /// 該当するキーの押下フラグをfalseにする /// また、マウス操作もキーアップをトリガーとして発動させるようにする /// </summary> /// <param name="e"> 離されたキー情報 </param> internal void KeyupEvent( KeyboardHookedEventArgs e ) { if( e.ExtraInfo != (int)Key.EXTRA_INFO ) { _enablekeyF[(byte)e.KeyCode] = false; _enablekeyE[(byte)e.KeyCode] = false; foreach( var m in this._mass.Mice.Where( m => !m.Push.Any( k => !_enablekeyE[k] && k != (byte)e.KeyCode ) ) ) { if( this._mouseTask?.Status == TaskStatus.Running ) { if( Properties.Settings.Default.mouseReClick == 0 ) { return; } else { this._mouseTaskCancelToken.Cancel(); while( this._mouseTask?.Status == TaskStatus.Running ) { } } } //スイッチの状態によって、操作する/しないを判定する if( m.mouseData.SwitchState != SwitchingStyle.BOTH && m.mouseData.SwitchState != Client.SwitchState ) { continue; } this._mouseTaskCancelToken = new CancellationTokenSource(); this._mouseTask = Task.Run( () => { foreach( var send in m.mouseData.Value ) { if( this._mouseTaskCancelToken.Token.IsCancellationRequested ) { throw new TaskCanceledException(); } var x = Client.x + (int)Math.Round( send.x * Client.ratioW ); var y = Client.y + (int)Math.Round( send.y * Client.ratioH ); switch( send.op ) { case Operation.LEFT: Win32.Mouse.SetCursorPos( x, y ); Click.Left( x, y, send.sleepBetween ); break; case Operation.RIGHT: Win32.Mouse.SetCursorPos( x, y ); Click.Right( x, y, send.sleepBetween ); break; case Operation.MOVE: Win32.Mouse.SetCursorPos( x, y ); break; default: throw new ArgumentOutOfRangeException(); } if( this._mouseTaskCancelToken.Token.IsCancellationRequested ) { throw new TaskCanceledException(); } Thread.Sleep( send.sleepAfter ); } }, this._mouseTaskCancelToken.Token ); } } }
/// <summary> /// キーダウン時に呼ばれる /// EnablekeyFは関数のはじめに、 /// EnablekeyEは関数の終わりにそれぞれtrueに書き換えられる /// ここでは /// コマンドの呼び出し、 /// 連打切替の有効無効の切り替え、 /// 方向キーの記憶を行う /// </summary> /// <param name="e"> 押されたキー情報 </param> internal async void KeydownEvent( KeyboardHookedEventArgs e ) { var key = (byte)e.KeyCode; //このキー入力がどこから発行されたものか判定 if( e.ExtraInfo == (int)Key.EXTRA_INFO ) { //LORから switch( key ) { case (byte)Keys.Left: _frontDirection = (byte)Keys.Left; _backDirection = (byte)Keys.Right; break; case (byte)Keys.Right: _frontDirection = (byte)Keys.Right; _backDirection = (byte)Keys.Left; break; default: return; } } else { // キーボードから if( this._commandTask?.Status == TaskStatus.Running ) { //コマンド実行中で、 if( this._mass.Barrages.Any( b => b.Push.Contains( key ) && !b.Push.Any( k => !_enablekeyE[k] ) ) ) { //連打キーだった場合コマンドの終了待機 await this._commandTask; } if( this._mass.Commands.Any( c => CommandCheck( key, c.Push ) ) ) { //コマンドキーだった場合 return; } } } _enablekeyF[key] = true; //コマンド foreach( var c in this._mass.Commands.Where( c => CommandCheck( key, c.Push ) ) ) { this._commandTask = Task.Run( () => ThreadCommand( c.sendList, _frontDirection, _backDirection ) ); break; } // ReSharper disable once SwitchStatementMissingSomeCases switch( key ) { case (byte)Keys.Left: _frontDirection = (byte)Keys.Left; _backDirection = (byte)Keys.Right; break; case (byte)Keys.Right: _frontDirection = (byte)Keys.Right; _backDirection = (byte)Keys.Left; break; } //切替 foreach( var t in this._mass.Toggles.Where( t => CommandCheck( key, t.Push ) ) ) { //not typo this._mass.ChangeEnable( t.Id, t.Enable = this._enableToggle[t.Id] = !this._enableToggle[t.Id] ); DIconUpdate(); } _enablekeyE[key] = true; }
/// <summary> /// キーフックイベント /// フックしたキーをjobの各メソッドに振り分ける /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void KeyHookEvent(object sender, KeyboardHookedEventArgs e) { #if DEBUG this._sw.Start(); #endif if (this._otherWindowOpen) { #if DEBUG goto echo; #else return; #endif } if (this._job.ActiveWindow && this._job.BarrageEnable && e.ExtraInfo != (int)Key.EXTRA_INFO) { if (CurrentSettingFile.CancelList.Contains((byte)e.KeyCode)) { e.Cancel = true; } } switch (e.UpDown) { case KeyboardUpDown.DOWN: if (this._job.ActiveWindow && this._job.BarrageEnable) { //キーダウンイベント Task.Run(() => this._job.KeydownEvent(e)); } break; case KeyboardUpDown.UP: if (this._job.ActiveWindow && this._job.BarrageEnable) { //キーアップイベント Task.Run(() => this._job.KeyupEvent(e)); } if (e.ExtraInfo != (int)Key.EXTRA_INFO) { //setting change hot key if (this._hotKeys.ContainsKey((byte)e.KeyCode)) { CurrentSettingName = this._hotKeys[(byte)e.KeyCode]; #if DEBUG goto echo; #else return; #endif } if ((byte)e.KeyCode == Properties.Settings.Default.hotKeyLorSwitching) { this._job.BarrageEnable = !this._job.BarrageEnable; } } break; default: throw new ArgumentOutOfRangeException(); } #if DEBUG echo: this._sw.Stop(); if (this._sw.Elapsed.TotalMilliseconds > 0.05) { Console.WriteLine(this._sw.Elapsed.TotalMilliseconds + ":" + KeysToText((byte)e.KeyCode) + "," + e.UpDown); } this._sw.Reset(); #endif }