Java JNA #2, Total Commander

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

 

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 […]
  • 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 […]
  • 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 […]
  • 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

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *