Archiwista [cz. 7 – Skrót klawiszowy]

Jedną z kluczowych funkcjonalności aplikacji jest tworzenie kopii zapasowych plików źródłowych. Za każdym razem, gdy użytkownik przyciśnie skrót klawiszowy program ma rozpocząć proces archiwizacji. W tym wpisie przedstawię etapy tworzenia klas, które pozwolą na nasłuchiwanie klawiatury oraz interpretację skrótów.

Nasłuchiwanie

Pierwszą rzeczą potrzebną do rozpoznania skrótu klawiszowego jest jego otrzymanie, więc pierwszą czynnością, jaką zrobiłem było przeszukanie Internetu na temat różnych możliwości nasłuchiwania klawiatury komputera. Jak się okazało istnieje wiele możliwości, jednak każda niosła ze sobą jakieś korzyści i limitacje. Jednak jedna pojawiała się w prawie każdym wpisie, jaki odwiedziłem. Global keyboard hooks pozwalają na słuchanie informacji z kolejki systemu operacyjnego dzięki czemu istnieje możliwość nasłuchiwania wszystkich klawiszy.

W ramach tej aplikacji wybrałem wersję low level keyboard hook poszukując informacji jak używać tego mechanizmu natknąłem się na wpis zawierający gotową klasę umożliwiającą podłączenie się oraz nasłuchiwanie klawiszy. Dlatego użyję tej klasy niestety nie posiada ona wszystkich funkcjonalności, jakich potrzebuję dlatego dokonam modyfikacji. Bez żadnych modyfikacji klasa informuje użytkownika tylko o tym, który klawisz został naciśnięty, ale nie o tym, czy klawisz został puszczony. Aby wykryć skróty klawiszowe będę potrzebował informacji o tym, czy klawisze typu: Alt, Ctrl, Shift są wciśnięte, w tym celu zmodyfikowałem kod dodając dwa eventy OnKeyDown oraz OnKeyUp. Mając informacje, czy dany klawisz jest wciśnięty czy puszczony mogę przystąpić do pisania klasy zarządzającej całością.

Skrót klawiszowy

Jeszcze przed przystąpieniem do tworzenia klasy, która będzie zarządzała całością muszę zaprojektować obiekt przedstawiający skrót klawiszowy. Klasa ta będzie miała informacje o tym, jakie klawisze muszą zostać wciśnięte jednocześnie, aby skrót był uznany za prawidłowy oraz event OnShortcutActivated, który zostanie uruchomiony w przypadku wykrycia odpowiedniej kombinacji klawiszy.

Zarządzanie skrótami

Aby nie tworzyć dużej ilości połączeń i nasłuchiwać każdy klawisz w każdym obiekcie reprezentującym skrót stworzę klasę zarządzającą skrótami. KeyboardShortcutManager posiada listę skrótów, gdy tylko zostanie jakikolwiek skrót z listy wciśnięty uruchomi się odpowiedni event. Dodatkowo w celu łatwej obsługi manager posiada interfejs składający się jak na razie z trzech metod RegisterKeyboardShortcut, UnRegisterKeyboardShortcut. Metody odpowiednio pozwalają na dodanie oraz usunięcie skrótu z listy nasłuchiwanych skrótów klawiszowych. Oraz metodę RecordKeyboardShortcut, która nagrywa następny skrót klawiszowy i zostanie on podmieniony dla skrótu podanego jako argument. Niestety podczas projektowania tej metody wystąpiło kilka problemów logicznych przez sposób, w jaki otrzymuję informację nie jestem w stanie zwrócić utworzonego skrótu. Aktualne rozwiązanie bazuje na fladze, która jest ustawiana dzięki temu manager wie, że kolejnym razem, kiedy użytkownik puści klawisz ma zapisać skrót klawiszowy jako nowy.

Kończąc

Podczas tworzenia klasy reprezentującej skrót klawiszowy przeładowałem również metodę ToString, aby mieć możliwość bezpośredniego Bindowania obiektu KeyboardShortcut do zawartości przycisku. Niestety zawartość przycisku pozostawała pusta. Okazało się, że wyłączenie stylu przycisku dało efekt, jaki oczekiwałem od samego początku. Wewnątrz zawartości przycisku wyświetliła się wartość zwrócona z przeładowanej metody ToString. Rozwiązaniem okazało się stworzenie ValueConvertera, którego jedynym zadaniem jest wywołanie metody ToString. Następne dodałem ToStringValueConverter do stylu bazowego przycisku i przycisk działa tak jak powinien.

Rozwiązanie przedstawione podczas nagrywania nowego skrótu spełnia swoje zadanie, którym jest zmiana klawiszy skrótu, ale niestety nie pozwala na jego zwrócenie bez zawiłych mechanizmów. Nie jestem usatysfakcjonowany takim rozwiązaniem w tym tygodniu zabrakło czasu na jego dopracowanie. Dlatego w następnym tygodniu będę pracował nad jego ulepszeniem.

Cały kod aplikacji można zobaczyć na moim koncie github /kkolodziejczak/Archivist

Leave a Reply

Translate »