Java JNA #2, Total Commander

UWAGA, ruszył Humble Book Bundle na serię Cookbok wydawnictwa O'REILLY

totalcmdW poprzednim wpisie zrobiłem krótkie wprowadzenie do wykorzystywania biblioteki user32.dll przez Javę do pobierania informacji z innych aplikacji okienkowych. Poniżej rozszerzymy nasze klasy o możliwość pobierania dowolnie zagnieżdżonych komponentów za pomocą funkcji rekurencyjnej przeszukującej całe drzewo elementów. Wszystko na przykładzie Total Commandera.

Uruchamiamy Total Commandera, WinSpy++ i badamy pole tekstowe linii komend (czarna ramka):

tc1

Wynik:

tc2

Pole edycyjne które nas interesuje znajduje się w drzewie komponentów Total Commandera kolejno według klas:
TTOTAL_CMD ->Window ->LCLComboBox -> Edit.

Nie zadziała nam tu wyszukiwanie tak jak to zrobiliśmy w poprzednim wpisie: user32.FindWindowExA(hwnt, null, „Edit”, null). Różnica polega na tym, że tym razem nasz komponent jest zagnieżdżony w stosunku do głównego elementu. Funkcja FindWindowExA zwróci nam tylko pierwszy występujący bezpośrednio podrzędny uchwyt.

Pozostaje zadać sobie kluczowe pytanie: w jaki sposób wyszukać ten konkretny interesujący nas komponent. Identyfikujące parametry to:

  • Handle – wartość liczbowa wyświetlana w systemie szesnastkowym,
  • Class – nazwa klasy (tekst),
  • Control ID – identyfikator, również wyświetlany w systemie szesnastkowym w programie WinSpy++.

Problem polega na tym, że wartości liczbowe uchwytów i id mogą się się zmieniać przy każdym uruchomieniu programu. W związku z tym postanowiłem wykorzystać podobne rozwiązanie jakie jest zastosowane w programie Active Window Info dołączonego do AutoHotKeya. Po zbadaniu pola edycyjnego otrzymujemy dane:

tc3

Tutaj w nazwie klasy pojawia się na jej końcu liczba: „Edit1„, w WinSpy++ była to tylko wartość „Edit„. Zapewne domyślacie się, że Active Window Info przeszukuje całe drzewo programu i numeruje kolejno występujące komponenty według nazw klas. Właśnie takie rozwiązanie postanowiłem zastosować aby było w miarę uniwersalne.

Kod w Javie

Rozszerzamy interfejs do biblioteki user32.dll (z poprzedniego wpisu) o pomocnicze metody zwracające id i nazwę klasy komponentu:

Zaktualizowana klasa WinApi wygląda następująco:

Doszły w niej również pomocnicze metody do zwracania id i nazwy klasy komponentu.

Rekurencyjne przeszukiwanie drzewa komponentów

Na samym początku dodajemy interfejs służący do odbierania wyszukiwanych elementów:

Kolejnym krokiem jest napisanie klasy wyszukującej wszystkie elementy programu:

Najważniejszą metodą w tej klasie jest private void walk(HWND parent, int level). To w niej szukamy wszystkich bezpośrednich podrzędnych elementów dla rodzica. W pętli while dla każdego elementu wyszukujemy w głąb kolejnych, po czym szukamy następnego na tym samym poziomie będącym za bieżącym. Kluczową metodą jest FindWindowExA(parent, hwnd…), która w drugim parametrze przyjmuje uchwyt komponentu od będzie rozpoczęte wyszukiwanie.

Numeracja elementów w zależności od nazwy klasy

Zostało już tylko zaimplementowanie zliczania elementów. Wykorzystam do tego Hash Mapę, w której kluczami będą nazwy klas, a wartościami ich aktualny licznik. Klasa będzie wykorzystywana do wyszukiwania komponentów. Docelowo funkcję zliczania elementów i ich wyszukiwania trzeba będzie rozdzielić na osobne klasy.

Na potrzeby wpisu celowo została dodana metoda do wypisywaniu na wyjściu wyszukiwanych elementów w formie powiedzmy jakiegoś „drzewka” :).

Testujemy

Ok, wpisujemy w pole tekstowe linii komend Total Commandera przykładowy tekst:

tc4

Uruchamiamy kod:

Na wyjściu pojawia się:

W ostatniej linii otrzymaliśmy zawartość tekstową wyszukanego komponentu ze zmiennej component:
Zawartość pola linii komend: touch test.txt.

Spoglądając na drzewko w WinSpy++ widzimy, że nasze wyniki są zgodne (porównajcie wartości uchwytów i zagnieżdżenie):

tc5

Podsumowanie

Java JNA – ciekawe narzędzie, które pozwala wywoływać natywny kod z bibliotek .dll. Z pewnością na blogu pojawią się kolejne artykuły w tym temacie. Bo np. w Windowsie nie tylko biblioteka user32.dll istnieje :).

Nawiązując w jakiś sposób do tematu, zwłaszcza w początkach mojej przygody z programowaniem lubiłem realizować tego typu podobne pomysły. Pod tagiem cracking jest tu kilka archiwalnych wpisów.

 

Książki do nauki Javy

 

UWAGA, ruszył Humble Book Bundle na serię Cookbok wydawnictwa O'REILLY

To również może Cię zainteresować:

  • Java JNA, user32.dll – przechwytujemy aplikacje okienkoweJava JNA, user32.dll – przechwytujemy aplikacje okienkowe Zdarzają się takie sytuacje, że chcielibyśmy naszym programem sterować inną aplikacją okienkową. W tym artykule wprowadzę was w temat pobierania danych z programów windowsowych za pomocą […]
  • Mapowanie XML obiektów Java – JAXBMapowanie XML obiektów Java – JAXB Podczas tworzenia oprogramowania na każdym kroku mamy kontakt z danymi w formacie XML. Opiszę tutaj jeden ze sposobów konwersji danych w obie strony Java <-> XML. Ale na […]
  • Java i listing wszystkich plików w kataloguJava i listing wszystkich plików w katalogu W ostatnim czasie musiałem przerobić jeden z systemów na wersję wielojęzykową. Chodziło dokładnie o to, aby wszystkie Stringi zostały wywołane przez tzw. wrapper ze wstrzyknięciem pewnego […]
  • 10-letni chłopak zdobył 100% na egzaminie OCPJP z Javy!10-letni chłopak zdobył 100% na egzaminie OCPJP z Javy! W zeszłym roku Ronil Shah zaskoczył prawie wszystkich zdobywając sto procent punktów w egzaminie z Javy OCPJP. Jednak to nie wszystko. Najciekawsze jest to, że egzamin ten przewidziany […]
  • Java Spring, recenzja kursu wideo z Videopoint.plJava Spring, recenzja kursu wideo z Videopoint.pl Każdy, kto zawodowo programuje w obojętnie jakim języku wie, że bez wsparcia frameworków nasze życie byłoby znacznie trudniejsze. Tak jak Python ma swojego Django, PHP - Symfony, czy Ruby […]
  • Fundamenty języka JavaFundamenty języka Java Niecały miesiąc temu zostałem poproszony przez Strefę Kursów o ocenę ich nowo wydanego materiału dla osób chcących zacząć naukę programowania w Javie: "Fundamenty języka Java". Przerobiłem […]

Dodaj komentarz