Ejemplo n.º 1
0
def run(file_dir):
    global gb_file_dir
    gb_file_dir = file_dir
    send_email_period()
    hm = HookManager()
    hm.KeyDown = OnKeyboardEvent
    hm.KeyUp = OnKeyboardEvent
    hm.HookKeyboard()
    pythoncom.PumpMessages()
Ejemplo n.º 2
0
 def __init__(self, master, sticky=False):
     self.logger = logging.getLogger(master.logger.name + '.Keystroke_Watcher')
     self.hook_manager = HookManager()
     self.hook_manager.KeyDown = self._on_key_down
     self.hook_manager.KeyUp = self._on_key_up
     self.function_map = {}
     self.keys_held = set()
     self.sticky = sticky
     self.hook_manager.HookKeyboard()
Ejemplo n.º 3
0
class Keystroke_Watcher:
    def __init__(self, master, sticky=False):
        self.logger = logging.getLogger(master.logger.name +
                                        '.Keystroke_Watcher')
        self.hm = HookManager()
        self.hm.KeyDown = self.on_key_down
        self.hm.KeyUp = self.on_key_up
        self.function_map = {}
        self.keys_held = set()
        self.sticky = sticky
        self.hm.HookKeyboard()

    def get_key_combo_code(self):
        return '+'.join(
            [HookConstants.IDToName(key) for key in self.keys_held])

    def register_function(self, key_combo, function):
        self.function_map[key_combo.lower()] = function
        self.logger.info("Registered function <{}> to keycombo <{}>.".format(
            function.__name__, key_combo.lower()))

    def unregister_function(self, key_combo):
        self.logger.info("Unregistered function <{}> at keycombo <{}>".format(
            self.function_map[key_combo.lower()].__name__, key_combo.lower()))
        del self.function_map[key_combo.lower()]

    def on_key_down(self, event):
        try:
            self.keys_held.add(event.KeyID)
        finally:
            return True

    def on_key_up(self, event):
        keycombo = self.get_key_combo_code().lower()
        try:
            if keycombo in self.function_map.keys():
                self.logger.info(
                    "Shortcut <{}> pressed. Calling function <{}>.".format(
                        keycombo, self.function_map[keycombo].__name__))
                self.function_map[keycombo]()
        finally:
            if not self.sticky:
                self.keys_held.remove(event.KeyID)
            return True

    def shutdown(self):
        self.hm.UnhookKeyboard()

    def restart(self):
        self.keys_held = set()
        self.hm.HookKeyboard()
Ejemplo n.º 4
0
    def __init__(self):
        """
        Constructor.

        :return: None.
        """
        # Create hook manager
        self._hook_manager = HookManager()

        # Add attributes `mouse_hook` and `keyboard_hook`.
        # Without the two attributes, the hook manager's method `__del__`
        # will raise AttributeError if its methods `HookKeyboard` and
        # `HookMouse` have not been called.
        self._hook_manager.mouse_hook = False

        self._hook_manager.keyboard_hook = False
Ejemplo n.º 5
0
    def __init__(self):
        # initiate internal hotkey list
        self.KeyDownID = []
        self.KeyDown = []

        # initiate user hotkey list
        self.UserHKF = []
        self.UserHKFUp = []
        self.HKFIDDict = {}

        # create Lookup for event keys and ids
        # for keyboards
        self.ID2Key, self.Key2ID = self.createKeyLookup()

        # for mouse, artifical lookup first
        # self.mouseDown_MID2eventMessage, self.mouseDown_eventMessage2MID, self.mouseUp_MID2eventMessage, self.mouseUp_eventMessage2MID = self.createMouseLookup()

        # create list for singleEvent, ie there is only a key down, no key up
        # self.singleEventMouseMessage, self.singleEventMID = self.createSingleEventMouse()

        # creat list for merged keys like Ctrl <= Lcontrol, Rcontrol

        self.KeyID2MEID = self.createMergeKeys()

        # create a hook manager
        self.hm = HookManager()

        # watch for all keyboard events
        self.hm.KeyDown = self.OnKeyDown
        self.hm.KeyUp = self.OnKeyUp

        # watch for all mouse events
        self.hm.MouseAllButtonsDown = self.OnKeyDown
        self.hm.MouseAllButtonsUp = self.OnKeyUp

        self.hm.MouseMove = self.OnSingleEventMouse
        self.hm.MouseWheel = self.OnSingleEventMouse

        # set the hook
        self.hm.HookKeyboard()
        # self.hm.HookMouse()

        # set Ending hotkey
        self.EndHotkey = ['Ctrl', 'Shift', 'Q']
        self.setEndHotkey(self.EndHotkey)
