Raportowanie interakcji użytkownika.

0

Użytkownicy mojego programu czasem wygenerują jakiś ciekawy błąd w programie, który nie zawsze wyłapany jest przez EurekaLog. Chodzi np. o sytuacje, gdzie user wykona szereg czynności (prawidłowych i dopuszczalnych), które w konsekwencji prowadzą do wystąpienia wyjątku. Przykładowa sytuacja: 2 w pewien sposób powiązane ze sobą obiekty, użytkownik w jakiś sposób usuwa jeden z nich a później chce wykonać coś na drugim obiekcie. Drugi obiekt odwołuje się do pierwszego i AV. Chcę dojść w takiej sytuacji jak użytkownik wykasował ten pierwszy obiekt - gdzie jest coś nie tak w kodzie. Czy ktoś zna jakiś ciekawy sposób w jaki można raportować co użytkownik 'klika'? Na myśl przychodzi mi tylko wyłapywanie zmian wybranych akcji w menu przez ActionManager + dodanie Clicków, Key i Mouse eventów związanych z akacjami na formatce. Nie chce wchodzić w szczegóły, wydaje mi się że wystarczyłaby mi informacja co po kolei user klika i gdzie. Najprostsze rozwiązanie czyli spytanie usera co robił przed wystąpieniem błędu nie zdaje rezultatu bo zawsze 'nic nie zrobili'. Jakby się bali że to oni coś zepsuli. EurekaLog czy MadExcept itp. nie pomogą bo mnie interesuje co się działo sporo wcześniej przed wystąpieniem błędu. Czy da radę zrobić to jakoś elegancko bez nadmiernego klepania kodu? Już wcześniej miałem taki pomysł, żeby dodatkowo doklejać taki trace wcześniejszych akcji do raportu Eureki.

0

Domyślam się, że przykład z obiektami A i B to tylko mocno uproszczony opis problemu. Nie znam Twojej architektury dziedziczenia obiektów ale pomysły na teraz, które mi przychodzą do głowy:

  • log w destruktorze obiektu
  • jeśli obiekt dziedziczy po TComponent to klasa ta ma mechanizm notyfikacji, który mógłbyś wykorzystać
  • nadpisanie adresu poszczególnych wywołań w poszczególnych klasach własnym mechanizmem - nie wiem czy dobrze to opisałem ale chodzi mi o to, że np nadpisujesz adres wywołania klasy button.click własną metodą, w której nadpisujesz wywołanie swoim logowaniem i później dalej odpalasz metodę button.click

Niestety o gotowcu, który z automatu rejestruje kliknięcia, klawisze, akcje itd. nie słyszałem.

0

Tak, przykład z obiektami to bardzo duże uproszczenie. Chciałem zobrazować mniej więcej o co mi chodzi. Nie interesują mnie jedynie sytuacje usuwania obiektu a raczej cała otoczka co się dzieje wcześniej. Log w destruktorze nie wystarczy, mnie interesują głównie poczynania usera w GUI. Potem już będę wiedział co i jak i czemu mogło wyjść coś nie tak. Obiekty nie są powiązane bezpośrednio z komponentami chociaż mnie interesują właśnie komponenty więc może byłoby to jakieś rozwiązanie. Tylko czy to nie podobne sytuacja jak wykorzystanie do tego ActionManager? Prawie wszystkie akcje mam wywoływane z menu w Ribbon.
Odnośnie trzeciej opcji to nie wiem czy dobrze rozumiem ale byłaby to zmiana globalna czy tylko do mojego projektu? W OnCreate formy byłoby takie predefinowanie odwołania do klasy?
Wydaje mi się, że mój pierwotny zamysł przynajmniej dla mnie jest trochę prostszy do realizacji. Musiałbym dodać logi dla Executa w ActionManager, MouseClick i KeyDown dla formatek. Teraz niestety nie mam na to czasu ale później wrócę do tematu i sprawdzę co i jak może zadziałać.

0
Clarc napisał(a):

Odnośnie trzeciej opcji to nie wiem czy dobrze rozumiem ale byłaby to zmiana globalna czy tylko do mojego projektu? W OnCreate formy byłoby takie predefinowanie odwołania do klasy?
Wydaje mi się, że mój pierwotny zamysł przynajmniej dla mnie jest trochę prostszy do realizacji. Musiałbym dodać logi dla Executa w ActionManager, MouseClick i KeyDown dla formatek. Teraz niestety nie mam na to czasu ale później wrócę do tematu i sprawdzę co i jak może zadziałać.

