рдбреЗрд▓реНрдлреА рдореЗрдВ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЯреНрд░рд┐рдХреНрд╕

рдирдорд╕реНрддреЗред

рдЖрдЬ рд╣реА, рдореИрдВрдиреЗ рдПрдХ рд╕рд╣рдпреЛрдЧреА рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреАред рдЙрд╕рдиреЗ рдореБрдЭреЗ рдЕрдкрдиреА рджрд┐рд▓рдЪрд╕реНрдк рдЪрд╛рд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдпрд╛, рдореИрдВрдиреЗ рдЙрд╕реЗ рдЕрдкрдиреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдпрд╛, рд▓реЗрдХрд┐рди рдШрд░ рдкрд░ рд╣реА рдореБрдЭреЗ рдЗрди рдЪрд╛рд▓реЛрдВ рдХреА рдкреВрд░реА рддрд╛рдХрдд рдХрд╛ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ, рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕рд╛рде рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред

рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╕реНрд╡рдЪрд╛рд▓рди рдФрд░ рдПрдорд╡реАрд╕реА рдкреИрдЯрд░реНрди рдХреЗ рдкреНрд░рд╢рдВрд╕рдХ - рдХреГрдкрдпрд╛, рдмрд┐рд▓реНрд▓реА рдХреЗ рдиреАрдЪреЗред



рдЯреНрд░рд┐рдХ 1. рд╕реНрдорд╛рд░реНрдЯ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХреНрд╕



рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ - рдХрдордЬреЛрд░ (рдХрдордЬреЛрд░) рд▓рд┐рдВрдХ - рд▓рд┐рдВрдХ рдЬреЛ рдХрд╛рдЙрдВрдЯрд░ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдкреЗрдбрд╝ рд╣реИ:

INode = interface function GetParent: INode; function ChildCount: Integer; function GetChild(Index: Integer): INode; end;
      
      



рдпрджрд┐ рдПрдХ рд╡рд░реНрдЧ рдХреЗ рдЕрдВрджрд░ рдЬреЛ рдХрд┐ рдЗрдирдХреЛрдб рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЕрднрд┐рднрд╛рд╡рдХ рдФрд░ рдмрдЪреНрдЪреЗ рдЗрд╕ рддрд░рд╣ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрдВрдЧреЗ:

 TNode = class(TInterfacedObject, INode) private FParent: INode; FChild: array of INode; end;
      
      



рд╡рд╣ рдкреЗрдбрд╝ рдХрднреА рдирд╖реНрдЯ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдорд╛рддрд╛-рдкрд┐рддрд╛ рдмрдЪреНрдЪреЛрдВ рдХреЛ рд▓рд┐рдВрдХ рджреЗрддреЗ рд░рд╣рддреЗ рд╣реИрдВ (рдФрд░ рдЗрд╕ рддрд░рд╣ рдЙрдирдХрд╛ рдХрд╛рдЙрдВрдЯрд░ рдмрдврд╝рддрд╛ рд╣реИ), рдФрд░ рдмрдЪреНрдЪреЗ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рд▓рд┐рдПред рдпрд╣ рдПрдХ рдХреНрд▓рд╛рд╕рд┐рдХ рдкрд░рд┐рдкрддреНрд░ рд▓рд┐рдВрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ, рдФрд░ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдХрд╛ рд╕рд╣рд╛рд░рд╛ рд▓реЗрддреЗ рд╣реИрдВред рдирдИ XE рдбреЗрд▓реНрдлреА рдореЗрдВ, рдЖрдк рдЗрд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

 TNode = class(TInterfacedObject, INode) private [weak] FParent: INode; FChild: array of INode; end;
      
      



рдФрд░ рдкреБрд░рд╛рдиреЗ рдореЗрдВ - рд╡реЗ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддреЗ рд╣реИрдВ:

 TNode = class(TInterfacedObject, INode) private FParent: Pointer; FChild: array of INode; end;
      
      



рдпрд╣ рдЖрдкрдХреЛ рдХрд╛рдЙрдВрдЯрд░реЛрдВ рдХреЗ рдСрдЯреЛ-рдЗрдиреНрдХреНрд░реАрдореЗрдВрдЯ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЕрдм рдЕрдЧрд░ рд╣рдо рдЕрднрд┐рднрд╛рд╡рдХ рдХреЛ рд╕реВрдЪрдХ рдЦреЛ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдкреВрд░реЗ рдкреЗрдбрд╝ рдХреЛ рдкреАрдЯрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрд┐рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдерд╛ред



рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдХрд╛ рдПрдХ рдФрд░ рдкрдХреНрд╖ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрдЪрд╛рдирдХ рдХреЛрдИ рд╡рд╕реНрддреБ рдирд╖реНрдЯ рд╣реЛ рдЧрдИ рд╣реИ, рдФрд░ рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рд░рдЦрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЗрд╕реЗ рдЯреНрд░реИрдХ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ - рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдХрдЪрд░рд╛ рд╕реВрдЪрдХ рд╣реИ, рдЬрдм рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рддреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреАред рдФрд░ рдпрд╣ рднрдпрд╛рдирдХ рд╣реИред рдЖрдкрдХреЛ рдЗрди рдХрдбрд╝рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдлрд╛рдИ рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреЛ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред



рд▓реЗрдХрд┐рди рдПрдХ рдмрд╣реБрдд рд╣реА рд╕реБрдВрджрд░ рд╕рдорд╛рдзрд╛рди рд╣реИред рдФрд░ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╣рдо рдПрдХ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдФрд░ рдПрдХ рд╡рд░реНрдЧ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ:

  IWeakRef = interface function IsAlive: Boolean; function Get: IUnknown; end; TWeakRef = class(TInterfacedObject, IWeakRef) private FOwner: Pointer; public procedure _Clean; function IsAlive: Boolean; function Get: IUnknown; end; procedure TWeakRef._Clean; begin FOwner := nil; end; function TWeakRef.Get: IUnknown; begin Result := IUnknown(FOwner); end; function TWeakRef.IsAlive: Boolean; begin Result := Assigned(FOwner); end;
      
      



рдпрд╣рд╛рдБ рд╕реВрдЪрдХ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рдЯрд╛рдЗрдкрдХрд╛рд╕реНрдЯ рд╣реИред рдпрд╣ рд╡рд╣ рдХрдордЬреЛрд░ рдХрдбрд╝реА рд╣реИ рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВрдиреЗ рдКрдкрд░ рдмрд╛рдд рдХреА рдереАред рд▓реЗрдХрд┐рди рдкреНрд░рдореБрдЦ рд╡рд┐рдзрд┐ IsAlive рд╣реИ , рдЬреЛ рд╕рд╣реА рд░рд┐рдЯрд░реНрди рджреЗрддрд╛ рд╣реИ - рдпрджрд┐ рд╡рд╕реНрддреБ рдХрдордЬреЛрд░ рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рд╕рдВрджрд░реНрднрд┐рдд рд╣реИ - рдЕрднреА рднреА рдореМрдЬреВрдж рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИ рдХрд┐ рд╕реБрдВрджрд░ рддрд░реАрдХреЗ рд╕реЗ рдлреЙрдирд░ рдХреЛ рдХреИрд╕реЗ рд╕рд╛рдл рдХрд┐рдпрд╛ рдЬрд╛рдП ред

рд╣рдо рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

  IWeakly = interface ['{F1DFE67A-B796-4B95-ADE1-8AA030A7546D}'] function WeakRef: IWeakRef; end;
      
      



}'] IWeakly = interface ['{F1DFE67A-B796-4B95-ADE1-8AA030A7546D}'] function WeakRef: IWeakRef; end;



рдЬреЛ рдПрдХ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рджреЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╡рд░реНрдЧ рд▓рд┐рдЦрддрд╛ рд╣реИ рдЬреЛ рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ:

  TWeaklyInterfacedObject = class(TInterfacedObject, IWeakly) private FWeakRef: IWeakRef; public function WeakRef: IWeakRef; destructor Destroy; override; end; destructor TWeaklyInterfacedObject.Destroy; begin inherited; FWeakRef._Clean; end; function TWeaklyInterfacedObject.WeakRef: IWeakRef; var obj: TWeakRef; begin if FWeakRef = nil then begin obj := TWeakRef.Create; obj.FOwner := Self; FWeakRef := obj; end; Result := FWeakRef; end;
      
      