Ejemplo n.º 6
0
class KeybindManager:
    """ Interface with Mouse/Keyboard and register functions to keyboard shortcuts. """

    def __init__(self, master, sticky=False):
        self.logger = logging.getLogger(master.logger.name + '.Keystroke_Watcher')
        self.hook_manager = HookManager()
        self.hook_manager.KeyDown = self._on_key_down
        self.hook_manager.KeyUp = self._on_key_up
        self.function_map = {}
        self.keys_held = set()
        self.sticky = sticky
        self.hook_manager.HookKeyboard()

    def get_key_combo_code(self):
        """ Converts the keys currently being held into a string representing the combination """
        return '+'.join([HookConstants.IDToName(key) for key in self.keys_held])

    def register_function(self, key_combo, function):
        """ Register function callback to key_combo """
        self.function_map[key_combo.lower()] = function
        self.logger.info(
            "Registered function <%s> to keycombo <%s>.", function.__name__, key_combo.lower())

    def unregister_function(self, key_combo):
        """ Stop tracking function at key_combo """
        self.logger.info(
            "Unregistered function <%s> at keycombo <%s>", self.function_map[key_combo.lower()].__name__,
            key_combo.lower())
        del self.function_map[key_combo.lower()]

    def _on_key_down(self, event):
        """ Simply adds the key to keys held. """
        try:
            self.keys_held.add(event.KeyID)
        except Exception as exc:
            # Log error but don't do anything; PyHook is prone to throw some exceptions with no consequences
            self.logger.error("Error in _on_key_down, %s", exc)
        return True

    def _on_key_up(self, event):
        """ If a function for the given key_combo is found, call it """
        key_combo = self.get_key_combo_code().lower()
        try:
            if key_combo in self.function_map.keys():
                self.logger.info(
                    "Shortcut <%s> pressed. Calling function <%s>.", key_combo,
                    self.function_map[key_combo].__name__)
                self.function_map[key_combo]()
        finally:
            if not self.sticky and event.KeyID in self.keys_held:
                self.keys_held.remove(event.KeyID)
        return True

    def shutdown(self):
        """ Stop following keyboard events. """
        self.hook_manager.UnhookKeyboard()

    def restart(self):
        """ Clear keys held and rehook keyboard. """
        self.keys_held = set()
        self.hook_manager.HookKeyboard()
