public override void Enter(KBHandler k) { timedelay = new TimeSpan(); if (State <KBUnpressed> .ReferenceEquals(k.kbsm.prevstate, KBUnpressed.Instance)) {//coming from unpressed, need to do processing //if entering this state always reset time and focus key k.focuskey = Keys.None; //get keylist, strip out ctrl,alt,shift,unmanaged keys then send events k.lastlist = k.CurKB.GetPressedKeys(); k.lastmodbits = KBHelper.GetModifiers(k.CurKB); KBHandler.Strip(ref k.lastlist, k); if (k.lastlist.Length == 0) { k.CallHandleKBKeyDown(k.lastlist, Keys.None, k.lastmodbits); } foreach (Keys kevent in k.lastlist) {//send event for each key (focus being different for each key) k.CallHandleKBKeyDown(k.lastlist, kevent, k.lastmodbits); //focus key will always be the last one processed k.focuskey = kevent; } } else {//the other state has done the processing so just need to do the down event foreach (Keys newkey in k.newfoundkeys) { k.CallHandleKBKeyDown(k.newlist, newkey, k.newmodbits); k.focuskey = newkey; } } }
/// <summary> /// strip a keylist of unmanaged keys and ctrl,alt,shifts, returning a new array /// </summary> /// <param name="klist">key list to strip unmanaged keys from</param> /// <param name="k">keyboard handler object</param> /// <returns>array with keys stripped (new memory array if unmanaged key list has items or removemodifiersfromkeylist is true)</returns> private static void Strip(ref Keys[] klist, KBHandler k) { //return original array reference if nothing in the unmanaged list if (k.unmanaged.Count == 0 && k.removemodifiersfromkeylist == false) { return; } int a; int b = 0; for (a = 0; a < klist.Length; a++) { if (!((k.removemodifiersfromkeylist == true && KBHelper.IsMod(klist[a])) || k.unmanaged.Contains(klist[a]))) {//if not modifier and not in unmanaged list then copy the value to next valid part in array, otherwise skip over(a will advance, b will stay the same and then next time the modiffier/unmanaged key will be overwritten by a good key) klist[b] = klist[a]; b++; } } if (b < a) { Keys[] newlist = new Keys[b]; for (int j = 0; j < b; j++) { newlist[j] = klist[j]; } klist = newlist; } }
/// <summary> /// returns whether this key is a "modifier" key i.e. control, shift or alt /// </summary> public static bool IsMod(Keys k) { return(KBHelper.IsShift(k) || KBHelper.IsAlt(k) || KBHelper.IsCtrl(k)); }
public override void Execute(KBHandler k) { k.newfoundkeys.Clear(); k.newlist = k.CurKB.GetPressedKeys(); if (k.newlist.Length == 0) {//nothing pressed, change state back to unpressed k.kbsm.ChangeState(KBUnpressed.Instance); return; } k.newmodbits = KBHelper.GetModifiers(k.CurKB); KBHandler.Strip(ref k.newlist, k); //see if list is same if (!KBHandler.FindNewKeys(k.lastlist, k.newlist, k.newfoundkeys)) { //a key was released but keys are still down k.kbsm.ChangeState(KBKeyLost.Instance); } else { if (k.newfoundkeys.Count == 0) { //no keys changed, need to compare modifiers now to see if any events if (k.newmodbits != k.lastmodbits) {//something's changed KBModifiers testmodbits; testmodbits = k.newmodbits & k.lastmodbits; //if we remain in this state in this portion of code, focus key will be none k.focuskey = Keys.None; if (testmodbits == KBModifiers.None) { //changed completely, send a keyboard down k.kbsm.ChangeState(KBKeyDown.Instance); } else if ((testmodbits & k.newmodbits) == (testmodbits & k.lastmodbits)) { //had one key the same but other two were different, send keyboard down k.kbsm.ChangeState(KBKeyDown.Instance); } else if ((testmodbits & k.newmodbits) == testmodbits) { //new mod bits only had 1, which means it lost one, change to lost state k.kbsm.ChangeState(KBKeyLost.Instance); } else if ((testmodbits & k.lastmodbits) == testmodbits) { //old mod bits is less, send down event k.kbsm.ChangeState(KBKeyDown.Instance); } else { throw new System.Exception("code error, unhandled mod key state"); } } else { //nothing at all changed, send a key repeat event (note - repeat time is detected in kbkeydown, so no need to keep track of time) repeatrunning -= k.lastpolltime.ElapsedRealTime.TotalMilliseconds; if (repeatrunning < 0) { k.CallHandleKBKeyRepeat(k.focuskey, k.lastmodbits); repeatrunning = k.repeatfrequency; } } } else {//new keys were found, change to keyboard down k.kbsm.ChangeState(KBKeyDown.Instance); } } //update last list and mod bits k.lastlist = k.newlist; k.lastmodbits = k.newmodbits; }
public override void Execute(KBHandler k) { k.newfoundkeys.Clear(); k.newlist = k.CurKB.GetPressedKeys(); if (k.newlist.Length == 0) {//nothing pressed, change state back to unpressed k.kbsm.ChangeState(KBUnpressed.Instance); return; } k.newmodbits = KBHelper.GetModifiers(k.CurKB); //strip modifiers and unmanaged keys KBHandler.Strip(ref k.newlist, k); //see if list is same if (!KBHandler.FindNewKeys(k.lastlist, k.newlist, k.newfoundkeys)) { //a key was released but keys are still down k.kbsm.ChangeState(KBKeyLost.Instance); } else { if (k.newfoundkeys.Count == 0) { //no keys changed, need to compare modifiers now to see if any events if (k.newmodbits != k.lastmodbits) {//something's changed KBModifiers testmodbits; testmodbits = k.newmodbits & k.lastmodbits; //if we remain in this state in this portion of code, focus key will be none k.focuskey = Keys.None; //since a change has happened make a new timespan timedelay = new TimeSpan(); if (testmodbits == KBModifiers.None) { //changed completely, send a keyboard down k.CallHandleKBKeyDown(k.newlist, Keys.None, k.newmodbits); } else if ((testmodbits & k.newmodbits) == (testmodbits & k.lastmodbits)) { //TODO dummy this will return true all the time //had one key the same but other two were different, send keyboard down k.CallHandleKBKeyDown(k.newlist, Keys.None, k.newmodbits); } else if ((testmodbits & k.newmodbits) == testmodbits) { //new mod bits only had 1, which means it lost one, change to lost state k.kbsm.ChangeState(KBKeyLost.Instance); } else if ((testmodbits & k.lastmodbits) == testmodbits) { //old mod bits is less, send down event k.CallHandleKBKeyDown(k.newlist, Keys.None, k.newmodbits); } else { throw new System.Exception("code error, unhandled mod key state"); } } else { if (k.focuskey != Keys.None) {//nothing at all changed and the focus key is a real key, increase time for repeat purposes timedelay += k.lastpolltime.ElapsedRealTime; if (timedelay.TotalMilliseconds > k.repeatdelay) { k.kbsm.ChangeState(KBKeyRepeat.Instance); } } } } else {//new keys were found, send a down event for each key foreach (Keys newkey in k.newfoundkeys) { k.CallHandleKBKeyDown(k.newlist, newkey, k.newmodbits); k.focuskey = newkey; timedelay = new TimeSpan(); } } } //update last list and mod bits k.lastlist = k.newlist; k.lastmodbits = k.newmodbits; }