рд╣рдордиреЗ рд╕рд┐рд░реНрдл рдПрдХ рддрд░реАрдХрд╛ рдЬреЛрдбрд╝рд╛ рд╣реИ рдЬреЛ рд╕рднреА рдХреЛ рдПрдХ рдХрдордЬреЛрд░ рдХрдбрд╝реА рджреЗрддрд╛ рд╣реИред рдФрд░ рдЪреВрдБрдХрд┐ рд╡рд╕реНрддреБ рд╣рдореЗрд╢рд╛ рдЕрдкрдиреЗ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡рд╣ рдЗрд╕реЗ рдЕрдкрдиреЗ рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдореЗрдВ рд╕рд╛рдл рдХрд░ рджреЗрддреА рд╣реИред рдЕрдм рдЬреЛ рдХреБрдЫ рд╣реИ рд╡рд╣ TInterfacedObject рдХреЗ рдмрдЬрд╛рдп TWeaklyInterfacedObject рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИ , рдмрд╕ рдЗрддрдирд╛ рд╣реАред рдХреЛрдИ рдФрд░ рдЕрдзрд┐рдХ рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдЬрд╛рддрд┐рдпрд╛рдВ, рдкреИрд░ рдореЗрдВ рд╢реЙрдЯреНрд╕ рдФрд░ рдмреЗрдИрдорд╛рдиреА рдирд╣реАрдВред



рдЯреНрд░рд┐рдХ 2. рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░реНрд╕ рдореИрдХреЗрдирд┐рдЬреНрдо



рдпрджрд┐ рдЖрдкрдиреЗ рдбреЗрд▓реНрдлреА рдореЗрдВ рдкреНрд▓рдЧ-рдЗрди рдХреА рдкреНрд░рдгрд╛рд▓реА рдХреЛ рд╕рд╛рдЗрдХрд┐рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдПрдорд╡реАрд╕реА рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдЖрдк рднрд╛рдЧреНрдпрд╢рд╛рд▓реА рд╣реИрдВред рдбреЗрд▓реНрдлреА рдореЗрдВ, рд╕рднреА рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдлрд╝рдВрдХреНрд╢рди (рдФрд░ рдЙрджрд╛рд╣рд░рдг) рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХ рдпрд╛ рджреЛ рдмрд┐рдВрджреБ рд╣реЛрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдЖрдкрдиреЗ рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдпрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рдПрдХ рдУрдирдмрд╛рд▓рд╛ рд╕рдВрдкрддреНрддрд┐ рдмрдирд╛рдпрд╛ рд╣реИ, рддреЛ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдмреНрд▓рд╛рдмрд▓рд╛ рдЖрдЦрд┐рд░рдХрд╛рд░ рд╣реБрдЖред рдЗрд╕рд▓рд┐рдП, рд╣рд░ рдХреЛрдИ рдЕрдкрдиреЗ рд╕рджрд╕реНрдпрддрд╛ рддрдВрддреНрд░ рдХреЛ рджреЗрдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЕрдХреНрд╕рд░ рдЗрди рдмрд╣реБрдд рд╕рджрд╕реНрдпрддрд╛ рдХреЛ рдбрд┐рдмрдЧ рдХрд░рдиреЗ рдореЗрдВ рдбреВрдм рдЬрд╛рддрд╛ рд╣реИред

рдЗрдВрдЯрд░рдлрд╝реЗрд╕-рдЖрдзрд╛рд░рд┐рдд рдИрд╡реЗрдВрдЯ рдЖрдорддреМрд░ рдкрд░ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЕрд▓рдЧ рдИрд╡реЗрдВрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрдирд╛рдПрдВ:

 IMouseEvents = interface procedure OnMouseMove(...); procedure OnMouseDown(...); procedure OnMouseUp(...); end;
      
      



рдФрд░ рд╡рд╕реНрддреБ рдХреА рдХреНрд▓рд╛рд╕рд┐рдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрдЬрд╛рдп рдЗрд╕реЗ рдкрд╛рд╕ рдХрд░реЗрдВ; рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рджрд╕реНрдпрддрд╛ / рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдореЗрдВ:

 IForm = interface procedure SubscribeMouse(const subscriber: IMouseEvents); procedure UnsubscribeMouse(const subscriber: IMouseEvents); end;
      
      



рдЬрдм рдХреЛрдб рдмрдврд╝рддрд╛ рд╣реИ, рдФрд░ IMouseEvents рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдереЛрдбрд╝рд╛ рдмрджрд▓рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ), рддреЛ рд░рд┐рдлреИрдХреНрдЯрд░рд┐рдВрдЧ рдмрд╣реБрдд рдЕрдзрд┐рдХ рддрдирд╛рд╡ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рдорд╛рди IMouseEvents рдХрд╛ рдЙрдкрдпреЛрдЧ IForm , IButton , IImage рдФрд░ рдЕрдиреНрдп рдмреБрд░реА рдЖрддреНрдорд╛рдУрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд░ рдЬрдЧрд╣ рдЖрдкрдХреЛ рд╕рджрд╕реНрдпрддрд╛ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рд╣реА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд▓рд┐рдП рдХреНрд░реЙрд▓ рдЬреЛрдбрд╝реЗрдВ, рдЖрджрд┐ред

рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЪрд╛рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдБред рд╣рдо рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

  IPublisher = interface ['{CDE9EE5C-021F-4942-A92A-39FC74395B4B}'] procedure Subscribe (const ASubscriber: IUnknown); procedure Unsubscribe(const ASubscriber: IUnknown); end;
      
      



рд╡рд╣ рд╡рд░реНрдЧ рдЬреЛ рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдЧрд╛ (рдЗрд╕реЗ TBasePublisher рд╣реЛрдиреЗ рджреЗрдВ ) рдХреЗрд╡рд▓ рд╕реВрдЪреА рдореЗрдВ рд╕реЗ рдХреБрдЫ рдЗрдВрдЯрд░рдлреЗрд╕ рдЬреЛрдбрд╝ рдФрд░ рд╣рдЯрд╛ рд╕рдХрддрд╛ рд╣реИред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рд╣рдо рдЙрди рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВ рдмреНрд░реЙрдбрдХрд╛рд╕реНрдЯрд░ рдХрд╣рддрд╛ рд╣реВрдВред рдпрд╣рд╛рдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдИрд╡реЗрдВрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ:

  IGraphEvents = interface ['{2C7EF06A-2D63-4F25-80BC-7BA747463DB6}'] procedure OnAddItem(const ASender: IGraphList; const AItem: TGraphItem); procedure OnClear(const ASender: IGraphList); end;
      
      



}'] IGraphEvents = interface ['{2C7EF06A-2D63-4F25-80BC-7BA747463DB6}'] procedure OnAddItem(const ASender: IGraphList; const AItem: TGraphItem); procedure OnClear(const ASender: IGraphList); end;



рд╣рдо TBasePublisher рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмреНрд░реЛрдХреЗрд╕реНрдЯрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:

  TGraphEventsBroadcaster = class(TBasePublisher, IGraphEvents) private procedure OnAddItem(const ASender: IGraphList; const AItem: TGraphItem); procedure OnClear(const ASender: IGraphList); end; procedure TGraphEventsBroadcaster.OnAddItem(const ASender: IGraphList; const AItem: TGraphItem); var arr: TInterfacesArray; i: Integer; ev: IGraphEvents; begin arr := GetItems; for i := 0 to Length(arr) - 1 do if Supports(arr[i], IGraphEvents, ev) then ev.OnAddItem(ASender, AItem); end; procedure TGraphEventsBroadcaster.OnClear(const ASender: IGraphList); var arr: TInterfacesArray; i: Integer; ev: IGraphEvents; begin arr := GetItems; for i := 0 to Length(arr) - 1 do if Supports(arr[i], IGraphEvents, ev) then ev.OnClear(ASender); end;
      
      



рдпрд╣реА рд╣реИ, рдкреНрд░рд╕рд╛рд░рдХ рд╕реНрд╡рдпрдВ рдИрд╡реЗрдВрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдпрд╣ рд╕рднреА рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдИрд╡реЗрдВрдЯ рднреЗрдЬрддрд╛ рд╣реИред рдлрд╛рдпрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрдк IGraphEvents рдХреЛ рдХрдо рд╕реЗ рдХрдо рдереЛрдбрд╝рд╛ рдмрджрд▓рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рд╕рдВрдХрд▓рди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдЕрдм IForm , IButton , IImage zoo рдХреЗрд╡рд▓ TGraphEventsBroadcaster рдХреЛ рдЕрдкрдиреЗ рдЕрдВрджрд░ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдХрд╣рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ IForm рдХреЗ рдХреЗрд╡рд▓ рдПрдХ рдЧреНрд░рд╛рд╣рдХ рд╣реИрдВред



рдЯреНрд░рд┐рдХ 3. рд╕реНрдорд╛рд░реНрдЯ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ + рдЧреНрд░рд╛рд╣рдХ рддрдВрддреНрд░



рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬреЛ рдХреБрдЫ рднреА рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рд╕рдм рдмреБрд░рд╛ рд╣реИред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдФрд░ рдЪрдХреНрд░реАрдп рд▓рд┐рдВрдХ рд╣реЛрдВрдЧреЗ, рдЖрдк рдЕрдВрддрд┐рдордХрд░рдг рдФрд░ рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдХреНрд╖реНрдп рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЖрдк рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрдЪрд░рд╛ рд▓рд┐рдВрдХ рдХреЛ рдбреАрдмрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЧрдбрд╝рдмрдбрд╝ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдмрд╣реБрдд рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╕реНрдорд╛рд░реНрдЯ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдХрд╛рдо рдореЗрдВ рдЖрддреЗ рд╣реИрдВред рд╣рдо рдЗрд╕ рдкреНрд░рдХрд╛рд╢рдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ (рдЬреЛ рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ IWeakly рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ):

  IPublisher = interface ['{CDE9EE5C-021F-4942-A92A-39FC74395B4B}'] procedure Subscribe (const ASubscriber: IWeakly); procedure Unsubscribe(const ASubscriber: IWeakly); end;
      
      



рдЕрдВрджрд░ рд╣реА, TBasePublisher рдкреНрд░рдХрд╛рд╢рдХ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ TWeakRefArr = рд╕рд░рдгреА IWeakRef рдХреА рдПрдХ рд╕рд░рдгреА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ;

  TBasePublisher = class(TInterfacedObject, IPublisher) private FItems: TWeakRefArr; protected function GetItems: TWeakRefArr; public procedure Subscribe (const ASubscriber: IWeakly); procedure Unsubscribe(const ASubscriber: IWeakly); end;
      
      



рдФрд░ рдкреНрд░рд╕рд╛рд░рдХ рдЕрдм рдХреЗрд╡рд▓ рдЬреАрд╡рди рд╢рдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ, рд╕рд╛рдорд╛рдиреНрдп рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕ рдШрдЯрдирд╛ рдХреЛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдмреНрд░реЙрдбрдХрд╛рд╕реНрдЯрд░ рдЗрд╕ рддрд░рд╣ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ:

 procedure TGraphEventsBroadcaster.OnAddItem(const ASender: IGraphList; const AItem: TGraphItem); var arr: TWeakRefArr; i: Integer; ev: IGraphEvents; begin arr := GetItems; for i := 0 to Length(arr) - 1 do if IsAlive(arr[i]) then if Supports(arr[i].Get, IGraphEvents, ev) then ev.OnAddItem(ASender, AItem); end; procedure TGraphEventsBroadcaster.OnClear(const ASender: IGraphList); var arr: TWeakRefArr; i: Integer; ev: IGraphEvents; begin arr := GetItems; for i := 0 to Length(arr) - 1 do if IsAlive(arr[i]) then if Supports(arr[i].Get, IGraphEvents, ev) then ev.OnClear(ASender); end;
      
      



рдЕрдм рд╣рдо рдЕрдирд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд┐рдВрдЧ рдСрд░реНрдбрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рдЪрд┐рдВрддрд┐рдд рдирд╣реАрдВ рд╣реИрдВред рдпрджрд┐ рд╣рдо рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рдХрд░рдирд╛ рднреВрд▓ рдЧрдП - рдпрд╣ рдареАрдХ рд╣реИред рд╕рдм рдХреБрдЫ рдкрд╛рд░рджрд░реНрд╢реА рд╣реЛ рдЧрдпрд╛, рдЬреИрд╕рд╛ рдХрд┐ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред



рдЪрд╛рд▓ 4. рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреБрдирдГ рд▓реЛрдб рдХрд░рдирд╛



рдЕрдВрддрд┐рдо рд╕реНрдкрд░реНрд╢:

  TAutoPublisher = packed record Publisher: IPublisher; class operator Add(const APublisher: TAutoPublisher; const ASubscriber: IWeakly): Boolean; class operator Subtract(const APublisher: TAutoPublisher; const ASubscriber: IWeakly): Boolean; end; class operator TAutoPublisher.Add(const APublisher: TAutoPublisher; const ASubscriber: IWeakly): Boolean; begin APublisher.Publisher.Subscribe(ASubscriber); Result := True; end; class operator TAutoPublisher.Subtract(const APublisher: TAutoPublisher; const ASubscriber: IWeakly): Boolean; begin APublisher.Publisher.Unsubscribe(ASubscriber); Result := True; end;
      
      



рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдмрд┐рдирд╛ рд╢рдмреНрджреЛрдВ рдХреЗ рд╕реНрдкрд╖реНрдЯ рд╣реИред рд╣рдо рд╕рд┐рд░реНрдл MyForm.MyEvents + MySubscriber рдХрд░рддреЗ рд╣реИрдВ ; - рд╣рдордиреЗ рд╕рд╛рдЗрди рдЕрдк рдХрд┐рдпрд╛ред рдШрдЯрд╛рдпрд╛: MyForm.MyEvents - MySubscriber ; - рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрддред



рдпрджрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЗрд╕рдХрд╛ рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рджрд┐рдпрд╛ рддреЛ рд▓реЗрдЦ рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдпрд╣рд╛рдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ ред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ:

рдХрд╛рд░реНрдпрдХреНрд░рдо 4 рдЦрд┐рдбрд╝рдХрд┐рдпрд╛рдВ рдмрдирд╛рддрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рд╡рд┐рдВрдбреЛ рдкрд░ рдЖрдк рдорд╛рдЙрд╕ рд╕реЗ рдбреНрд░рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдбреНрд░реЙ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рд╕реВрдЪреА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╕рджрд╕реНрдпрддрд╛ рддрдВрддреНрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рднреА рд╡рд┐рдВрдбреЛрдЬрд╝ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рддреИрдпрд╛рд░ рдЖрдВрдХрдбрд╝рд╛ рд╕рднреА рд░реВрдкреЛрдВ рдкрд░ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдлреЙрд░реНрдо рдкрд░, рдЖрдк рдЯреНрд░реИрдХрдмрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреА рд▓рд╛рдЗрди рдХреА рдореЛрдЯрд╛рдИ рдХрд╛ рдЪрдпрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред



IntfEx.pas - рд╕реНрдорд╛рд░реНрдЯ рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдкрд░ рдкреНрд░рдХрд╛рд╢рдХ TBasePublisher рдХрд╛ рдЖрдзрд╛рд░ рд╡рд░реНрдЧ + TAutoPublisher рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдзрд┐рднрд╛рд░

Datas.pas - рдЗрд╕ рд╕реВрдЪреА рдХреЛ рдмрджрд▓рддреЗ рд╕рдордп рдЦреАрдВрдЪреА рдЧрдИ рд╡рд╕реНрддреБрдУрдВ + рдШрдЯрдирд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреА рд╕реВрдЪреА

DrawForm.pas - рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рдЬреЛ рдПрдХ рдлрд╛рд░реНрдо рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рдЖрдк рдЖрдХрд░реНрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рджрд╕реНрдпрддрд╛ рд╣реИред

HiddenForm.pas - рдЫрд┐рдкрд╛ рд╣реБрдЖ рдореБрдЦреНрдп рд░реВрдк (рдХреЗрд╡рд▓ рд╡рд┐рдВрдбреЛ рд▓реВрдк рд╕реНрдкрд┐рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ)

рдареАрдХ рд╣реИ, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдлрд╝рд╛рдЗрд▓ рдереЛрдбрд╝рд╛ рд╕рдВрд╢реЛрдзрд┐рдд рд╣реИ (рдкреНрд░рдкрддреНрд░ рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕ рдкрд░ рдЖрдк рдЖрдХрд░реНрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)



рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдореИрдХреНрд╕рд┐рдбрд┐рдХреНрд╕ рд╕рд░реЛ рдХреЗ рджрд┐рдорд┐рддреНрд░реА рдЗрд▓рд┐рдВрд╕ рджреНрд╡рд╛рд░рд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдЕрдВрддрд┐рдо рд░реВрдк рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред



рдпреБрдкреАрдбреАред рд░рд┐рд▓реАрдЬ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ, рдбреЗрд▓реНрдлреА 10.1 рдиреЗ рдкреВрд░реНрдг-рд╡рд┐рдХрд╕рд┐рдд [рдХрдордЬреЛрд░] рд▓рд┐рдВрдХ рдкреЗрд╢ рдХрд┐рдПред рд╣реБрдб рдХреЗ рддрд╣рдд, рд╡реЗ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдХрдордЬреЛрд░ рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рд╕рд╛рджреГрд╢реНрдп рджреНрд╡рд╛рд░рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рд▓рдп рд╣реЛрдиреЗ рдкрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╢реВрдиреНрдп рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдкрдврд╝реЗрдВ: habr.com/en/post/282035



All Articles