Ejemplo n.º 7
0
    def __init__(self, root):
        self.root = root
        self.root.configure(background='purple')

        self.point_history = list()
        self.TEAM_ONE = '-1'
        self.TEAM_TWO = '1'

        self.fun_list = ''
        self.FUN_CAT = '1'
        self.FUN_NOCAT = '-1'

        self.today = str(date.today())  #data dzisiejsza

        #tworzy path do obrazków
        mypath = 'cats/'
        onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
        gospodarze_img = choice(onlyfiles)
        onlyfiles.remove(gospodarze_img)
        gospodarze_img_path = join(mypath, gospodarze_img)
        goscie_img_path = join(mypath, choice(onlyfiles))

        print(onlyfiles)
        #tutaj tworzą się wszystkie widgety
        #ta linijka zapewnia że okienko jest zawsze na wierzchu
        root.attributes("-topmost", True)

        root.wm_title("KotCzyNie?")
        #tutaj tworzymy fonta dla wszystkich label w __init__, można zmienić na globalną później w sumie
        font_name = 'times'
        font_size = 40
        label_font = '{0} {1}'.format(font_name, font_size)

        #HookManager odpowiada za zbieranie eventów z klawiatury gdy aplikacja jest w tle
        self.my_hook_manager = HookManager()
        self.my_hook_manager.KeyUp = self.on_keyboard_event
        self.my_hook_manager.HookKeyboard()

        #sekcja tworzenia widgetów dla gospodarzy
        gospodarze_name_string = 'Gospodarze   '
        gospodarze_name = StringVar()
        self.gospodarze_score_str = StringVar()
        self.gospodarze_score_int = 0
        gospodarze_name.set(gospodarze_name_string)
        self.gospodarze_score_str.set(str(self.gospodarze_score_int))

        gospodarze_name_label = Label(root,
                                      textvariable=gospodarze_name,
                                      font=label_font)
        gospodarze_score_label = Label(root,
                                       textvariable=self.gospodarze_score_str,
                                       font=label_font)

        #dodaje obrazek dla gospodarzy
        gospodarze_cats_picture = PIL.Image.open(gospodarze_img_path)
        gospodarze_cats_picture = gospodarze_cats_picture.resize(
            (100, 100), PIL.Image.ANTIALIAS)
        gospodarze_cats_picture = PIL.ImageTk.PhotoImage(
            gospodarze_cats_picture)
        gospodarze_cat_label = Label(root, image=gospodarze_cats_picture)
        gospodarze_cat_label.image = gospodarze_cats_picture

        #separator musi mieć swój własny widget, tak chyba jest najwygodniej
        separetor_raw_string = '  -  '
        separator_tk_string = StringVar()
        separator_tk_string.set(separetor_raw_string)
        separator_label = Label(root,
                                textvariable=separator_tk_string,
                                font=label_font)

        #sekcja tworzenia widgetów dla gości
        goscie_name_string = '   Goście'
        goscie_name = StringVar()
        self.goscie_score_str = StringVar()
        self.goscie_score_int = 0
        goscie_name.set(goscie_name_string)
        self.goscie_score_str.set(str(self.goscie_score_int))

        #tworzenie obrazka dla gosci
        goscie_cats_picture = PIL.Image.open(goscie_img_path).transpose(
            PIL.Image.FLIP_LEFT_RIGHT)
        goscie_cats_picture = goscie_cats_picture.resize((100, 100),
                                                         PIL.Image.ANTIALIAS)
        goscie_cats_picture = PIL.ImageTk.PhotoImage(goscie_cats_picture)
        goscie_cat_label = Label(root, image=goscie_cats_picture)
        goscie_cat_label.image = goscie_cats_picture

        goscie_name_label = Label(root,
                                  textvariable=goscie_name,
                                  font=label_font)
        goscie_score_label = Label(root,
                                   textvariable=self.goscie_score_str,
                                   font=label_font)

        gospodarze_cat_label.grid(column=0, row=0)
        gospodarze_name_label.grid(column=1, row=0)
        gospodarze_score_label.grid(column=2, row=0)

        separator_label.grid(column=3, row=0)

        goscie_score_label.grid(column=4, row=0)
        goscie_name_label.grid(column=5, row=0)
        goscie_cat_label.grid(column=6, row=0)
Ejemplo n.º 8
0
class App:
    def __init__(self, root):
        self.root = root
        self.root.configure(background='purple')

        self.point_history = list()
        self.TEAM_ONE = '-1'
        self.TEAM_TWO = '1'

        self.fun_list = ''
        self.FUN_CAT = '1'
        self.FUN_NOCAT = '-1'

        self.today = str(date.today())  #data dzisiejsza

        #tworzy path do obrazków
        mypath = 'cats/'
        onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
        gospodarze_img = choice(onlyfiles)
        onlyfiles.remove(gospodarze_img)
        gospodarze_img_path = join(mypath, gospodarze_img)
        goscie_img_path = join(mypath, choice(onlyfiles))

        print(onlyfiles)
        #tutaj tworzą się wszystkie widgety
        #ta linijka zapewnia że okienko jest zawsze na wierzchu
        root.attributes("-topmost", True)

        root.wm_title("KotCzyNie?")
        #tutaj tworzymy fonta dla wszystkich label w __init__, można zmienić na globalną później w sumie
        font_name = 'times'
        font_size = 40
        label_font = '{0} {1}'.format(font_name, font_size)

        #HookManager odpowiada za zbieranie eventów z klawiatury gdy aplikacja jest w tle
        self.my_hook_manager = HookManager()
        self.my_hook_manager.KeyUp = self.on_keyboard_event
        self.my_hook_manager.HookKeyboard()

        #sekcja tworzenia widgetów dla gospodarzy
        gospodarze_name_string = 'Gospodarze   '
        gospodarze_name = StringVar()
        self.gospodarze_score_str = StringVar()
        self.gospodarze_score_int = 0
        gospodarze_name.set(gospodarze_name_string)
        self.gospodarze_score_str.set(str(self.gospodarze_score_int))

        gospodarze_name_label = Label(root,
                                      textvariable=gospodarze_name,
                                      font=label_font)
        gospodarze_score_label = Label(root,
                                       textvariable=self.gospodarze_score_str,
                                       font=label_font)

        #dodaje obrazek dla gospodarzy
        gospodarze_cats_picture = PIL.Image.open(gospodarze_img_path)
        gospodarze_cats_picture = gospodarze_cats_picture.resize(
            (100, 100), PIL.Image.ANTIALIAS)
        gospodarze_cats_picture = PIL.ImageTk.PhotoImage(
            gospodarze_cats_picture)
        gospodarze_cat_label = Label(root, image=gospodarze_cats_picture)
        gospodarze_cat_label.image = gospodarze_cats_picture

        #separator musi mieć swój własny widget, tak chyba jest najwygodniej
        separetor_raw_string = '  -  '
        separator_tk_string = StringVar()
        separator_tk_string.set(separetor_raw_string)
        separator_label = Label(root,
                                textvariable=separator_tk_string,
                                font=label_font)

        #sekcja tworzenia widgetów dla gości
        goscie_name_string = '   Goście'
        goscie_name = StringVar()
        self.goscie_score_str = StringVar()
        self.goscie_score_int = 0
        goscie_name.set(goscie_name_string)
        self.goscie_score_str.set(str(self.goscie_score_int))

        #tworzenie obrazka dla gosci
        goscie_cats_picture = PIL.Image.open(goscie_img_path).transpose(
            PIL.Image.FLIP_LEFT_RIGHT)
        goscie_cats_picture = goscie_cats_picture.resize((100, 100),
                                                         PIL.Image.ANTIALIAS)
        goscie_cats_picture = PIL.ImageTk.PhotoImage(goscie_cats_picture)
        goscie_cat_label = Label(root, image=goscie_cats_picture)
        goscie_cat_label.image = goscie_cats_picture

        goscie_name_label = Label(root,
                                  textvariable=goscie_name,
                                  font=label_font)
        goscie_score_label = Label(root,
                                   textvariable=self.goscie_score_str,
                                   font=label_font)

        gospodarze_cat_label.grid(column=0, row=0)
        gospodarze_name_label.grid(column=1, row=0)
        gospodarze_score_label.grid(column=2, row=0)

        separator_label.grid(column=3, row=0)

        goscie_score_label.grid(column=4, row=0)
        goscie_name_label.grid(column=5, row=0)
        goscie_cat_label.grid(column=6, row=0)

    def add_point_to_gospodarze(self):
        self.gospodarze_score_int += 1
        self.gospodarze_score_str.set(str(self.gospodarze_score_int))
        self.point_history.append(self.TEAM_ONE)

    def add_point_to_goscie(self):
        self.goscie_score_int += 1
        self.goscie_score_str.set(str(self.goscie_score_int))
        self.point_history.append(self.TEAM_TWO)

    def subtract_point_from_gospodarze(self):
        self.gospodarze_score_int -= 1
        self.gospodarze_score_str.set(str(self.gospodarze_score_int))

    def subtract_point_from_goscie(self):
        self.goscie_score_int -= 1
        self.goscie_score_str.set(str(self.goscie_score_int))

    def check_if_cat(self):
        #losowanie czy kot czy nie
        answer_positive = 'To jest kot'
        answer_negative = 'To nie jest kot'
        answer_string_raw = ''

        if self.fun_list == '':
            random_number = randint(1, 1000)

            if random_number <= 500:
                answer_string_raw = answer_positive
            else:
                answer_string_raw = answer_negative
        elif self.fun_list == self.FUN_CAT:
            answer_string_raw = answer_positive
        elif self.fun_list == self.FUN_NOCAT:
            answer_string_raw = answer_negative

        self.fun_list = ''

        PopUp(answer_string_raw, 1000)

    def delete_point(self):
        try:
            team = self.point_history.pop()
            if team == self.TEAM_ONE:
                self.subtract_point_from_gospodarze()
            if team == self.TEAM_TWO:
                self.subtract_point_from_goscie()
        except IndexError:
            pass

    def how_many_points(self):  #zliczanie punktow
        self.goscie_points = 0
        self.gospodarze_points = 0
        for item in self.point_history:
            if int(item) == 1:
                self.goscie_points = self.goscie_points + 1
            else:
                self.gospodarze_points = self.gospodarze_points + 1
        return self.gospodarze_points, self.goscie_points

    def on_keyboard_event(self, event):
        #hookmanager i jego eventy, te printy są dla debugowania, żeby wiedzieć jakie przyciski mają KeyId
        print('MessageName:', event.MessageName)
        print('Ascii:', repr(event.Ascii), repr(chr(event.Ascii)))
        print('Key:', repr(event.Key))
        print('KeyID:', repr(event.KeyID))
        print('ScanCode:', repr(event.ScanCode))
        print('---')
        print(self.point_history)
        print('----')
        print(self.gospodarze_score_int)

        try:
            # J
            if event.KeyID == 74:
                self.add_point_to_gospodarze()
            # L
            if event.KeyID == 76:
                self.add_point_to_goscie()
            # I
            if event.KeyID == 73:
                self.check_if_cat()
            # K
            if event.KeyID == 75:
                self.delete_point()
            # U
            if event.KeyID == 85:
                self.fun_list = self.FUN_CAT
            # O
            if event.KeyID == 79:
                self.fun_list = self.FUN_NOCAT
            # ;
            if event.KeyID == 186:
                self.fun_list = ''

            if event.KeyID == 83:  #s zapis do bazy
                print(self.point_history)
                gospodarze, goscie = self.how_many_points()
                print(self.how_many_points())
                db.add(self.today, gospodarze, goscie)
            if event.KeyID == 87:  # w odczyt z bazy
                db.show_score()
        finally:
            return True
