Obsługa zdarzeń


Zdarzenia są obsługiwane przez metody implementujące reakcje na dynamicznie dostarczane komunikaty. Biblioteka VCL Delphi używa obsługi zdarzeń jako reakcji na komunikaty Windows.

Procedura obsługująca zdarzenie kreowana jest przez włączenie dyrektywy message w deklaracji metody, wraz ze stałą typu całkowitego od 1 do 49151, która specyfikuje ID komunikatu. Dla procedur obsługi zdarzeń w kontrolkach VCL, stała musi być jedną ze zdefiniowanych ID komunikatów Windows, z którymi koresponduje rekord typów w module Messages. Przykład:

type
  TTextBox = class(TCustomControl)
    private
    procedure WMChar(var Message: TWMChar); message WM_CHAR;
    ...
  end;

Procedura obsługi zdarzenia musi być procedurą z jednym parametrem formalnym przekazywanym przez zmienną (przez referencję, odwołanie).

Procedura obsługi zdarzenia nie może zawierać dyrektywy override. W rzeczywistości nie ma konieczności specyfikowania takiej samej nazwy metody lub typu parametru jako metody, którą się pokrywa. ID komunikatu sam jeden determinuje, na który komunikat metoda reaguje i czy jest ona pokryta.

Implementacja procedur obsługi zdarzeń

Implementacja procedury obsługi zdarzenia może wywoływać odziedziczone procedury obsługi zdarzeń, jak w tym przykładzie:

procedure TTextBox.WMChar(var Message: TWMChar);
begin
  if Chr(Message.CharCode) = #13 then 
   ProcessEnter
  else 
   inherited;
end;

Instrukcja inherited przeszukuje wstecz hierarchię klas i uruchamia pierwszą procedurę obsługi zdarzenia z takim samym ID jak w bieżącej metodzie, automatycznie przekazując rekord komunikatu. Jeśli w klasie-przodku nie ma procedur obsługi zdarzenia implementujących obsługę żądanego ID, inherited wywołuje metodę DefaultHandler oryginalnie zdefiniowaną w klasie TObject.

Implementacja metody DefaultHandler w klasie TObject nie wykonuje żadnych operacji. Poprzez pokrycie metody DefaultHandler, klasa może implementować swoją własną domyślną procedurę obsługi zdarzeń. Metoda DefaultHandler dla kontrolek VCL wywołuje funkcję Windows DefWindowProc.

Wysyłanie komunikatów

Procedury obsługi zdarzeń są rzadko wywoływane wprost. Zamiast tego, wysyłane są do obiektu komunikaty przez użycie metody Dispatch odziedziczonej z klasy TObject:

procedure Dispatch(var Message);

Parametr message przekazywany do Dispatch musi być rekordem, którego pierwszy element jest polem typu Cardinal zawierającym ID komunikatu.

Dispatch przeszukuje wstecz hierarchię klas (startując od klasy obiektu, gdzie jest wywoływana) i wywołuje pierwszą procedurę obsługi zdarzenia dla przekazanego do niej ID. Jeśli nie znaleziono żadnej procedury obsługi zdarzenia dla danego ID, Dispatch wywołuje metodę DefaultHandler.