2011-01-11 9 views
14

Il debugger Delphi è ottimo per il debug di codice lineare, in cui una funzione chiama altre funzioni in modo prevedibile e lineare e possiamo scorrere il programma riga per riga.C'è un modo per registrare ogni evento di gui in Delphi?

Trovo che il debugger sia meno utile quando si ha a che fare con il codice GUI event driven, in cui una singola riga di codice può causare l'attivazione di nuovi eventi, che a loro volta possono attivare altri eventi. In questa situazione, l'approccio 'passo attraverso il codice' non mi permette di vedere tutto ciò che sta accadendo.

Il modo in cui risolvo questo è 1) indovinare quali eventi potrebbero essere parte del problema, quindi 2) aggiungere punti di interruzione o registrazione a ciascuno di questi eventi.

Il problema è che questo approccio è casuale e richiede tempo.

C'è un interruttore che posso sfogliare il debugger per dire 'registra tutti gli eventi di gui'? O c'è qualche codice che posso aggiungere a intercettare gli eventi, qualcosa come

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

Il risultato finale che sto cercando è qualcosa di simile (per esempio):

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

Questo sarebbe prendere tutto il congettura dal debug di Delphi.

Sto usando Delphi 2010

[EDIT] alcune risposte hanno suggerito modi per intercettare o registrare i messaggi di Windows. Altri hanno poi sottolineato che non tutti gli eventi di Delphi sono messaggi di Windows. Penso che sia questo tipo di eventi "Non Windows Message" di cui stavo chiedendo; Eventi creati dal codice Delphi. [/ EDIT]

[EDIT2] Dopo aver letto tutte le informazioni qui, ho avuto un'idea di utilizzare RTTI per intercettare dinamicamente TNotifyEvents e registrarli nel registro eventi nella finestra Debug. Ciò include gli eventi OnEnter, OnExit, OnChange, OnClick, OnMouseEnter, OnMouseLeave. Dopo un po 'di hacking, ho funzionato abbastanza bene, almeno per il mio utilizzo (non registra eventi Key, ma potrebbe essere aggiunto). Ho postato il codice here

Per utilizzare

  1. Scarica l'Unità EventInterceptor e aggiungerlo al progetto
  2. aggiungere l'unità EventInterceptor alla clausola uses
  3. Aggiungere questa linea da qualche parte in il tuo codice per ogni modulo che desideri monitorare.

    AddEventInterceptors (MyForm);

Aprire la finestra debugger e tutti gli eventi che sono chiamati verranno registrati nel registro eventi

[/ EDIT2]

risposta

8

Utilizzare l'unità "delphieventlogger" che ho scritto download here. È solo una chiamata al metodo ed è molto facile da usare. Registra tutti i TNotifyEvents (ad esempio OnChange, OnEnter, OnExit) nel registro eventi Delphi nella finestra del debugger.

+0

+1 per pubblicare la propria soluzione con il codice qui! –

2

Usa WINSIGHT per vedere il flusso di messaggi in tempo reale.

Se si desidera realmente che il programma generi un registro, ignorare WinProc e/o intercettare i messaggi in Application.

+0

Anche se tutti gli eventi di Delphi sono Windows? Ho appena provato a registrare eventi usando TApplicationEvents.OnMessage, e tutto ciò che mi sembra di ottenere è il movimento del mouse e gli eventi della tastiera. Non vedo gli eventi OnChange, OnExit o OnEnter (per quanto posso dire). Suppongo di sperare in qualcosa di più alto livello rispetto ai messaggi di Windows. – awmross

+0

btw WinSight non viene fornito con Delphi 2010 – awmross

+2

@awmross: gli eventi Delphi non sono messaggi di Windows. I messaggi di Windows vengono inviati alle routine di gestione dei messaggi sui controlli di Delphi, alcuni dei quali chiamano gestori di eventi se ce n'è uno collegato. –

3

No, non c'è un modo generalizzato per farlo, perché Delphi non ha alcun tipo di "tipo di evento" che può essere collegato in qualche modo. Un gestore di eventi è solo un riferimento al metodo e viene chiamato in questo modo:

if assigned(FEventHandler) then 
    FEventHandler(self); 

Solo una normale chiamata di riferimento metodo. Se si desidera registrare tutti i gestori di eventi, sarà necessario inserire alcune chiamate in ognuno di essi.

+0

Si scopre che molti degli eventi a cui sono interessato sono dello stesso tipo (ad esempio, TNotifyEvent). Usando RTTI possiamo intercettare tutti gli eventi di questo tipo e registrarli. – awmross

3

So che è un po 'costoso, ma è possibile utilizzare il QA automatico (ora SmartBear) TestRecorder come estensione a TestComplete (se si desidera questo solo sul proprio sistema, solo TestComplete lo farà). Questo software tiene traccia delle azioni della GUI e le archivia in un linguaggio simile a uno script. C'è anche un'unità che può essere collegata al tuo exe per rendere queste registrazioni direttamente sul sistema dell'utente. Ciò è particolarmente utile quando alcuni utenti non sono in grado di spiegare cosa hanno fatto per produrre un errore.

-1

È possibile provare uno dei AOP frameworks for Delphi. MeAOP fornisce un logger predefinito che è possibile utilizzare. Non ti dirà cosa sta succedendo all'interno di un gestore di eventi, ma ti dirà quando viene chiamato un gestore di eventi e quando ritorna.

+0

Anch'io ho pensato ad AOP per questo. Ho provato MeAOP ma non sembra compilato in D2010 (penso che sia un problema Unicode) – awmross

1

In alternativa, per eseguire il debug degli eventi attivati ​​utilizzare il debugger Step Into (F7) anziché i comandi Step Over (F8).

Il debugger si interromperà su qualsiasi linea di codice disponibile raggiunta durante la chiamata.

+0

Inizialmente non potevo usare questo approccio, dato che usiamo una libreria skinning di terze parti piuttosto complessa; Ho trovato che il debugger sarebbe entrato in questo codice di terze parti. Ho quindi scoperto la direttiva del compilatore "{$ D-}" che può disattivare il debug di un'intera unità. Ciò ha limitato il debugger al solo passaggio nel mio codice di progetto, che ha reso pratico il tuo suggerimento. Penso che ci sia un problema generale con questo approccio; gli eventi che stai cercando potrebbero essere chiamati in profondità nell'albero delle chiamate; quindi, passare manualmente al codice richiede ancora delle congetture e tentativi per errore. – awmross

+0

@awmross: per eseguire il debug di un'applicazione (evento guidato o meno) è quasi completamente un'arte di congetture e tentativi per errore;) – jachguate

2

L'evento TApplication.OnMessage può essere utilizzato per catturare i messaggi inviati alla coda messaggi principale. Questo è principalmente per i messaggi OS-enabled, non per i messaggi VCL/RTL interni, che vengono solitamente inviati direttamente ai metodi WndProc(). Inizialmente, non tutti gli eventi VCL sono guidati dai messaggi. Non esiste un'unica soluzione per quello che stai cercando. Dovresti utilizzare una combinazione di TApplication.OnMessage, TApplication.HookMainWindow(), sostituzioni WndProc(), SetWindowsHook() e punti di interruzione/collegamento selettivi nel codice.

strumento WINSIGHT di Borland non è distribuito più, ma ci sono un sacco di strumenti di terze parti prontamente disponibili che fanno la stessa cosa come WINSIGHT, come la spia di Microsoft ++, WinSpector, ecc, per il monitoraggio dei messaggi di finestra di registrazione in tempo reale .

Problemi correlati