2011-01-11 13 views
14

Debugger Delphi doskonale nadaje się do debugowania kodu liniowego, gdzie jedna funkcja wywołuje inne funkcje w przewidywalny, liniowy sposób, a my możemy przechodzić przez linię programu po linii.Czy istnieje sposób rejestrowania każdego zdarzenia GUI w Delphi?

Uważam, że debugger jest mniej przydatny, gdy mamy do czynienia z kodem GUI sterowanym zdarzeniem, gdzie pojedynczy wiersz kodu może powodować wyzwalanie nowych zdarzeń, co z kolei może powodować inne zdarzenia. W tej sytuacji podejście "krok po kodzie" nie pozwala mi zobaczyć wszystkiego, co się dzieje.

Sposób, w jaki zwykle rozwiązuję to: 1) odgadnąć, które zdarzenia mogą być częścią problemu, następnie 2) dodać punkty przerwania lub zalogować się do każdego z tych zdarzeń.

Problem polega na tym, że takie podejście jest przypadkowe i czasochłonne.

Czy jest przełącznik, który można uruchomić w debugerze, aby powiedzieć "log all gui events"? Czy jest jakiś kod mogę dodać do wydarzeń pułapkę, coś

procedure GuiEventCalled(ev:Event) 
begin 
    log(ev); 
    ev.call(); 
end 

Efektem końcowym szukam jest coś takiego (na przykład):

FieldA.KeyDown 
FieldA.KeyPress 
FieldA.OnChange 
FieldA.OnExit 
FieldB.OnEnter 

będzie to trwać przez cały zgadywanie z debugowania GUI Delphi.

używam Delphi 2010

[edytuj] Kilka odpowiedzi sugerowane sposoby przechwytywać lub rejestrowania komunikatów Windows. Inni wskazywali, że nie wszystkie zdarzenia Delphi są w ogóle komunikatem Windows. Wydaje mi się, że to właśnie tego rodzaju zdarzenia o charakterze "wiadomości z systemu Windows" były o to pytane; Zdarzenia tworzone przez kod Delphi. [/ EDIT]

[EDIT2] Po przeczytaniu wszystkich informacji tutaj, wpadłem na pomysł, aby użyć RTTI do dynamicznego przechwytywania TNotifyEvents i rejestrowania ich w dzienniku zdarzeń w oknie debugowania. Obejmuje to zdarzenia OnEnter, OnExit, OnChange, OnClick, OnMouseEnter, OnMouseLeave. Po odrobinie hackowania udało mi się to całkiem dobrze, przynajmniej na mój użytek (nie zapisuje kluczowych zdarzeń, ale można to dodać). ja pisał kod here

Aby korzystać

  1. Pobierz Jednostka EventInterceptor i dodać go do swojego projektu
  2. Dodaj EventInterceptor Jednostka klauzuli używa
  3. Dodaj tę linię gdzieś w Twój kod dla każdego formularza, który chcesz śledzić.

    AddEventInterceptors (MyForm);

Otwórz okno debugger oraz wszelkie zdarzenia, które są nazywane będą rejestrowane w dzienniku zdarzeń

[/ EDIT2]

Odpowiedz

8

Użyj jednostki "delphieventlogger", którą napisałem download here. Jest to tylko jedno wywołanie metody i jest bardzo łatwe w użyciu. Loguje wszystkie zdarzenia TNotifyEvents (np. OnChange, OnEnter, OnExit) do dziennika zdarzeń Delphi w oknie debuggera.

+0

+1 do opublikowania własnego rozwiązania z kodem tutaj! –

2

Zastosowanie WinSight zobaczyć przepływ wiadomości w czasie rzeczywistym.

Jeśli naprawdę chcesz, aby program tworzył dziennik, zastąp nadpisując WinProc i/lub przechwytuj wiadomości w Application.

+0

Czy wszystkie komunikaty Delphi są wiadomościami systemu Windows? Właśnie próbowałem rejestrowania zdarzeń przy użyciu TApplicationEvents.OnMessage, a wszystko, co wydaje mi się uzyskiwać, to ruchy myszką i zdarzenia klawiatury. Nie widzę zdarzeń OnChange, OnExit ani OnEnter (o ile wiem). Sądzę, że miałem nadzieję na coś bardziej wysokiego poziomu niż wiadomości systemu Windows. – awmross

+0

btw WinSight nie jest dostarczany z Delphi 2010 – awmross