I jeśli to są akcje, to napisz własną akcję, nadpisz metodę DoExec i loguj wykonanie danej akcji w kontekście np. okna (To będzie prawdopodobnie Self.Action.Owner).
Co miałoby robić MouseClick i KeyDown i po co?
Skoro używasz akcji, to i wykonanie OnClick to też akcja.
Sprawa komplikuje się przy edycji danych, ale to też można rozwiązać - wystarczy np. wydziedziczyć z jakiegoś tam używanego przez Ciebie TQuery, napisać metody DoAfterCOŚ (np. DoAfterEdit) i logować.

Można podejść do tematu bardziej hardcorowo (biblioteka Detours się kłania), ale średnio mi się to podoba.
Tak działa gotowiec, czyli Castalia Usertility, który został kupiony przez Emba i może jakoś inaczej to się nazywa - ale nie pamiętam jak.
Masz tu początek ze źródłami, robi praktycznie to co chciałeś:
https://github.com/jacobthurman/UsertilitySDK

Ale to i tak mało, bo tak naprawdę brakuje jeszcze logowania zmiany stanu obiektu; czyli, że np. Kasia zmieniła coś z wartość X na wartość Y.

To wszystko da się zrobić, ale do tematu trzeba podejść szerzej i mieć zaimplementowane pewne mechanizmy na niższych warstwach.
Ale to już rozmowa, jak zbudować taki framework i dlaczego w tan a nie inny sposób.
Temat rzeka, a mało informacji o Ciebie, więc... kombinuj ;-)

0

Aplikacja to konkretnie GIS. MouseClick służy m.in. do wprowadzania 'obiektów' w GIS-ie a w KeyDown np. dla Esc mam możliwość przerwania akcji. Jedno i drugie jest dla mnie ważne ze względu na to co i jak użytkownik może popsuć. Z edycją danych bym sobie poradził bo jak piszesz mam zdarzenia przed wysłaniem danych do bazy - już ich używam do Undo/Redo.
Z UsertilitySDK zobaczę czy da się coś zrobić. Widzę, że od 4 lat lisza, kompilacja dla XE6 no i drak dokumentacji najgorszy :/ Ale zobaczę, może da radę zainstalować i coś z tego wyciągnąć.

0
Clarc napisał(a):

Aplikacja to konkretnie GIS. MouseClick służy m.in. do wprowadzania 'obiektów' w GIS-ie a w KeyDown np. dla Esc mam możliwość przerwania akcji. Jedno i drugie jest dla mnie ważne ze względu na to co i jak użytkownik może popsuć.

To zrób to na poziomie obiektu, a nie zdarzeń myszy/klawiatury...

Z edycją danych bym sobie poradził bo jak piszesz mam zdarzenia przed wysłaniem danych do bazy - już ich używam do Undo/Redo.

OK.

Z UsertilitySDK zobaczę czy da się coś zrobić. Widzę, że od 4 lat lisza, kompilacja dla XE6 no i drak dokumentacji najgorszy :/ Ale zobaczę, może da radę zainstalować i coś z tego wyciągnąć.

Tam jest tylko hook na SetFocus i ActiveWindow, no i to jest plugin do Castalia Usertility, a to teraz działa inaczej i kupiła to Emba...
A generalnie, to jest rozwiązanie jakiego możesz oczekiwać w całości...

0

To zrób to na poziomie obiektu, a nie zdarzeń myszy/klawiatury...

Brałem to pod uwagę ale zdarzenia na obiekcie nie wyjaśnią mi co zrobił użytkownik że doszło do takiej a nie innej sytuacji. Zdarzenia obiektu mogą być wywołane przez kilka interakcji użytkownika. To że user wykonał obiekt.add a później obiekt.delete nie jest tym czego potrzebuje. Muszę wiedzieć za pomocą czego był wykonany obiekt.add: dodanie obiektu, kopiowanie, jakiś import bo tak jak pisałem wcześniej ważny jest ciąg przyczynowo skutkowy. Jakiś czas temu miałem fatalny błąd którego w żaden sposób nie dało zreplikować. Po sporym czasie okazało się, że myszka była felerna, i zamiast clicka dawała dbclick :] User robił dokładnie tak jak mówił a myszka robiła swoje. To akurat szczególny przypadek ale znam i takie gdzie ktoś pisze coś na klawiaturze w laptopie a nadgarstkiem dotyka touchpada i tekst się nie chce wpisywać :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1