def _hook(): global hm hm = pyHook.HookManager() hm.KeyDown = _hhook hm.HookKeyboard() PumpMessages()
def _show_toast(self, title, msg, icon_path, duration, callback_on_click): """Notification settings. :title: notification title :msg: notification message :icon_path: path to the .ico file to custom notification :duration: delay in seconds before notification self-destruction, None for no-self-destruction """ # Register the window class. self.wc = WNDCLASS() self.hinst = self.wc.hInstance = GetModuleHandle(None) self.wc.lpszClassName = str("PythonTaskbar") # must be a string self.wc.lpfnWndProc = self._decorator(self.wnd_proc, callback_on_click) # could instead specify simple mapping try: self.classAtom = RegisterClass(self.wc) except (TypeError, Exception): pass # not sure of this style = WS_OVERLAPPED | WS_SYSMENU self.hwnd = CreateWindow(self.classAtom, "Taskbar", style, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, self.hinst, None) UpdateWindow(self.hwnd) # icon if icon_path is not None: icon_path = path.realpath(icon_path) else: icon_path = resource_filename(Requirement.parse("win10toast"), "win10toast/data/python.ico") icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE try: hicon = LoadImage(self.hinst, icon_path, IMAGE_ICON, 0, 0, icon_flags) except Exception as e: logging.error("Some trouble with the icon ({}): {}" .format(icon_path, e)) hicon = LoadIcon(0, IDI_APPLICATION) # Taskbar icon flags = NIF_ICON | NIF_MESSAGE | NIF_TIP nid = (self.hwnd, 0, flags, WM_USER + 20, hicon, "Tooltip") Shell_NotifyIcon(NIM_ADD, nid) Shell_NotifyIcon(NIM_MODIFY, (self.hwnd, 0, NIF_INFO, WM_USER + 20, hicon, "Balloon Tooltip", msg, 200, title)) PumpMessages() # take a rest then destroy if duration is not None: DestroyWindow(self.hwnd) sleep(duration) UnregisterClass(self.wc.lpszClassName, None) DestroyWindow(self.hwnd) UnregisterClass(self.wc.lpszClassName, None)
def _show_toast(self, title, msg, icon_path, duration, cbFunc=None, cbArgs=None): """Notification settings. :title: notification title :msg: notification message :icon_path: path to the .ico file to custom notification :duration: delay in seconds before notification self-destruction """ self.user_cbFunc = cbFunc self.user_cbArgs = cbArgs # Register the window class. self.wc = WNDCLASS() self.hinst = self.wc.hInstance = GetModuleHandle(None) self.wc.lpszClassName = str("PythonTaskbar" + os.urandom(24).hex()) # must be a string self.wc.lpfnWndProc = self._decorator( self.wnd_proc, self.user_cbFunc) # could also specify a wndproc. try: self.classAtom = RegisterClass(self.wc) except: pass #not sure of this style = WS_OVERLAPPED | WS_SYSMENU self.hwnd = CreateWindow(self.classAtom, "Taskbar", style, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, self.hinst, None) UpdateWindow(self.hwnd) # icon hicon = None if icon_path is not None: icon_path = path.realpath(icon_path) icon_flags = LR_LOADFROMFILE try: hicon = LoadImage(self.hinst, icon_path, IMAGE_ICON, 0, 0, icon_flags) except Exception as e: logging.error("Some trouble with the icon ({}): {}".format( icon_path, e)) hicon = LoadIcon(0, IDI_APPLICATION) # Taskbar icon flags = NIF_ICON | NIF_MESSAGE | NIF_TIP nid = (self.hwnd, 0, flags, WM_USER + 20, hicon, "Tooltip") Shell_NotifyIcon(NIM_ADD, nid) Shell_NotifyIcon(NIM_MODIFY, (self.hwnd, 0, NIF_INFO, WM_USER + 20, hicon, "Balloon Tooltip", msg, 200, title)) PumpMessages() # take a rest then destroy sleep(duration) DestroyWindow(self.hwnd) UnregisterClass(self.wc.lpszClassName, None) return None
return True def switchRule(self): if (self.alreadyOn == False): self.alreadyOn = True os.system( 'netsh advfirewall firewall set rule name="ArmaLagg" new enable=no' ) os.system( 'netsh advfirewall firewall set rule name="Arma 3" new enable=yes' ) print("not active") else: self.alreadyOn = False os.system( 'netsh advfirewall firewall set rule name="ArmaLagg" new enable=yes' ) os.system( 'netsh advfirewall firewall set rule name="Arma 3" new enable=no' ) print("active") def generateRule(self): os.system( 'netsh advfirewall firewall add rule name="ArmaLagg" dir=out action=block program="' + input("Your Arma path:\n") + '" enable=no') watcher = Keystroke_Watcher() PumpMessages()
def _show_toast(self, title, msg, icon_path, duration, callback_on_click): '''Notification settings. :param title: notification title :param msg: notification message :param icon_path: path to the .ico file to custom notification :para mduration: delay in seconds before notification self-destruction, None for no-self-destruction ''' # Register the window class. self.wc = WNDCLASS() self.hinst = self.wc.hInstance = GetModuleHandle(None) # must be a string self.wc.lpszClassName = str(f"PythonTaskbar{title}") # could instead specify simple mapping self.wc.lpfnWndProc = self._decorator(self.wnd_proc, callback_on_click) try: self.classAtom = RegisterClass(self.wc) except Exception as e: #logging.error('Some trouble with classAtom (%s)', e) self.classAtom = self.wc style = WS_OVERLAPPED | WS_SYSMENU self.hwnd = CreateWindow(self.classAtom, 'Taskbar', style, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, self.hinst, None) UpdateWindow(self.hwnd) # icon if icon_path is not None: icon_path = path.realpath(icon_path) converted = False if Image is not None and icon_path.split('.')[-1] != '.ico': img = Image.open(icon_path) new_name = icon_path.split('.')[:-1] + '.ico' img.save(new_name) icon_path = new_name converted = True else: icon_path = resource_filename(Requirement.parse('win10toast'), 'win10toast/data/python.ico') converted = False icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE try: hicon = LoadImage(self.hinst, icon_path, IMAGE_ICON, 0, 0, icon_flags) if Image and path.exists(new_name and converted): remove(new_name) except Exception as e: logging.error('Some trouble with the icon (%s): %s', icon_path, e) hicon = LoadIcon(0, IDI_APPLICATION) # Taskbar icon flags = NIF_ICON | NIF_MESSAGE | NIF_TIP nid = self.hwnd, 0, flags, WM_USER + 20, hicon, 'Tooltip' Shell_NotifyIcon(NIM_ADD, nid) Shell_NotifyIcon(NIM_MODIFY, (self.hwnd, 0, NIF_INFO, WM_USER + 20, hicon, 'Balloon Tooltip', msg, 200, title)) PumpMessages() # take a rest then destroy if duration is not None: sleep(duration) DestroyWindow(self.hwnd) UnregisterClass(self.wc.lpszClassName, None) return None
def _show_toast(self, title, msg, icon_path, delay, sound_path, tooltip, duration, callback_on_click, kill_without_click): """Notification settings. :title: notification title :msg: notification message :icon_path: path to the .ico file to custom notification :delay: delay in seconds before notification self-destruction, None for no-self-destruction :sound_path: path to the .wav file to custom notification :duration: how long the notification stays on the screen in seconds :callback_on_click: function to run on click :kill_without_click: Kill the tray icon after the notification goes away, even if it wasn't clicked """ self.delay = delay self.destroy_window = kill_without_click # Register the window class. self.wc = WNDCLASS() self.hinst = self.wc.hInstance = GetModuleHandle(None) self.wc.lpszClassName = str( f"PythonTaskbar - {uuid4().hex}") # must be a string self.wc.lpfnWndProc = self._decorator( self.wnd_proc, callback_on_click) # could instead specify simple mapping try: self.classAtom = RegisterClass(self.wc) except Exception as e: raise type(e)(f"Some trouble with classAtom:\n{e}") from None style = WS_OVERLAPPED | WS_SYSMENU self.hwnd = CreateWindow(self.classAtom, "Python Taskbar", style, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, self.hinst, None) UpdateWindow(self.hwnd) # icon if icon_path is not None: icon_path = path.realpath(icon_path) else: icon_path = resource_filename(Requirement.parse("win10toast"), "win10toast/data/python.ico") icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE try: hicon = LoadImage(self.hinst, icon_path, IMAGE_ICON, 0, 0, icon_flags) except Exception as e: raise type(e)( f"Some trouble with the icon ({icon_path}):\n{e}") from None hicon = LoadIcon(0, IDI_APPLICATION) # set the duration buff = create_unicode_buffer(10) SystemParametersInfoW(SPI_GETMESSAGEDURATION, 0, buff, 0) try: oldlength = int( buff.value.encode('unicode_escape').decode().replace( "\\", "0"), 16) except ValueError: oldlength = 5 # default notification length durationOutput = SystemParametersInfoW(SPI_SETMESSAGEDURATION, 0, duration, SPIF_SENDCHANGE) SystemParametersInfoW(SPI_GETMESSAGEDURATION, 0, buff, 0) durationError = False try: int( buff.value.encode('unicode_escape').decode().replace( "\\", "0"), 16) except ValueError: durationError = True if durationOutput == 0 or duration > 255 or durationError: SystemParametersInfoW(SPI_SETMESSAGEDURATION, 0, oldlength, SPIF_SENDCHANGE) raise RuntimeError( f"Some trouble with the duration ({duration}): Invalid duration length" ) # Taskbar icon flags = NIF_ICON | NIF_MESSAGE | NIF_TIP nid = (self.hwnd, 0, flags, WM_USER + 20, hicon, tooltip) Shell_NotifyIcon(NIM_ADD, nid) Shell_NotifyIcon( NIM_MODIFY, (self.hwnd, 0, NIF_INFO, WM_USER + 20, hicon, tooltip, msg, 0, title, 0 if sound_path == None else NIIF_NOSOUND)) # play the custom sound if sound_path is not None: sound_path = path.realpath(sound_path) if not path.exists(sound_path): raise IOError( "Some trouble with the sound file ({sound_path}): [Errno 2] No such file" ) try: PlaySound(sound_path, SND_FILENAME) except Exception as e: raise type( e)(f"Some trouble with the sound file ({sound_path}): {e}" ) from None PumpMessages() # put the notification duration back to normal SystemParametersInfoW(SPI_SETMESSAGEDURATION, 0, oldlength, SPIF_SENDCHANGE) # take a rest then destroy if self.delay is not None and self.destroy_window: while self.delay > 0: sleep(0.1) self.delay -= 0.1 DestroyWindow(self.hwnd) UnregisterClass(self.wc.lpszClassName, self.hinst) try: # sometimes the tray icon sticks around until you click it - this should stop it self.remove_window(self.hwnd) except WinTypesException: pass return
def msg_loop(self): if self.visible: PumpMessages()
def _show_toast(self): """Internal function called by Toast#display to show the toast""" self.active = True self.destroy_window = self.toast_data["kill_without_click"] # Register the window class self.toast_data["wnd_class"] = WNDCLASS() self.toast_data["hinst"] = self.toast_data[ "wnd_class"].hInstance = GetModuleHandle(None) self.toast_data[ "wnd_class"].lpszClassName = f"PythonTaskbar{uuid4().hex}" self.toast_data["wnd_class"].lpfnWndProc = self._decorator( self._wnd_proc, self.toast_data["callback_on_click"]) self.toast_data["class_atom"] = RegisterClass( self.toast_data["wnd_class"]) style = WS_OVERLAPPED | WS_SYSMENU self.toast_data["hwnd"] = CreateWindow( self.toast_data["class_atom"], self.toast_data["wnd_class"].lpszClassName, style, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, self.toast_data["hinst"], None, ) UpdateWindow(self.toast_data["hwnd"]) icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE hicon = LoadImage(self.toast_data["hinst"], self.toast_data['icon_path'], IMAGE_ICON, 0, 0, icon_flags) # Set the duration buff = create_unicode_buffer(10) SystemParametersInfoW(SPI_GETMESSAGEDURATION, 0, buff, 0) try: oldlength = int( buff.value.encode("unicode_escape").decode().replace( "\\", "0"), 16) except ValueError: oldlength = 5 # Default notification length SystemParametersInfoW(SPI_SETMESSAGEDURATION, 0, self.toast_data["duration"], SPIF_SENDCHANGE) # Taskbar icon flags = NIF_ICON | NIF_MESSAGE | NIF_TIP nid = ( self.toast_data["hwnd"], 0, flags, WM_USER + 20, hicon, self.toast_data["tooltip"], ) # Make it so that it won't replace another # notification with the same title and message title = self.toast_data["title"] + " " * randint( 0, 63 - len(self.toast_data["title"])) message = self.toast_data["msg"] + " " * randint( 0, 128 - len(self.toast_data["msg"])) # Add tray icon and queue message Shell_NotifyIcon(NIM_ADD, nid) Shell_NotifyIcon( NIM_MODIFY, ( self.toast_data["hwnd"], 0, NIF_INFO, WM_USER + 20, hicon, self.toast_data["tooltip"], message, 0, title, NIIF_NOSOUND if self.toast_data["sound_path"] else 0, ), ) # Play the custom sound if self.toast_data["sound_path"] is not None: sound_path = path.realpath(self.toast_data["sound_path"]) PlaySound(sound_path, SND_FILENAME) # Show the message PumpMessages() # Put the notification duration back to normal SystemParametersInfoW(SPI_SETMESSAGEDURATION, 0, oldlength, SPIF_SENDCHANGE) # Take a rest then destroy if not self.toast_data["keep_alive"] and self.destroy_window: self.destroy()
def main(): watcher = Keystroke_Watcher PumpMessages()
def run(self): self.watcher = KeystrokeWatcher(self.functions) PumpMessages()
def _show_toast( self, title: str, msg: str = "No msg", icon_path: Path = None, duration: float = None, sound_path=None, callback_on_click: callable = None, tooltip: Optional[str] = None, ) -> None: """Notification settings. :param title: notification title :param msg: notification message :param icon_path: path to the .ico file to custom notification :param duration: delay in seconds before notification self-destruction, None for no-self-destruction :param sound_path: path to the .wav file to custom notification """ self.duration = duration def callback(): """ """ self.duration = 0 if callback_on_click is not None: callback_on_click() if tooltip is None: tooltip = PROJECT_NAME # Register the window class. self.window_class = WNDCLASS() self.instance_handle = self.window_class.hInstance = GetModuleHandle( None) self.window_class.lpszClassName = f"{PROJECT_NAME}-{title}" # must be a string self.window_class.lpfnWndProc = self._decorator( self.wnd_proc, callback) # could instead specify simple mapping try: self.classAtom = RegisterClass(self.window_class) except Exception as e: logging.error("Some trouble with classAtom (%s)", e) style = WS_OVERLAPPED | WS_SYSMENU button_style = WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON # TODO: Unused for now self.window_handle = CreateWindow( self.classAtom, "Taskbar", style, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, self.instance_handle, None, ) UpdateWindow(self.window_handle) # icon new_name = "" if icon_path is not None: icon_path = path.realpath(icon_path) converted = False if Image is not None and icon_path.split(".")[-1] != ".ico": img = Image.open(icon_path) new_name = f'{str(icon_path.split(".")[:-1])}.ico' img.save(new_name) icon_path = new_name converted = True else: icon_path = resource_filename( Requirement.parse(PROJECT_NAME), str(Path(PROJECT_NAME) / "data" / "python.ico"), ) converted = False try: hicon = LoadImage( self.instance_handle, icon_path, IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE, ) if Image and path.exists(new_name and converted): remove(new_name) except Exception as e: logging.error("Some trouble with the icon (%s): %s", icon_path, e) hicon = LoadIcon(0, IDI_APPLICATION) # Set the duration """ buff = create_unicode_buffer(10) windll.user32.SystemParametersInfoW(SPI_GETMESSAGEDURATION, 0, buff, 0) try: oldlength = int(buff.value.encode("unicode_escape").decode().replace("\\", "0"), 16) except ValueError: oldlength = 5 # Default notification length duration_output = windll.user32.SystemParametersInfoW(SPI_SETMESSAGEDURATION, 0, self.duration, SPIF_SENDCHANGE) windll.user32.SystemParametersInfoW(SPI_GETMESSAGEDURATION, 0, buff, 0) duration_error = False try: int(buff.value.encode("unicode_escape").decode().replace("\\", "0"), 16) except ValueError: duration_error = True if duration_output == 0 or self.duration > 255 or duration_error: windll.user32.SystemParametersInfoW(SPI_SETMESSAGEDURATION, 0, oldlength, SPIF_SENDCHANGE) self.active = False raise RuntimeError(f"Some trouble with the duration ({self.duration})" ": Invalid duration length") """ title += " " * randint(0, 63 - len(title)) msg += " " * randint(0, 128 - len(msg)) Shell_NotifyIcon( NIM_ADD, ( self.window_handle, 0, NIF_ICON | NIF_MESSAGE | NIF_TIP, WM_USER + 20, hicon, tooltip, ), ) Shell_NotifyIcon( NIM_MODIFY, ( self.window_handle, 0, NIF_INFO, WM_USER + 20, hicon, tooltip, msg, 200, title, 0 if sound_path is None else NIIF_NOSOUND, ), ) if sound_path is not None: # play the custom sound sound_path = path.realpath(sound_path) if not path.exists(sound_path): logging.error( f"Some trouble with the sound file ({sound_path}): [Errno 2] No such file" ) try: PlaySound(sound_path, SND_FILENAME) except Exception as e: logging.error( f"Some trouble with the sound file ({sound_path}): {e}") PumpMessages() """ # Put the notification duration back to normal SystemParametersInfoW(SPI_SETMESSAGEDURATION, 0, oldlength, SPIF_SENDCHANGE) """ if duration is not None: # take a rest then destroy # sleep(duration) while self.duration > 0: sleep(0.1) self.duration -= 0.1 DestroyWindow(self.window_handle) UnregisterClass(self.window_class.lpszClassName, self.instance_handle) try: # Sometimes the try icon sticks around until you click it - this should stop that Shell_NotifyIcon(NIM_DELETE, (self.window_handle, 0)) except WinTypesException: pass self.active = False
def run(self): watcher = Watcher() PumpMessages()