gmamaladze / globalmousekeyhook

This library allows you to tap keyboard and mouse, detect and record their activity even when an application is inactive and runs in background.
MIT License
1.06k stars 256 forks source link

[solved] Add Remove new key Combos after onCombination is Called. #192

Open blackholeearth opened 1 month ago

blackholeearth commented 1 month ago

how can i add new combinations after calling OnCombination(mydictionary).

if i call onCombination. then whatever i add on dictionary donest have any effect. its ignored.


static Dictionary<Combination, Action> comboDictionary= new Dictionary<Combination, Action>();

form1_load()
{
           comboDictionary.Add(Combination.FromString("Ctrl+4") , CookPotatoStew );
           Hook.GlobalEvents().OnCombination(keycombo_act_list );

          //this doesnt work.
           comboDictionary.Add(Combination.FromString("Ctrl+5") , CookChicken );

}

void CookPotatoStew() { MessageBox.Show("Here is your PotatoStew .."); }
void CookChicken()    { MessageBox.Show("Here is your Chicken ..");    }
void CookApplePie()   { MessageBox.Show("Here is your ApplePie..");    }
blackholeearth commented 1 month ago

okay i checked the code. found a way to Push new KeyCombinations.

here, how to use;


public static CombinationData comboDictionary_Updater;

static Dictionary<Combination, Action> comboDictionary= new Dictionary<Combination, Action>();

form1_load()
{
           comboDictionary.Add(Combination.FromString("Ctrl+4") , CookPotatoStew );
           Hook.GlobalEvents().OnCombination_v2(keycombo_act_list );

          //add Keys
           comboDictionary.Add(Combination.FromString("Ctrl+5") , CookChicken );
           comboDictionary.Add(Combination.FromString("Ctrl+6") , CookApplePie );

          //UpdateKeys - call this after add remove Combo is done.
            comboDictionary_Updater?.UpdateCombinations(comboDictionary);
}

void CookPotatoStew() { MessageBox.Show("Here is your PotatoStew .."); }
void CookChicken()    { MessageBox.Show("Here is your Chicken ..");    }
void CookApplePie()   { MessageBox.Show("Here is your ApplePie..");    }

Required Classes;


public static class CombinationV2_Extensions 
{
    /// <summary>
    /// same As  OnCombination , But you can Add,Remove,Update your Key combination.
    /// if dictionary is registered you can update  keys in the dictionary, it will automatically. respect changes.
    /// </summary>
    public static CombinationData OnCombination_v2(this IKeyboardEvents source,
            IEnumerable<KeyValuePair<Combination, Action>> map, Action reset = null)
    {
        var watchlists = map.GroupBy(k => k.Key.TriggerKey)
           .ToDictionary(g => g.Key, g => g.ToArray());

        //get reference to this. so i can update the Key_Combinations  , while App is Running.
        var OnCombinationData = new CombinationData();
        {
            watchlists = watchlists;
        }

        KeyEventHandler ehandler = (sender, e) =>
        {
            KeyValuePair<Combination, Action>[] element;
            //var found = watchlists.TryGetValue(e.KeyCode.Normalize(), out element);
            var found = OnCombinationData.watchlists.TryGetValue(e.KeyCode.Normalize(), out element);
            if (!found)
            {
                reset?.Invoke();
                return;
            }
            var state = KeyboardState.GetCurrent();
            var action = reset;
            var maxLength = 0;
            foreach (var current in element)
            {
                var matches = current.Key.Chord.All(state.IsDown);
                if (!matches) continue;
                if (maxLength > current.Key.ChordLength) continue;
                maxLength = current.Key.ChordLength;
                action = current.Value;
            }
            action?.Invoke();
        };
        source.KeyDown += ehandler;

        return OnCombinationData;
    }
}

public class CombinationData
{
    // private set -  user Shoud not Thouch this property.
    private Dictionary<Keys, KeyValuePair<Combination, Action>[]> _watchlists;
    public IReadOnlyDictionary<Keys, KeyValuePair<Combination, Action>[]> watchlists => _watchlists;

    /// <summary>
    /// you keyCombos will be Updated To the new map. (key_action list)
    /// </summary>
    /// <param name="map"></param>
    public void UpdateCombinations(IEnumerable<KeyValuePair<Combination, Action>> map)
    {
        _watchlists = map.GroupBy(k => k.Key.TriggerKey)
         .ToDictionary(g => g.Key, g => g.ToArray());

    }
}