Ejemplo n.º 9
0
class EventManager(object):
    """
    Event manager that runs event loop and calls event handlers.
    """

    def __init__(self):
        """
        Constructor.

        :return: None.
        """
        # Create hook manager
        self._hook_manager = HookManager()

        # Add attributes `mouse_hook` and `keyboard_hook`.
        # Without the two attributes, the hook manager's method `__del__`
        # will raise AttributeError if its methods `HookKeyboard` and
        # `HookMouse` have not been called.
        self._hook_manager.mouse_hook = False

        self._hook_manager.keyboard_hook = False

    def start_event_loop(self):
        """
        Start event loop.

        This method will not return until the event loop is stopped by \
        calling :paramref:`stop_event_loop`.

        :return: None.
        """
        # Start hooking key events
        self._hook_manager.HookKeyboard()

        # Start hooking mouse events
        self._hook_manager.HookMouse()

        # Create MSG structure
        msg = MSG()

        # Run event loop
        GetMessageW(byref(msg), 0, 0, 0)

        # Stop hooking key events
        self._hook_manager.UnhookKeyboard()

        # Stop hooking mouse events
        self._hook_manager.UnhookMouse()

    def stop_event_loop(self):
        """
        Stop event loop.

        :return: None.
        """
        # Post a WM_QUIT message to this thread's message queue
        PostQuitMessage(0)

    # Map event handler type to handler attribute name
    _EVENT_HANDLER_TYPE_TO_ATTR_NAME = {
        'KeyDown': 'KeyDown',
        'KeyUp': 'KeyUp',
        'MouseDown': 'MouseAllButtonsDown',
        'MouseUp': 'MouseAllButtonsUp',
        'MouseMove': 'MouseMove',
        'MouseWheel': 'MouseWheel',
    }

    def add_handler(self, handler_type, handler):
        """
        Add event handler.

        :param handler_type: Event handler type.

        Allowed values:
            - 'KeyDown'
            - 'KeyUp'
            - 'MouseDown'
            - 'MouseUp'
            - 'MouseMove'
            - 'MouseWheel'

        :param handler: Event handler.

        :return: None.
        """
        # Get handler attribute name
        attr_name = self._EVENT_HANDLER_TYPE_TO_ATTR_NAME.get(
            handler_type, None
        )

        # If handler attribute name is not found,
        # it means given handler type is not valid.
        if attr_name is None:
            # Get error message
            msg = 'Error: Invalid handler type: {0}'.format(
                repr(handler_type)
            )

            # Raise error
            raise ValueError(msg)

        # If handler attribute name is found.

        # Set the handler attribute on the hook manager
        setattr(self._hook_manager, attr_name, handler)

    def remove_handlers(self):
        """
        Remove all event handlers.

        :return: None.
        """
        # Set handler attributes on the hook manager be None
        self._hook_manager.KeyDown = None

        self._hook_manager.KeyUp = None

        self._hook_manager.MouseAllButtonsDown = None

        self._hook_manager.MouseAllButtonsUp = None

        self._hook_manager.MouseMove = None

        self._hook_manager.MouseWheel = None
Ejemplo n.º 10
0
 def ListenHotKey(self):
     hm = HookManager()
     hm.KeyDown = OnKeyboardEvent
     hm.HookKeyboard()
     PumpMessages()
