掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
通知先が2カ所以上あるような複数イベントの処理 (ID:13661)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
>ソースを参考にしてさっそく実装してみたいと思います。 「Observers」という単語がちょっと難しかったのでイベント発生側をSend 受け取り側をReceiveとした他、Change関係のフラグを使用しないようにしました。 他はほとんどsakiyama様のソースそのままですが・・・ ちなみに実際に本番でも使用していますが特に問題なく動いています。 複数通知先イベント発生/受け取りユニット MultiEvent.pasと サンプルフォーム Unit1.pasを載せておきます。 TForm1.OnUpdate1やTForm1.OnUpdate2の中に処理やブレイクポイントを付けて お試しください。 unit MultiEvent; interface uses SysUtils, Classes, Contnrs; type TMultiEventUpdateEvent = procedure(Sender, Arg: TObject) of object; TMultiEventReceive = class; TMultiEventSend = class(TComponent) private FObservers: TComponentList; function GetObservers(Index: Integer): TMultiEventReceive; protected property Observers[Index: Integer]: TMultiEventReceive read GetObservers; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure Add(Value: TMultiEventReceive); procedure Delete(Value: TMultiEventReceive); procedure Notify(Arg : TObject); end; TMultiEventReceive = class(TComponent) private { Private 宣言 } FObservable: TMultiEventSend; FOnUpdate: TMultiEventUpdateEvent; procedure SetObservable(const Value: TMultiEventSend); protected { Protected 宣言 } procedure DoUpdate(Arg : TObject); public { Public 宣言 } property Observable: TMultiEventSend read FObservable write SetObservable; published { Published 宣言 } procedure Notification(AComponent: TComponent; Operation: TOperation); override; property OnUpdate:TMultiEventUpdateEvent read FOnUpdate write FOnUpdate; end; implementation { TMultiEventSend } procedure TMultiEventSend.Add(Value: TMultiEventReceive); begin if FObservers.IndexOf(Value) < 0 then FObservers.Add(Value); end; constructor TMultiEventSend.Create(AOwner: TComponent); begin inherited; FObservers := TComponentList.Create(False); end; destructor TMultiEventSend.Destroy; begin FObservers.Free; inherited; end; function TMultiEventSend.GetObservers(Index: Integer): TMultiEventReceive; begin Result := FObservers[Index] as TMultiEventReceive; end; procedure TMultiEventSend.Notify(Arg : TObject); var i: Integer; begin for i := 0 to FObservers.Count -1 do begin (FObservers[i] as TMultiEventReceive).DoUpdate(Arg); end; end; procedure TMultiEventSend.Delete(Value: TMultiEventReceive); begin FObservers.Extract(Value); end; { TMultiEventReceive } procedure TMultiEventReceive.DoUpdate(Arg : TObject); begin if Assigned(FOnUpdate) then FOnUpdate(Self, Arg); end; procedure TMultiEventReceive.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (Operation = opRemove) and (AComponent = FObservable) then SetObservable(nil); end; procedure TMultiEventReceive.SetObservable(const Value: TMultiEventSend); begin if Assigned(FObservable) then begin FObservable.Delete(Self); end; FObservable := Value; if Assigned(FObservable) then begin FObservable.Add(Self); FObservable.FreeNotification(Self); end; end; end. ------------------------------------------------------------------------------------ unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, MultiEvent, StdCtrls; type TTestData = class(TPersistent) private { Private 宣言 } FEvents: TMultiEventSend; FValue: Integer; procedure SetValue(const Value: Integer); public { Public 宣言 } constructor Create; destructor Destroy; override; property Events : TMultiEventSend read FEvents write FEvents; property Value : Integer read FValue write SetValue; end; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private 宣言 } FTest : TTestData; FEvents1: TMultiEventReceive; FEvents2: TMultiEventReceive; procedure OnUpdate1(Sender, Arg: TObject); procedure OnUpdate2(Sender, Arg: TObject); public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.DFM} { TTestData } constructor TTestData.Create; begin FEvents := TMultiEventSend.Create(nil); end; destructor TTestData.Destroy; begin FEvents.Free; inherited; end; procedure TForm1.FormCreate(Sender: TObject); begin FTest := TTestData.Create; FEvents1 := TMultiEventReceive.Create(Self); FEvents1.OnUpdate := OnUpdate1; FEvents2 := TMultiEventReceive.Create(Self); FEvents2.OnUpdate := OnUpdate2; FTest.Events.Add(FEvents1); FTest.Events.Add(FEvents2); end; procedure TForm1.FormDestroy(Sender: TObject); begin FTest.Events.Delete(FEvents2); FTest.Events.Delete(FEvents1); FEvents2.Free; FEvents1.Free; FTest.Free; end; procedure TForm1.OnUpdate1(Sender, Arg: TObject); var s : string; begin s := ''; end; procedure TForm1.OnUpdate2(Sender, Arg: TObject); var s : string; begin s := ''; end; procedure TTestData.SetValue(const Value: Integer); begin FValue := Value; FEvents.Notify(Self); end; procedure TForm1.Button1Click(Sender: TObject); begin FTest.Value := 0; end; end.
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.