+2

@awmross: Zdarzenia Delphi nie są komunikatami systemu Windows. Komunikaty systemu Windows są wysyłane do procedur obsługi komunikatów na kontrolkach Delphi, z których niektóre obsługują zdarzenia obsługi zdarzeń, jeśli są dołączone. –

3

Nie, nie ma uogólnionego sposobu, aby to zrobić, ponieważ Delphi nie ma żadnego rodzaju "rodzaju zdarzenia", które można w jakiś sposób podłączyć. Procedura obsługi zdarzenia jest po prostu odwołaniem do metody i wywoływana jest w ten sposób:

if assigned(FEventHandler) then 
    FEventHandler(self); 

Tylko normalne odwołanie do metody. Jeśli chcesz rejestrować wszystkie programy obsługi zdarzeń, musisz osobiście wprowadzić wywołanie do każdego z nich.

+0

Okazuje się, że wiele wydarzeń, które mnie interesują, jest tego samego typu (tj. TNotifyEvent). Za pomocą RTTI możemy przechwytywać wszystkie zdarzenia tego typu i logować je. – awmross

3

Wiem, że jest to trochę kosztowne, ale możesz używać automatycznych kontroli jakości (teraz SmartBear) TestRecorder jako rozszerzenia do TestComplete (jeśli chcesz to tylko w systemie, sam TestComplete zrobi). To oprogramowanie będzie śledzić twoje działania GUI i zapisywać je w skrypcie takim jak język. Istnieje nawet jednostka, która może być podłączona do twojego exe, aby nagrywać bezpośrednio w systemie użytkownika. Jest to szczególnie przydatne, gdy niektórzy użytkownicy nie są w stanie wyjaśnić, co zrobili, aby wygenerować błąd.

-1

Możesz wypróbować jeden z AOP frameworks for Delphi. MeAOP zapewnia domyślny program rejestrujący, z którego można korzystać. Nie powie ci, co się dzieje w programie obsługi zdarzeń, ale powie ci, kiedy zostanie wywołana procedura obsługi zdarzenia i kiedy wróci.

+0

Też myślałem o AOP dla tego. Próbowałem MeAOP, ale nie wydaje się, aby skompilować pod D2010 (myślę, że jest to problem Unicode). – awmross

1

Alternatywnie, aby debugować zdarzenia wyzwalane, należy użyć polecenia krok po kroku (F7) zamiast polecenia krok po kroku (F8).

Debuger zatrzyma się na dostępnej linii kodu osiągniętej podczas połączenia. Zdarzenie

+0

Początkowo nie mogłem użyć tego podejścia, ponieważ używamy biblioteki skórowania innej firmy, która jest dość skomplikowana; Zauważyłem, że debugger wkroczyłby w ten zewnętrzny kod. Następnie odkryłem dyrektywę kompilatora "{$ D-}", która może wyłączyć debugowanie dla całej jednostki. To ograniczyło działanie debuggera tylko do mojego kodu projektu, co uczyniło twoją sugestię praktyczną. Myślę jednak, że istnieje ogólny problem z tym podejściem; zdarzenia, których szukasz, mogą zostać wywołane głęboko w drzewie wywołań; więc ręczne przejście przez kod nadal wymaga zgadywania i próby przez pomyłkę. – awmross

+0

@awmross: Aby debugować aplikację (zdarzenie napędzane lub nie) jest prawie całkowicie sztuką zgadywania i próbowania przez błąd;) – jachguate

2

Zdarzenie TApplication.OnMessage może być używane do przechwytywania wiadomości umieszczonych w głównej kolejce komunikatów. Dotyczy to głównie wiadomości wysyłanych przez system operacyjny, a nie wewnętrznych komunikatów VCL/RTL, które są zwykle wywoływane bezpośrednio metodami WndProc(). Nie wszystkie zdarzenia VCL są oparte na komunikatach. Nie ma jednego rozwiązania tego, czego szukasz. Musielibyśmy użyć kombinacji override,, WndProc(), , selektywnych punktów przerwania/haków w kodzie.

Narzędzie WinSight Borlanda nie jest już dystrybuowane, ale dostępnych jest wiele narzędzi innych firm, które działają tak samo jak WinSight, takich jak Spy ++ firmy Microsoft, WinSpector itp. Do śledzenia komunikatów okna rejestrowania w czasie rzeczywistym .

Powiązane problemy