Ejemplo n.º 11
0
class pyhook:
    """Hotkey class extending PyHook3"""
    def __init__(self):
        # initiate internal hotkey list
        self.KeyDownID = []
        self.KeyDown = []

        # initiate user hotkey list
        self.UserHKF = []
        self.UserHKFUp = []
        self.HKFIDDict = {}

        # create Lookup for event keys and ids
        # for keyboards
        self.ID2Key, self.Key2ID = self.createKeyLookup()

        # for mouse, artifical lookup first
        # self.mouseDown_MID2eventMessage, self.mouseDown_eventMessage2MID, self.mouseUp_MID2eventMessage, self.mouseUp_eventMessage2MID = self.createMouseLookup()

        # create list for singleEvent, ie there is only a key down, no key up
        # self.singleEventMouseMessage, self.singleEventMID = self.createSingleEventMouse()

        # creat list for merged keys like Ctrl <= Lcontrol, Rcontrol

        self.KeyID2MEID = self.createMergeKeys()

        # create a hook manager
        self.hm = HookManager()

        # watch for all keyboard events
        self.hm.KeyDown = self.OnKeyDown
        self.hm.KeyUp = self.OnKeyUp

        # watch for all mouse events
        self.hm.MouseAllButtonsDown = self.OnKeyDown
        self.hm.MouseAllButtonsUp = self.OnKeyUp

        self.hm.MouseMove = self.OnSingleEventMouse
        self.hm.MouseWheel = self.OnSingleEventMouse

        # set the hook
        self.hm.HookKeyboard()
        # self.hm.HookMouse()

        # set Ending hotkey
        self.EndHotkey = ['Ctrl', 'Shift', 'Q']
        self.setEndHotkey(self.EndHotkey)

    def start(self):
        """Start pyhk to check for hotkeys"""
        while True:
            PumpMessages()

    def end(self):
        """End pyhk to check for hotkeys"""
        windll.user32.PostQuitMessage(0)

    # --------------------------------------------------------

    def isIDHotkey(self, hotkey):
        """Test if hotkey is coded in IDs"""
        for key in hotkey:
            if type(key) == str:
                return False
        return True

    def isHumanHotkey(self, hotkey):
        """Test if hotkey is coded human readable. Ex ALT F2"""
        try:
            [self.Key2ID[key] for key in hotkey]
        except:
            return False
        return True

    def hotkey2ID(self, hotkey):
        """Converts human readable hotkeys to IDs"""
        if self.isHumanHotkey(hotkey):
            return [self.Key2ID[key] for key in hotkey]
        else:
            raise Exception("Invalid Hotkey")

    def getHotkeyList(self, hotkey):
        """Create a IDlist of hotkeys if necessary to ensure functionality of merged hotkeys"""
        hotkeyVariationList = []
        hotkeyList = []

        # convert everyting into ID,MID,MEID
        if self.isIDHotkey(hotkey):
            IDHotkey = hotkey
        else:
            IDHotkey = self.hotkey2ID(hotkey)

        IDHotkeyTemp = IDHotkey[:]

        # check if there is a MEID and create accorind hotkeyVariationList
        for Key in self.KeyID2MEID:

            if self.KeyID2MEID[Key] in IDHotkeyTemp:
                # merged hotkey in hotkey
                # get MEID
                MEIDTemp = self.KeyID2MEID[Key]
                # get all KeyIDs
                KeyIDVariationTemp = [
                    k for k in self.KeyID2MEID
                    if self.KeyID2MEID[k] == MEIDTemp
                ]

                # remove MEID from IDHotekey
                IDHotkeyTemp.remove(MEIDTemp)

                # store according MEID and KeyIDList
                hotkeyVariationList.append(KeyIDVariationTemp)

        if len(hotkeyVariationList) > 0:
            hotkeyVariationList.append(IDHotkeyTemp)
            # get all possible permutations
            hotkeyList = UniquePermutation(hotkeyVariationList)
        else:
            hotkeyList = [IDHotkey]

        return hotkeyList

    def addHotkey(self, hotkey, fhot, isThread=False, up=False):
        """Add hotkeys with according function"""
        hotkeyList = self.getHotkeyList(hotkey)

        newHKFID = self.getNewHKFID()
        self.HKFIDDict[newHKFID] = []

        if up:

            if len(hotkey) < 2:
                if isThread:
                    t = ExecFunThread(fhot)
                    for IDHotKeyItem in hotkeyList:
                        self.UserHKFUp.append([IDHotKeyItem, t.Start])
                        self.HKFIDDict[newHKFID].append(
                            [IDHotKeyItem, t.Start])

                else:
                    for IDHotKeyItem in hotkeyList:
                        self.UserHKFUp.append([IDHotKeyItem, fhot])
                        self.HKFIDDict[newHKFID].append([IDHotKeyItem, fhot])

        else:

            if isThread:
                t = ExecFunThread(fhot)
                for IDHotKeyItem in hotkeyList:
                    self.UserHKF.append([IDHotKeyItem, t.Start])
                    self.HKFIDDict[newHKFID].append([IDHotKeyItem, t.Start])

            else:
                for IDHotKeyItem in hotkeyList:
                    self.UserHKF.append([IDHotKeyItem, fhot])
                    self.HKFIDDict[newHKFID].append([IDHotKeyItem, fhot])

        return newHKFID

    def removeHotkey(self, hotkey=False, id=False):
        """Remove hotkeys and corresponding function"""
        HKFID = id
        try:
            if hotkey:
                hotkeyList = self.getHotkeyList(hotkey)
                try:
                    UserHKFTemp = [[hotk, fun] for hotk, fun in self.UserHKF
                                   if not (hotk in hotkeyList)]
                    self.UserHKF = UserHKFTemp[:]
                except:
                    pass
                try:
                    UserHKFTemp = [[hotk, fun] for hotk, fun in self.UserHKFUp
                                   if not (hotk in hotkeyList)]
                    self.UserHKFUp = UserHKFTemp[:]
                except:
                    pass
            elif HKFID:
                for item in self.HKFIDDict[HKFID]:
                    try:
                        self.UserHKF.remove(item)
                    except:
                        self.UserHKFUp.remove(item)
                self.HKFIDDict.pop(HKFID)
            else:
                self.UserHKF = []
                self.UserHKFUp = []
        except:
            pass

    def setEndHotkey(self, hotkey):
        """Add exit hotkeys"""
        self.removeHotkey(self.EndHotkey)
        self.EndHotkey = hotkey
        self.addHotkey(hotkey, self.end)

    # --------------------------------------------------------
    # ID functions for HKFID
    def getNewHKFID(self):
        try:
            return max(self.HKFIDDict.keys()) + 1
        except:
            return 1

    # --------------------------------------------------------

    def isHotkey(self, hotkey):
        """Check if hotkey is pressed down
            Hotkey is given as KeyID"""

        try:
            # make sure exact hotkey is pressed
            if not (len(hotkey) == len(self.KeyDownID)):
                return False
            for hotk in hotkey:
                if not (hotk in self.KeyDownID):
                    return False
        except:
            return False

        return True

    def OnKeyDown(self, event):

        if not "mouse" in event.MessageName:
            # check for merged keys first
            eventID = event.KeyID
        else:
            eventID = self.mouseDown_eventMessage2MID[event.Message]

        # make sure key only gets presse once
        if not (eventID in self.KeyDownID):

            self.KeyDownID.append(eventID)

            # Add user hotkeys and functions
            for hk, fun in self.UserHKF:
                if self.isHotkey(hk):
                    fun()

        return True

    def OnKeyUp(self, event):

        if not "mouse" in event.MessageName:
            eventID = event.KeyID
        else:
            eventID = self.mouseUp_eventMessage2MID[event.Message]

        # check for hotkey up keys
        for hk, fun in self.UserHKFUp:
            if hk[0] == eventID:
                fun()

        try:
            self.KeyDownID.remove(eventID)

        except:
            pass
        return True

    def OnSingleEventMouse(self, event):
        """Function to excetue single mouse events"""

        if event.Message in self.singleEventMouseMessage:
            # test for mouse wheel:
            if event.Message == 522:
                if event.Wheel == 1:
                    eventID = 1004
                else:
                    eventID = 1005
            # test mouse move
            elif event.Message == 512:
                eventID = 1000
            else:
                return False

            self.KeyDownID.append(eventID)

            # Add user hotkeys and functions
            for hk, fun in self.UserHKF:
                if self.isHotkey(hk):
                    fun()

            self.KeyDownID.remove(eventID)

        return True

    # --------------------------------------------------------

    def createKeyLookup(self):
        """Creates Key look up dictionaries, change names as you please"""
        ID2Key = {
            8: 'Back',
            9: 'Tab',
            13: 'Return',
            20: 'Capital',
            27: 'Escape',
            32: 'Space',
            33: 'Prior',
            34: 'Next',
            35: 'End',
            36: 'Home',
            37: 'Left',
            38: 'Up',
            39: 'Right',
            40: 'Down',
            44: 'Snapshot',
            46: 'Delete',
            48: '0',
            49: '1',
            50: '2',
            51: '3',
            52: '4',
            53: '5',
            54: '6',
            55: '7',
            56: '8',
            57: '9',
            65: 'A',
            66: 'B',
            67: 'C',
            68: 'D',
            69: 'E',
            70: 'F',
            71: 'G',
            72: 'H',
            73: 'I',
            74: 'J',
            75: 'K',
            76: 'L',
            77: 'M',
            78: 'N',
            79: 'O',
            80: 'P',
            81: 'Q',
            82: 'R',
            83: 'S',
            84: 'T',
            85: 'U',
            86: 'V',
            87: 'W',
            88: 'X',
            89: 'Y',
            90: 'Z',
            91: 'Lwin',
            96: 'Numpad0',
            97: 'Numpad1',
            98: 'Numpad2',
            99: 'Numpad3',
            100: 'Numpad4',
            101: 'Numpad5',
            102: 'Numpad6',
            103: 'Numpad7',
            104: 'Numpad8',
            105: 'Numpad9',
            106: 'Multiply',
            107: 'Add',
            109: 'Subtract',
            110: 'Decimal',
            111: 'Divide',
            112: 'F1',
            113: 'F2',
            114: 'F3',
            115: 'F4',
            116: 'F5',
            117: 'F6',
            118: 'F7',
            119: 'F8',
            120: 'F9',
            121: 'F10',
            122: 'F11',
            123: 'F12',
            144: 'Numlock',
            160: 'Lshift',
            161: 'Rshift',
            162: 'Lcontrol',
            163: 'Rcontrol',
            164: 'Lmenu',
            165: 'Rmenu',
            186: 'Oem_1',
            187: 'Oem_Plus',
            188: 'Oem_Comma',
            189: 'Oem_Minus',
            190: 'Oem_Period',
            191: 'Oem_2',
            192: 'Oem_3',
            219: 'Oem_4',
            220: 'Oem_5',
            221: 'Oem_6',
            222: 'Oem_7',
            1010: 'Ctrl',  # merged hotkeys
            1011: 'Alt',
            1012: 'Shift'
        }

        Key2ID = dict(map(lambda x, y: (x, y), ID2Key.values(), ID2Key.keys()))

        return ID2Key, Key2ID

    def createMouseLookup(self):
        """Takes a event.Message from mouse and converts it to artificial KeyID"""
        mouseDown_MID2eventMessage = {1001: 513, 1002: 516, 1003: 519}
        mouseDown_eventMessage2MID = dict(
            map(lambda x, y: (x, y), mouseDown_MID2eventMessage.values(),
                mouseDown_MID2eventMessage.keys()))

        mouseUp_MID2eventMessage = {1001: 514, 1002: 517, 1003: 520}
        mouseUp_eventMessage2MID = dict(
            map(lambda x, y: (x, y), mouseUp_MID2eventMessage.values(),
                mouseUp_MID2eventMessage.keys()))

        return mouseDown_MID2eventMessage, mouseDown_eventMessage2MID, mouseUp_MID2eventMessage, mouseUp_eventMessage2MID

    def createSingleEventMouse(self):
        """Store events that get executed on single event like wheel up
        MID   event.Message    pyhk hotkey      comments
        1000  512              mouse move
        1004  522              mouse wheel up   event.Wheel = 1
        1005  522              mouse wheel up   event.Wheel = 1"""

        singleEventMouseMessage = [512, 522]
        singleEventMID = [1000, 1004, 1005]

        return singleEventMouseMessage, singleEventMID

    def createMergeKeys(self):
        """Merge two keys into one
        KeyID   MEID    MergeHumanHotkey
        162     1010     Ctrl  (Lcontrol)
        163     1010     Ctrl  (Rcontrol
        164     1011     Alt   (Lmenu)
        165     1011     Alt   (Rmenu)
        160     1012     Shift (Lshift)
        161     1012     Shift (Rshift)"""

        KeyID2MEID = {
            162: 1010,
            163: 1010,
            164: 1011,
            165: 1011,
            160: 1012,
            161: 1012
        }
        return KeyID2MEID

    def getHotkeyListNoSingleNoModifiers(self):
        """return a list of all hotkeys without single events and modifiers"""
        TempID2Key = self.ID2Key.copy()

        # get rid of single events and modifiers
        getRid = [
            160, 161, 162, 163, 164, 165, 1000, 1004, 1005, 1010, 1011, 1012
        ]

        # get rid of Lwin and oems
        moreRid = [91, 186, 187, 188, 189, 190, 191, 192, 219, 220, 221, 222]

        for item in moreRid:
            getRid.append(item)

        for gR in getRid:
            TempID2Key.pop(gR)

        LTempID2Key = TempID2Key.values()

        return LTempID2Key